From fdd8552c4ee06c9fc713a7d15098af0baaddd4df Mon Sep 17 00:00:00 2001 From: FBShipIt Date: Mon, 25 Jul 2016 06:31:32 -0700 Subject: [PATCH] Import new C source of truth css-layout fbshipit-source-id: e866918d6c62fc1cf3a04c269f782b94db9b875a --- .buckconfig | 2 + .buckversion | 1 + .eslintrc | 20 - .gitignore | 14 +- .hgignore | 7 + .travis.yml | 18 - BUCK | 81 + CONTRIBUTING.md => CONTRIBUTING | 0 CSSLAYOUT_DEFS | 7 + CSSLayout/CSSLayout-internal.h | 105 + dist/css-layout.h => CSSLayout/CSSLayout.c | 1420 ++- CSSLayout/CSSLayout.h | 210 + .../CSSAlign.cs => CSSLayout/CSSMacros.h | 25 +- CSSLayout/CSSNodeList.c | 86 + CSSLayout/CSSNodeList.h | 30 + Gruntfile.js | 198 - LICENSE | 2 +- README | 9 + README.md | 157 - TestResult.xml | 9 - dist/README.md | 20 - dist/css-layout.jar | Bin 16324 -> 0 bytes dist/css-layout.js | 1737 --- dist/css-layout.min.js | 2 - dist/css-layout.min.js.map | 1 - java/CSharpTranspiler.js | 195 - java/JavaTranspiler.js | 174 - java/Layout-test-utils.c | 216 - java/Layout-test-utils.h | 18 - java/Layout-test-utils.js | 604 - java/Layout.c | 1817 --- java/Layout.h | 200 - java/Layout.js | 1708 --- .../com/facebook/csslayout/CSSAlign.java | 3 +- .../csslayout/CSSCachedMeasurement.java | 3 +- .../com/facebook/csslayout/CSSConstants.java | 3 +- .../com/facebook/csslayout/CSSDirection.java | 3 +- .../facebook/csslayout/CSSFlexDirection.java | 3 +- .../com/facebook/csslayout/CSSJustify.java | 3 +- .../com/facebook/csslayout/CSSLayout.java | 3 +- .../facebook/csslayout/CSSLayoutContext.java | 3 +- .../facebook/csslayout/CSSMeasureMode.java | 3 +- .../com/facebook/csslayout/CSSNode.java | 3 +- .../com/facebook/csslayout/CSSOverflow.java | 3 +- .../facebook/csslayout/CSSPositionType.java | 3 +- .../com/facebook/csslayout/CSSStyle.java | 3 +- .../com/facebook/csslayout/CSSWrap.java | 3 +- .../facebook/csslayout/CachedCSSLayout.java | 3 +- .../com/facebook/csslayout/FloatUtil.java | 3 +- .../com/facebook/csslayout/LayoutEngine.java | 269 +- .../com/facebook/csslayout/MeasureOutput.java | 3 +- .../com/facebook/csslayout/Spacing.java | 3 +- java/csharp/.editorconfig | 13 - java/csharp/.gitignore | 6 - .../Facebook.CSSLayout.Tests/CSSNodeTest.cs | 53 - .../Facebook.CSSLayout.Tests.csproj | 70 - .../LayoutCachingTest.cs | 240 - .../LayoutEngineTest.cs | 9900 ----------------- .../Properties/AssemblyInfo.cs | 27 - .../Facebook.CSSLayout.Tests/TestConstants.cs | 30 - .../Facebook.CSSLayout.Tests/packages.config | 4 - java/csharp/Facebook.CSSLayout.sln | 34 - java/csharp/Facebook.CSSLayout/Assertions.cs | 27 - .../CSSCachedMeasurement.cs | 22 - .../csharp/Facebook.CSSLayout/CSSConstants.cs | 21 - .../csharp/Facebook.CSSLayout/CSSDirection.cs | 18 - .../Facebook.CSSLayout/CSSFlexDirection.cs | 19 - java/csharp/Facebook.CSSLayout/CSSJustify.cs | 20 - java/csharp/Facebook.CSSLayout/CSSLayout.cs | 89 - .../Facebook.CSSLayout/CSSLayoutContext.cs | 27 - .../Facebook.CSSLayout/CSSMeasureMode.cs | 18 - java/csharp/Facebook.CSSLayout/CSSNode.cs | 558 - java/csharp/Facebook.CSSLayout/CSSOverflow.cs | 17 - .../Facebook.CSSLayout/CSSPositionType.cs | 17 - .../Facebook.CSSLayout/CSSSpacingType.cs | 24 - java/csharp/Facebook.CSSLayout/CSSStyle.cs | 50 - java/csharp/Facebook.CSSLayout/CSSWrap.cs | 16 - .../Facebook.CSSLayout/CachedCSSLayout.cs | 25 - .../Facebook.CSSLayout.csproj | 73 - .../Facebook.CSSLayout.nuspec | 17 - java/csharp/Facebook.CSSLayout/FloatUtil.cs | 27 - .../csharp/Facebook.CSSLayout/LayoutEngine.cs | 1452 --- .../Facebook.CSSLayout/MeasureOutput.cs | 36 - .../Facebook.CSSLayout/NullableAttribute.cs | 22 - .../Properties/AssemblyInfo.cs | 27 - java/csharp/Facebook.CSSLayout/Spacing.cs | 234 - java/csharp/Makefile | 37 - java/css-layout.js | 29 - java/java/.idea/.name | 1 - java/java/.idea/compiler.xml | 23 - .../.idea/copyright/profiles_settings.xml | 5 - java/java/.idea/encodings.xml | 5 - java/java/.idea/misc.xml | 10 - java/java/.idea/modules.xml | 9 - java/java/.idea/scopes/scope_settings.xml | 5 - java/java/.idea/uiDesigner.xml | 125 - java/java/.idea/vcs.xml | 7 - java/java/java.iml | 22 - java/transpile.js | 349 - lib/gtest/BUCK | 42 + lib/infer-annotations/BUCK | 21 + .../infer-annotations-1.4.jar | Bin lib/jsr-305/BUCK | 21 + {java/java/lib => lib/jsr-305}/jsr305.jar | Bin lib/junit/BUCK | 21 + {java/java/lib => lib/junit}/junit4.jar | Bin package.json | 47 - tests/CSSLayoutTest.cpp | 9361 ++++++++++++++++ tests/CSSLayoutTestUtils/CSSLayoutTestUtils.c | 121 + tests/CSSLayoutTestUtils/CSSLayoutTestUtils.h | 43 + tests/Layout-consts-test.js | 22 - tests/Layout-random-test.js | 122 - tests/Layout-test.c | 9382 ---------------- tests/Layout-test.js | 3049 ----- .../com/facebook/csslayout/CSSNodeTest.java | 3 +- .../facebook/csslayout/LayoutCachingTest.java | 3 +- .../facebook/csslayout/LayoutEngineTest.java | 129 +- .../com/facebook/csslayout/TestConstants.java | 10 +- 118 files changed, 11099 insertions(+), 34574 deletions(-) create mode 100644 .buckconfig create mode 100644 .buckversion delete mode 100644 .eslintrc create mode 100644 .hgignore delete mode 100644 .travis.yml create mode 100644 BUCK rename CONTRIBUTING.md => CONTRIBUTING (100%) create mode 100644 CSSLAYOUT_DEFS create mode 100644 CSSLayout/CSSLayout-internal.h rename dist/css-layout.h => CSSLayout/CSSLayout.c (51%) create mode 100644 CSSLayout/CSSLayout.h rename java/csharp/Facebook.CSSLayout/CSSAlign.cs => CSSLayout/CSSMacros.h (50%) create mode 100644 CSSLayout/CSSNodeList.c create mode 100644 CSSLayout/CSSNodeList.h delete mode 100644 Gruntfile.js create mode 100644 README delete mode 100644 README.md delete mode 100644 TestResult.xml delete mode 100644 dist/README.md delete mode 100644 dist/css-layout.jar delete mode 100644 dist/css-layout.js delete mode 100644 dist/css-layout.min.js delete mode 100644 dist/css-layout.min.js.map delete mode 100644 java/CSharpTranspiler.js delete mode 100644 java/JavaTranspiler.js delete mode 100644 java/Layout-test-utils.c delete mode 100644 java/Layout-test-utils.h delete mode 100644 java/Layout-test-utils.js delete mode 100644 java/Layout.c delete mode 100644 java/Layout.h delete mode 100755 java/Layout.js rename java/{java/src => }/com/facebook/csslayout/CSSAlign.java (88%) rename java/{java/src => }/com/facebook/csslayout/CSSCachedMeasurement.java (92%) rename java/{java/src => }/com/facebook/csslayout/CSSConstants.java (91%) rename java/{java/src => }/com/facebook/csslayout/CSSDirection.java (88%) rename java/{java/src => }/com/facebook/csslayout/CSSFlexDirection.java (88%) rename java/{java/src => }/com/facebook/csslayout/CSSJustify.java (89%) rename java/{java/src => }/com/facebook/csslayout/CSSLayout.java (98%) rename java/{java/src => }/com/facebook/csslayout/CSSLayoutContext.java (93%) rename java/{java/src => }/com/facebook/csslayout/CSSMeasureMode.java (88%) rename java/{java/src => }/com/facebook/csslayout/CSSNode.java (99%) rename java/{java/src => }/com/facebook/csslayout/CSSOverflow.java (88%) rename java/{java/src => }/com/facebook/csslayout/CSSPositionType.java (88%) rename java/{java/src => }/com/facebook/csslayout/CSSStyle.java (97%) rename java/{java/src => }/com/facebook/csslayout/CSSWrap.java (87%) rename java/{java/src => }/com/facebook/csslayout/CachedCSSLayout.java (94%) rename java/{java/src => }/com/facebook/csslayout/FloatUtil.java (92%) rename java/{java/src => }/com/facebook/csslayout/LayoutEngine.java (99%) rename java/{java/src => }/com/facebook/csslayout/MeasureOutput.java (90%) rename java/{java/src => }/com/facebook/csslayout/Spacing.java (99%) delete mode 100644 java/csharp/.editorconfig delete mode 100644 java/csharp/.gitignore delete mode 100644 java/csharp/Facebook.CSSLayout.Tests/CSSNodeTest.cs delete mode 100755 java/csharp/Facebook.CSSLayout.Tests/Facebook.CSSLayout.Tests.csproj delete mode 100644 java/csharp/Facebook.CSSLayout.Tests/LayoutCachingTest.cs delete mode 100644 java/csharp/Facebook.CSSLayout.Tests/LayoutEngineTest.cs delete mode 100755 java/csharp/Facebook.CSSLayout.Tests/Properties/AssemblyInfo.cs delete mode 100644 java/csharp/Facebook.CSSLayout.Tests/TestConstants.cs delete mode 100755 java/csharp/Facebook.CSSLayout.Tests/packages.config delete mode 100755 java/csharp/Facebook.CSSLayout.sln delete mode 100755 java/csharp/Facebook.CSSLayout/Assertions.cs delete mode 100644 java/csharp/Facebook.CSSLayout/CSSCachedMeasurement.cs delete mode 100644 java/csharp/Facebook.CSSLayout/CSSConstants.cs delete mode 100755 java/csharp/Facebook.CSSLayout/CSSDirection.cs delete mode 100644 java/csharp/Facebook.CSSLayout/CSSFlexDirection.cs delete mode 100644 java/csharp/Facebook.CSSLayout/CSSJustify.cs delete mode 100644 java/csharp/Facebook.CSSLayout/CSSLayout.cs delete mode 100755 java/csharp/Facebook.CSSLayout/CSSLayoutContext.cs delete mode 100644 java/csharp/Facebook.CSSLayout/CSSMeasureMode.cs delete mode 100644 java/csharp/Facebook.CSSLayout/CSSNode.cs delete mode 100644 java/csharp/Facebook.CSSLayout/CSSOverflow.cs delete mode 100644 java/csharp/Facebook.CSSLayout/CSSPositionType.cs delete mode 100755 java/csharp/Facebook.CSSLayout/CSSSpacingType.cs delete mode 100644 java/csharp/Facebook.CSSLayout/CSSStyle.cs delete mode 100644 java/csharp/Facebook.CSSLayout/CSSWrap.cs delete mode 100644 java/csharp/Facebook.CSSLayout/CachedCSSLayout.cs delete mode 100755 java/csharp/Facebook.CSSLayout/Facebook.CSSLayout.csproj delete mode 100755 java/csharp/Facebook.CSSLayout/Facebook.CSSLayout.nuspec delete mode 100644 java/csharp/Facebook.CSSLayout/FloatUtil.cs delete mode 100644 java/csharp/Facebook.CSSLayout/LayoutEngine.cs delete mode 100644 java/csharp/Facebook.CSSLayout/MeasureOutput.cs delete mode 100755 java/csharp/Facebook.CSSLayout/NullableAttribute.cs delete mode 100755 java/csharp/Facebook.CSSLayout/Properties/AssemblyInfo.cs delete mode 100644 java/csharp/Facebook.CSSLayout/Spacing.cs delete mode 100644 java/csharp/Makefile delete mode 100644 java/css-layout.js delete mode 100644 java/java/.idea/.name delete mode 100644 java/java/.idea/compiler.xml delete mode 100644 java/java/.idea/copyright/profiles_settings.xml delete mode 100644 java/java/.idea/encodings.xml delete mode 100644 java/java/.idea/misc.xml delete mode 100644 java/java/.idea/modules.xml delete mode 100644 java/java/.idea/scopes/scope_settings.xml delete mode 100644 java/java/.idea/uiDesigner.xml delete mode 100644 java/java/.idea/vcs.xml delete mode 100644 java/java/java.iml delete mode 100644 java/transpile.js create mode 100644 lib/gtest/BUCK create mode 100644 lib/infer-annotations/BUCK rename {java/java/lib => lib/infer-annotations}/infer-annotations-1.4.jar (100%) create mode 100644 lib/jsr-305/BUCK rename {java/java/lib => lib/jsr-305}/jsr305.jar (100%) create mode 100644 lib/junit/BUCK rename {java/java/lib => lib/junit}/junit4.jar (100%) delete mode 100644 package.json create mode 100644 tests/CSSLayoutTest.cpp create mode 100644 tests/CSSLayoutTestUtils/CSSLayoutTestUtils.c create mode 100644 tests/CSSLayoutTestUtils/CSSLayoutTestUtils.h delete mode 100644 tests/Layout-consts-test.js delete mode 100644 tests/Layout-random-test.js delete mode 100644 tests/Layout-test.c delete mode 100755 tests/Layout-test.js rename {java/java/tests => tests/java}/com/facebook/csslayout/CSSNodeTest.java (96%) rename {java/java/tests => tests/java}/com/facebook/csslayout/LayoutCachingTest.java (99%) rename {java/java/tests => tests/java}/com/facebook/csslayout/LayoutEngineTest.java (98%) rename {java/java/tests => tests/java}/com/facebook/csslayout/TestConstants.java (79%) diff --git a/.buckconfig b/.buckconfig new file mode 100644 index 00000000..74a40a76 --- /dev/null +++ b/.buckconfig @@ -0,0 +1,2 @@ +[cxx] + gtest_dep = //lib/gtest:gtest diff --git a/.buckversion b/.buckversion new file mode 100644 index 00000000..e4b27eaf --- /dev/null +++ b/.buckversion @@ -0,0 +1 @@ +158950c02e1553d3a17979e74d9df020594e4d30 diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index 91d700b9..00000000 --- a/.eslintrc +++ /dev/null @@ -1,20 +0,0 @@ -{ - "extends": "./node_modules/fbjs-scripts/eslint/.eslintrc", - "globals": { - "jasmine": true, - "describe": true, - "beforeEach": true, - "afterEach": true, - "spyOn": true, - "it": true, - "xit": true, - "expect": true, - "require": true, - "global": true, - "__dirname": true, - "module": true, - "console": true, - "setTimeout": true, - "define": true - } -} diff --git a/.gitignore b/.gitignore index b7fd170c..9b3e6804 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ -a.out -*.class -/**/java/out/* -/**/.idea/workspace.xml -/lib/ -/node_modules/ -npm-debug.log +.DS_STORE + +/buck-cache/ +/buck-out/ +/.buckconfig.local +/.buckd +/lib/gtest/googletest-*/ diff --git a/.hgignore b/.hgignore new file mode 100644 index 00000000..9b3e6804 --- /dev/null +++ b/.hgignore @@ -0,0 +1,7 @@ +.DS_STORE + +/buck-cache/ +/buck-out/ +/.buckconfig.local +/.buckd +/lib/gtest/googletest-*/ diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index f42fbfed..00000000 --- a/.travis.yml +++ /dev/null @@ -1,18 +0,0 @@ -language: node_js -node_js: - - "0.12" - -sudo: true - -before_install: - - npm install grunt-cli -g - - sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF - - echo "deb http://download.mono-project.com/repo/debian wheezy main" | sudo tee /etc/apt/sources.list.d/mono-xamarin.list - - echo "deb http://download.mono-project.com/repo/debian wheezy-libtiff-compat main" | sudo tee -a /etc/apt/sources.list.d/mono-xamarin.list - - sudo apt-get -qq update - - sudo apt-get -qq install mono-devel referenceassemblies-pcl nunit - -addons: - apt: - packages: - - gcc diff --git a/BUCK b/BUCK new file mode 100644 index 00000000..b098c8e0 --- /dev/null +++ b/BUCK @@ -0,0 +1,81 @@ +# Copyright (c) 2014-present, Facebook, Inc. +# All rights reserved. +# +# This source code is licensed under the BSD-style license found in the +# LICENSE file in the root directory of this source tree. An additional grant +# of patent rights can be found in the PATENTS file in the same directory. + +include_defs('//CSSLAYOUT_DEFS') + +BASE_COMPILER_FLAGS = [ + '-fno-omit-frame-pointer', + '-fexceptions', + '-Wall', + '-Werror', +] + +GMOCK_OVERRIDE_FLAGS = [ + # gmock does not mark mocked methods as override, ignore the warnings in tests + '-Wno-inconsistent-missing-override', +] + +COMPILER_FLAGS = BASE_COMPILER_FLAGS + ['-std=c11'] +TEST_COMPILER_FLAGS = BASE_COMPILER_FLAGS + GMOCK_OVERRIDE_FLAGS + ['-std=c++11'] + +cxx_library( + name = 'CSSLayout', + srcs = glob(['CSSLayout/*.c']), + tests=[':CSSLayout_tests'], + exported_headers = subdir_glob([('', 'CSSLayout/*.h')]), + header_namespace = '', + compiler_flags = COMPILER_FLAGS, + deps = [], + visibility = ['PUBLIC'], +) + +cxx_library( + name = 'CSSLayoutTestUtils', + srcs = glob(['tests/CSSLayoutTestUtils/*.c']), + exported_headers = subdir_glob([('tests', 'CSSLayoutTestUtils/*.h')]), + header_namespace = '', + compiler_flags = COMPILER_FLAGS, + deps = [ + ':CSSLayout', + ], + visibility = ['PUBLIC'], +) + +cxx_test( + name = 'CSSLayout_tests', + contacts = ['emilsj@fb.com'], + srcs = glob(['tests/*.cpp']), + compiler_flags = TEST_COMPILER_FLAGS, + deps = [ + ':CSSLayout', + ':CSSLayoutTestUtils', + GTEST_TARGET, + ], + visibility = ['PUBLIC'], +) + +java_library( + name = 'CSSLayout_java', + srcs = glob(['java/**/*.java']), + tests=[':CSSLayout_java_tests'], + source = '1.7', + target = '1.7', + deps = [ + INFER_ANNOTATIONS_TARGET, + JSR_305_TARGET, + ], + visibility = ['PUBLIC'], +) + +java_test( + name = 'CSSLayout_java_tests', + srcs = glob(['tests/java/**/*.java']), + deps = [ + ':CSSLayout_java', + JUNIT_TARGET, + ], +) diff --git a/CONTRIBUTING.md b/CONTRIBUTING similarity index 100% rename from CONTRIBUTING.md rename to CONTRIBUTING diff --git a/CSSLAYOUT_DEFS b/CSSLAYOUT_DEFS new file mode 100644 index 00000000..29559bc8 --- /dev/null +++ b/CSSLAYOUT_DEFS @@ -0,0 +1,7 @@ + +CSSLAYOUT_ROOT = '//...' +INFER_ANNOTATIONS_TARGET = '//lib/infer-annotations:infer-annotations' +JSR_305_TARGET = '//lib/jsr-305:jsr-305' +JUNIT_TARGET = '//lib/junit:junit' +GTEST_TARGET = '//lib/gtest:gtest' +GTEST_DL_URL = 'https://github.com/google/googletest/archive/release-1.7.0.zip' diff --git a/CSSLayout/CSSLayout-internal.h b/CSSLayout/CSSLayout-internal.h new file mode 100644 index 00000000..2c65026c --- /dev/null +++ b/CSSLayout/CSSLayout-internal.h @@ -0,0 +1,105 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#ifndef __CSS_LAYOUT_INTERNAL_H +#define __CSS_LAYOUT_INTERNAL_H + +#include +#include + +#include "CSSLayout.h" +#include "CSSNodeList.h" + +CSS_EXTERN_C_BEGIN + +typedef struct CSSCachedMeasurement { + float availableWidth; + float availableHeight; + CSSMeasureMode widthMeasureMode; + CSSMeasureMode heightMeasureMode; + + float computedWidth; + float computedHeight; +} CSSCachedMeasurement; + +// This value was chosen based on empiracle data. Even the most complicated +// layouts should not require more than 16 entries to fit within the cache. +enum { + CSS_MAX_CACHED_RESULT_COUNT = 16 +}; + +typedef struct CSSLayout { + float position[4]; + float dimensions[2]; + CSSDirection direction; + + float flexBasis; + + // Instead of recomputing the entire layout every single time, we + // cache some information to break early when nothing changed + int generationCount; + CSSDirection lastParentDirection; + + int nextCachedMeasurementsIndex; + CSSCachedMeasurement cachedMeasurements[CSS_MAX_CACHED_RESULT_COUNT]; + float measuredDimensions[2]; + + CSSCachedMeasurement cached_layout; +} CSSLayout; + +typedef struct CSSStyle { + CSSDirection direction; + CSSFlexDirection flexDirection; + CSSJustify justifyContent; + CSSAlign alignContent; + CSSAlign alignItems; + CSSAlign alignSelf; + CSSPositionType positionType; + CSSWrapType flexWrap; + CSSOverflow overflow; + float flex; + float margin[6]; + float position[4]; + /** + * You should skip all the rules that contain negative values for the + * following attributes. For example: + * {padding: 10, paddingLeft: -5} + * should output: + * {left: 10 ...} + * the following two are incorrect: + * {left: -5 ...} + * {left: 0 ...} + */ + float padding[6]; + float border[6]; + float dimensions[2]; + float minDimensions[2]; + float maxDimensions[2]; +} CSSStyle; + +typedef struct CSSNode { + CSSStyle style; + CSSLayout layout; + int lineIndex; + bool shouldUpdate; + bool isTextNode; + CSSNodeRef parent; + CSSNodeListRef children; + bool isDirty; + + struct CSSNode* nextChild; + + CSSSize (*measure)(void *context, float width, CSSMeasureMode widthMode, float height, CSSMeasureMode heightMode); + void (*print)(void *context); + void *context; +} CSSNode; + +CSS_EXTERN_C_END + +#endif diff --git a/dist/css-layout.h b/CSSLayout/CSSLayout.c similarity index 51% rename from dist/css-layout.h rename to CSSLayout/CSSLayout.c index 44160d61..49136970 100644 --- a/dist/css-layout.h +++ b/CSSLayout/CSSLayout.c @@ -1,211 +1,5 @@ -/* - * #define CSS_LAYOUT_IMPLEMENTATION - * before you include this file in *one* C or C++ file to create the implementation. - */ /** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -#ifndef __LAYOUT_H -#define __LAYOUT_H - -#include -#ifndef __cplusplus -#include -#endif - -// Not defined in MSVC++ -#ifndef NAN -static const unsigned long __nan[2] = {0xffffffff, 0x7fffffff}; -#define NAN (*(const float *)__nan) -#endif - -#define CSS_UNDEFINED NAN - -typedef enum { - CSS_DIRECTION_INHERIT = 0, - CSS_DIRECTION_LTR, - CSS_DIRECTION_RTL -} css_direction_t; - -typedef enum { - CSS_FLEX_DIRECTION_COLUMN = 0, - CSS_FLEX_DIRECTION_COLUMN_REVERSE, - CSS_FLEX_DIRECTION_ROW, - CSS_FLEX_DIRECTION_ROW_REVERSE -} css_flex_direction_t; - -typedef enum { - CSS_JUSTIFY_FLEX_START = 0, - CSS_JUSTIFY_CENTER, - CSS_JUSTIFY_FLEX_END, - CSS_JUSTIFY_SPACE_BETWEEN, - CSS_JUSTIFY_SPACE_AROUND -} css_justify_t; - -typedef enum { - CSS_OVERFLOW_VISIBLE = 0, - CSS_OVERFLOW_HIDDEN -} css_overflow_t; - -// Note: auto is only a valid value for alignSelf. It is NOT a valid value for -// alignItems. -typedef enum { - CSS_ALIGN_AUTO = 0, - CSS_ALIGN_FLEX_START, - CSS_ALIGN_CENTER, - CSS_ALIGN_FLEX_END, - CSS_ALIGN_STRETCH -} css_align_t; - -typedef enum { - CSS_POSITION_RELATIVE = 0, - CSS_POSITION_ABSOLUTE -} css_position_type_t; - -typedef enum { - CSS_NOWRAP = 0, - CSS_WRAP -} css_wrap_type_t; - -// Note: left and top are shared between position[2] and position[4], so -// they have to be before right and bottom. -typedef enum { - CSS_LEFT = 0, - CSS_TOP, - CSS_RIGHT, - CSS_BOTTOM, - CSS_START, - CSS_END, - CSS_POSITION_COUNT -} css_position_t; - -typedef enum { - CSS_MEASURE_MODE_UNDEFINED = 0, - CSS_MEASURE_MODE_EXACTLY, - CSS_MEASURE_MODE_AT_MOST, - CSS_MEASURE_MODE_COUNT -} css_measure_mode_t; - -typedef enum { - CSS_WIDTH = 0, - CSS_HEIGHT -} css_dimension_t; - -typedef struct { - float available_width; - float available_height; - css_measure_mode_t width_measure_mode; - css_measure_mode_t height_measure_mode; - - float computed_width; - float computed_height; -} css_cached_measurement_t; - -enum { - // This value was chosen based on empiracle data. Even the most complicated - // layouts should not require more than 16 entries to fit within the cache. - CSS_MAX_CACHED_RESULT_COUNT = 16 -}; - -typedef struct { - float position[4]; - float dimensions[2]; - css_direction_t direction; - - float flex_basis; - - // Instead of recomputing the entire layout every single time, we - // cache some information to break early when nothing changed - bool should_update; - int generation_count; - css_direction_t last_parent_direction; - - int next_cached_measurements_index; - css_cached_measurement_t cached_measurements[CSS_MAX_CACHED_RESULT_COUNT]; - float measured_dimensions[2]; - - css_cached_measurement_t cached_layout; -} css_layout_t; - -typedef struct { - float dimensions[2]; -} css_dim_t; - -typedef struct { - css_direction_t direction; - css_flex_direction_t flex_direction; - css_justify_t justify_content; - css_align_t align_content; - css_align_t align_items; - css_align_t align_self; - css_position_type_t position_type; - css_wrap_type_t flex_wrap; - css_overflow_t overflow; - float flex; - float margin[6]; - float position[4]; - /** - * You should skip all the rules that contain negative values for the - * following attributes. For example: - * {padding: 10, paddingLeft: -5} - * should output: - * {left: 10 ...} - * the following two are incorrect: - * {left: -5 ...} - * {left: 0 ...} - */ - float padding[6]; - float border[6]; - float dimensions[2]; - float minDimensions[2]; - float maxDimensions[2]; -} css_style_t; - -typedef struct css_node css_node_t; -struct css_node { - css_style_t style; - css_layout_t layout; - int children_count; - int line_index; - - css_node_t* next_child; - - css_dim_t (*measure)(void *context, float width, css_measure_mode_t widthMode, float height, css_measure_mode_t heightMode); - void (*print)(void *context); - struct css_node* (*get_child)(void *context, int i); - bool (*is_dirty)(void *context); - bool (*is_text_node)(void *context); - void *context; -}; - -// Lifecycle of nodes and children -css_node_t *new_css_node(void); -void init_css_node(css_node_t *node); -void free_css_node(css_node_t *node); - -// Print utilities -typedef enum { - CSS_PRINT_LAYOUT = 1, - CSS_PRINT_STYLE = 2, - CSS_PRINT_CHILDREN = 4, -} css_print_options_t; -void print_css_node(css_node_t *node, css_print_options_t options); - -// Function that computes the layout! -void layoutNode(css_node_t *node, float availableWidth, float availableHeight, css_direction_t parentDirection); -bool isUndefined(float value); - -#endif - -#ifdef CSS_LAYOUT_IMPLEMENTATION -/** - * Copyright (c) 2014, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the @@ -219,10 +13,7 @@ bool isUndefined(float value); #include #include -// in concatenated header, don't include Layout.h it's already at the top -#ifndef CSS_LAYOUT_IMPLEMENTATION -#include "Layout.h" -#endif +#include "CSSLayout-internal.h" #ifdef _MSC_VER #include @@ -238,10 +29,190 @@ __forceinline const float fmaxf(const float a, const float b) { #define POSITIVE_FLEX_IS_AUTO 0 +CSSNodeRef CSSNodeNew() { + CSSNodeRef node = calloc(1, sizeof(CSSNode)); + assert(node != NULL); + + CSSNodeInit(node); + return node; +} + +void CSSNodeFree(CSSNodeRef node) { + CSSNodeListFree(node->children); + free(node); +} + +void CSSNodeInit(CSSNodeRef node) { + node->parent = NULL; + node->children = CSSNodeListNew(4); + node->shouldUpdate = true; + node->isDirty = false; + + node->style.alignItems = CSSAlignStretch; + node->style.alignContent = CSSAlignFlexStart; + + node->style.direction = CSSDirectionInherit; + node->style.flexDirection = CSSFlexDirectionColumn; + + node->style.overflow = CSSOverflowVisible; + + // Some of the fields default to undefined and not 0 + node->style.dimensions[CSSDimensionWidth] = CSSUndefined; + node->style.dimensions[CSSDimensionHeight] = CSSUndefined; + + node->style.minDimensions[CSSDimensionWidth] = CSSUndefined; + node->style.minDimensions[CSSDimensionHeight] = CSSUndefined; + + node->style.maxDimensions[CSSDimensionWidth] = CSSUndefined; + node->style.maxDimensions[CSSDimensionHeight] = CSSUndefined; + + node->style.position[CSSPositionLeft] = CSSUndefined; + node->style.position[CSSPositionTop] = CSSUndefined; + node->style.position[CSSPositionRight] = CSSUndefined; + node->style.position[CSSPositionBottom] = CSSUndefined; + + node->style.margin[CSSPositionStart] = CSSUndefined; + node->style.margin[CSSPositionEnd] = CSSUndefined; + node->style.padding[CSSPositionStart] = CSSUndefined; + node->style.padding[CSSPositionEnd] = CSSUndefined; + node->style.border[CSSPositionStart] = CSSUndefined; + node->style.border[CSSPositionEnd] = CSSUndefined; + + node->layout.dimensions[CSSDimensionWidth] = CSSUndefined; + node->layout.dimensions[CSSDimensionHeight] = CSSUndefined; + + // Such that the comparison is always going to be false + node->layout.lastParentDirection = (CSSDirection)-1; + node->layout.nextCachedMeasurementsIndex = 0; + + node->layout.measuredDimensions[CSSDimensionWidth] = CSSUndefined; + node->layout.measuredDimensions[CSSDimensionHeight] = CSSUndefined; + node->layout.cached_layout.widthMeasureMode = (CSSMeasureMode)-1; + node->layout.cached_layout.heightMeasureMode = (CSSMeasureMode)-1; +} + +void _CSSNodeMarkDirty(CSSNodeRef node) { + if (!node->isDirty) { + node->isDirty = true; + if (node->parent) { + _CSSNodeMarkDirty(node->parent); + } + } +} + +void CSSNodeInsertChild(CSSNodeRef node, CSSNodeRef child, unsigned int index) { + CSSNodeListInsert(node->children, child, index); + child->parent = node; + _CSSNodeMarkDirty(node); +} + +void CSSNodeRemoveChild(CSSNodeRef node, CSSNodeRef child) { + CSSNodeListDelete(node->children, child); + child->parent = NULL; + _CSSNodeMarkDirty(node); +} + +CSSNodeRef CSSNodeGetChild(CSSNodeRef node, unsigned int index) { + return CSSNodeListGet(node->children, index); +} + +unsigned int CSSNodeChildCount(CSSNodeRef node) { + return CSSNodeListCount(node->children); +} + +void CSSNodeMarkDirty(CSSNodeRef node) { + // Nodes without custom measure functions should not manually mark themselves as dirty + assert(node->measure != NULL); + _CSSNodeMarkDirty(node); +} + +#define CSS_NODE_PROPERTY_IMPL(type, name, paramName, instanceName) \ +void CSSNodeSet##name(CSSNodeRef node, type paramName) { \ + node->instanceName = paramName; \ +} \ +\ +type CSSNodeGet##name(CSSNodeRef node) { \ + return node->instanceName; \ +} \ + +#define CSS_NODE_STYLE_PROPERTY_IMPL(type, name, paramName, instanceName) \ +void CSSNodeStyleSet##name(CSSNodeRef node, type paramName) { \ + if (node->style.instanceName != paramName) { \ + node->style.instanceName = paramName; \ + _CSSNodeMarkDirty(node); \ + } \ +} \ +\ +type CSSNodeStyleGet##name(CSSNodeRef node) { \ + return node->style.instanceName; \ +} \ + +#define CSS_NODE_LAYOUT_PROPERTY_IMPL(type, name, instanceName) \ +type CSSNodeLayoutGet##name(CSSNodeRef node) { \ + return node->layout.instanceName; \ +} \ + +CSS_NODE_PROPERTY_IMPL(void*, Context, context, context); +CSS_NODE_PROPERTY_IMPL(CSSMeasureFunc, MeasureFunc, measureFunc, measure); +CSS_NODE_PROPERTY_IMPL(CSSPrintFunc, PrintFunc, printFunc, print); +CSS_NODE_PROPERTY_IMPL(bool, IsTextnode, isTextNode, isTextNode); +CSS_NODE_PROPERTY_IMPL(bool, ShouldUpdate, shouldUpdate, shouldUpdate); + +CSS_NODE_STYLE_PROPERTY_IMPL(CSSDirection, Direction, direction, direction); +CSS_NODE_STYLE_PROPERTY_IMPL(CSSFlexDirection, FlexDirection, flexDirection, flexDirection); +CSS_NODE_STYLE_PROPERTY_IMPL(CSSJustify, JustifyContent, justifyContent, justifyContent); +CSS_NODE_STYLE_PROPERTY_IMPL(CSSAlign, AlignContent, alignContent, alignContent); +CSS_NODE_STYLE_PROPERTY_IMPL(CSSAlign, AlignItems, alignItems, alignItems); +CSS_NODE_STYLE_PROPERTY_IMPL(CSSAlign, AlignSelf, alignSelf, alignSelf); +CSS_NODE_STYLE_PROPERTY_IMPL(CSSPositionType, PositionType, positionType, positionType); +CSS_NODE_STYLE_PROPERTY_IMPL(CSSWrapType, FlexWrap, flexWrap, flexWrap); +CSS_NODE_STYLE_PROPERTY_IMPL(CSSOverflow, Overflow, overflow, overflow); +CSS_NODE_STYLE_PROPERTY_IMPL(float, Flex, flex, flex); + +CSS_NODE_STYLE_PROPERTY_IMPL(float, PositionLeft, positionLeft, position[CSSPositionLeft]); +CSS_NODE_STYLE_PROPERTY_IMPL(float, PositionTop, positionTop, position[CSSPositionTop]); +CSS_NODE_STYLE_PROPERTY_IMPL(float, PositionRight, positionRight, position[CSSPositionRight]); +CSS_NODE_STYLE_PROPERTY_IMPL(float, PositionBottom, positionBottom, position[CSSPositionBottom]); + +CSS_NODE_STYLE_PROPERTY_IMPL(float, MarginLeft, marginLeft, margin[CSSPositionLeft]); +CSS_NODE_STYLE_PROPERTY_IMPL(float, MarginTop, marginTop, margin[CSSPositionTop]); +CSS_NODE_STYLE_PROPERTY_IMPL(float, MarginRight, marginRight, margin[CSSPositionRight]); +CSS_NODE_STYLE_PROPERTY_IMPL(float, MarginBottom, marginBottom, margin[CSSPositionBottom]); +CSS_NODE_STYLE_PROPERTY_IMPL(float, MarginStart, marginStart, margin[CSSPositionStart]); +CSS_NODE_STYLE_PROPERTY_IMPL(float, MarginEnd, marginEnd, margin[CSSPositionEnd]); + +CSS_NODE_STYLE_PROPERTY_IMPL(float, PaddingLeft, paddingLeft, padding[CSSPositionLeft]); +CSS_NODE_STYLE_PROPERTY_IMPL(float, PaddingTop, paddingTop, padding[CSSPositionTop]); +CSS_NODE_STYLE_PROPERTY_IMPL(float, PaddingRight, paddingRight, padding[CSSPositionRight]); +CSS_NODE_STYLE_PROPERTY_IMPL(float, PaddingBottom, paddingBottom, padding[CSSPositionBottom]); +CSS_NODE_STYLE_PROPERTY_IMPL(float, PaddingStart, paddingStart, padding[CSSPositionStart]); +CSS_NODE_STYLE_PROPERTY_IMPL(float, PaddingEnd, paddingEnd, padding[CSSPositionEnd]); + +CSS_NODE_STYLE_PROPERTY_IMPL(float, BorderLeft, borderLeft, border[CSSPositionLeft]); +CSS_NODE_STYLE_PROPERTY_IMPL(float, BorderTop, borderTop, border[CSSPositionTop]); +CSS_NODE_STYLE_PROPERTY_IMPL(float, BorderRight, borderRight, border[CSSPositionRight]); +CSS_NODE_STYLE_PROPERTY_IMPL(float, BorderBottom, borderBottom, border[CSSPositionBottom]); +CSS_NODE_STYLE_PROPERTY_IMPL(float, BorderStart, borderStart, border[CSSPositionStart]); +CSS_NODE_STYLE_PROPERTY_IMPL(float, BorderEnd, BorderEnd, border[CSSPositionEnd]); + +CSS_NODE_STYLE_PROPERTY_IMPL(float, Width, width, dimensions[CSSDimensionWidth]); +CSS_NODE_STYLE_PROPERTY_IMPL(float, Height, height, dimensions[CSSDimensionHeight]); +CSS_NODE_STYLE_PROPERTY_IMPL(float, MinWidth, minWidth, minDimensions[CSSDimensionWidth]); +CSS_NODE_STYLE_PROPERTY_IMPL(float, MinHeight, minHeight, minDimensions[CSSDimensionHeight]); +CSS_NODE_STYLE_PROPERTY_IMPL(float, MaxWidth, maxWidth, maxDimensions[CSSDimensionWidth]); +CSS_NODE_STYLE_PROPERTY_IMPL(float, MaxHeight, maxHeight, maxDimensions[CSSDimensionHeight]); + +CSS_NODE_LAYOUT_PROPERTY_IMPL(float, Left, position[CSSPositionLeft]); +CSS_NODE_LAYOUT_PROPERTY_IMPL(float, Top, position[CSSPositionTop]); +CSS_NODE_LAYOUT_PROPERTY_IMPL(float, Right, position[CSSPositionRight]); +CSS_NODE_LAYOUT_PROPERTY_IMPL(float, Bottom, position[CSSPositionBottom]); +CSS_NODE_LAYOUT_PROPERTY_IMPL(float, Width, dimensions[CSSDimensionWidth]); +CSS_NODE_LAYOUT_PROPERTY_IMPL(float, Height, dimensions[CSSDimensionHeight]); + int gCurrentGenerationCount = 0; -bool layoutNodeInternal(css_node_t* node, float availableWidth, float availableHeight, css_direction_t parentDirection, - css_measure_mode_t widthMeasureMode, css_measure_mode_t heightMeasureMode, bool performLayout, char* reason); +bool layoutNodeInternal(CSSNode* node, float availableWidth, float availableHeight, CSSDirection parentDirection, + CSSMeasureMode widthMeasureMode, CSSMeasureMode heightMeasureMode, bool performLayout, char* reason); bool isUndefined(float value) { return isnan(value); @@ -254,61 +225,6 @@ static bool eq(float a, float b) { return fabs(a - b) < 0.0001; } -void init_css_node(css_node_t* node) { - node->style.align_items = CSS_ALIGN_STRETCH; - node->style.align_content = CSS_ALIGN_FLEX_START; - - node->style.direction = CSS_DIRECTION_INHERIT; - node->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN; - - node->style.overflow = CSS_OVERFLOW_VISIBLE; - - // Some of the fields default to undefined and not 0 - node->style.dimensions[CSS_WIDTH] = CSS_UNDEFINED; - node->style.dimensions[CSS_HEIGHT] = CSS_UNDEFINED; - - node->style.minDimensions[CSS_WIDTH] = CSS_UNDEFINED; - node->style.minDimensions[CSS_HEIGHT] = CSS_UNDEFINED; - - node->style.maxDimensions[CSS_WIDTH] = CSS_UNDEFINED; - node->style.maxDimensions[CSS_HEIGHT] = CSS_UNDEFINED; - - node->style.position[CSS_LEFT] = CSS_UNDEFINED; - node->style.position[CSS_TOP] = CSS_UNDEFINED; - node->style.position[CSS_RIGHT] = CSS_UNDEFINED; - node->style.position[CSS_BOTTOM] = CSS_UNDEFINED; - - node->style.margin[CSS_START] = CSS_UNDEFINED; - node->style.margin[CSS_END] = CSS_UNDEFINED; - node->style.padding[CSS_START] = CSS_UNDEFINED; - node->style.padding[CSS_END] = CSS_UNDEFINED; - node->style.border[CSS_START] = CSS_UNDEFINED; - node->style.border[CSS_END] = CSS_UNDEFINED; - - node->layout.dimensions[CSS_WIDTH] = CSS_UNDEFINED; - node->layout.dimensions[CSS_HEIGHT] = CSS_UNDEFINED; - - // Such that the comparison is always going to be false - node->layout.last_parent_direction = (css_direction_t)-1; - node->layout.should_update = true; - node->layout.next_cached_measurements_index = 0; - - node->layout.measured_dimensions[CSS_WIDTH] = CSS_UNDEFINED; - node->layout.measured_dimensions[CSS_HEIGHT] = CSS_UNDEFINED; - node->layout.cached_layout.width_measure_mode = (css_measure_mode_t)-1; - node->layout.cached_layout.height_measure_mode = (css_measure_mode_t)-1; -} - -css_node_t* new_css_node() { - css_node_t* node = (css_node_t*)calloc(1, sizeof(*node)); - init_css_node(node); - return node; -} - -void free_css_node(css_node_t* node) { - free(node); -} - static void indent(int n) { for (int i = 0; i < n; ++i) { printf(" "); @@ -336,8 +252,8 @@ static bool four_equal(float four[4]) { static void print_css_node_rec( - css_node_t* node, - css_print_options_t options, + CSSNode* node, + CSSPrintOptions options, int level ) { indent(level); @@ -347,124 +263,125 @@ static void print_css_node_rec( node->print(node->context); } - if (options & CSS_PRINT_LAYOUT) { + if (options & CSSPrintOptionsLayout) { printf("layout: {"); - printf("width: %g, ", node->layout.dimensions[CSS_WIDTH]); - printf("height: %g, ", node->layout.dimensions[CSS_HEIGHT]); - printf("top: %g, ", node->layout.position[CSS_TOP]); - printf("left: %g", node->layout.position[CSS_LEFT]); + printf("width: %g, ", node->layout.dimensions[CSSDimensionWidth]); + printf("height: %g, ", node->layout.dimensions[CSSDimensionHeight]); + printf("top: %g, ", node->layout.position[CSSPositionTop]); + printf("left: %g", node->layout.position[CSSPositionLeft]); printf("}, "); } - if (options & CSS_PRINT_STYLE) { - if (node->style.flex_direction == CSS_FLEX_DIRECTION_COLUMN) { + if (options & CSSPrintOptionsStyle) { + if (node->style.flexDirection == CSSFlexDirectionColumn) { printf("flexDirection: 'column', "); - } else if (node->style.flex_direction == CSS_FLEX_DIRECTION_COLUMN_REVERSE) { + } else if (node->style.flexDirection == CSSFlexDirectionColumnReverse) { printf("flexDirection: 'column-reverse', "); - } else if (node->style.flex_direction == CSS_FLEX_DIRECTION_ROW) { + } else if (node->style.flexDirection == CSSFlexDirectionRow) { printf("flexDirection: 'row', "); - } else if (node->style.flex_direction == CSS_FLEX_DIRECTION_ROW_REVERSE) { + } else if (node->style.flexDirection == CSSFlexDirectionRowReverse) { printf("flexDirection: 'row-reverse', "); } - if (node->style.justify_content == CSS_JUSTIFY_CENTER) { + if (node->style.justifyContent == CSSJustifyCenter) { printf("justifyContent: 'center', "); - } else if (node->style.justify_content == CSS_JUSTIFY_FLEX_END) { + } else if (node->style.justifyContent == CSSJustifyFlexEnd) { printf("justifyContent: 'flex-end', "); - } else if (node->style.justify_content == CSS_JUSTIFY_SPACE_AROUND) { + } else if (node->style.justifyContent == CSSJustifySpaceAround) { printf("justifyContent: 'space-around', "); - } else if (node->style.justify_content == CSS_JUSTIFY_SPACE_BETWEEN) { + } else if (node->style.justifyContent == CSSJustifySpaceBetween) { printf("justifyContent: 'space-between', "); } - if (node->style.align_items == CSS_ALIGN_CENTER) { + if (node->style.alignItems == CSSAlignCenter) { printf("alignItems: 'center', "); - } else if (node->style.align_items == CSS_ALIGN_FLEX_END) { + } else if (node->style.alignItems == CSSAlignFlexEnd) { printf("alignItems: 'flex-end', "); - } else if (node->style.align_items == CSS_ALIGN_STRETCH) { + } else if (node->style.alignItems == CSSAlignStretch) { printf("alignItems: 'stretch', "); } - if (node->style.align_content == CSS_ALIGN_CENTER) { + if (node->style.alignContent == CSSAlignCenter) { printf("alignContent: 'center', "); - } else if (node->style.align_content == CSS_ALIGN_FLEX_END) { + } else if (node->style.alignContent == CSSAlignFlexEnd) { printf("alignContent: 'flex-end', "); - } else if (node->style.align_content == CSS_ALIGN_STRETCH) { + } else if (node->style.alignContent == CSSAlignStretch) { printf("alignContent: 'stretch', "); } - if (node->style.align_self == CSS_ALIGN_FLEX_START) { + if (node->style.alignSelf == CSSAlignFlexStart) { printf("alignSelf: 'flex-start', "); - } else if (node->style.align_self == CSS_ALIGN_CENTER) { + } else if (node->style.alignSelf == CSSAlignCenter) { printf("alignSelf: 'center', "); - } else if (node->style.align_self == CSS_ALIGN_FLEX_END) { + } else if (node->style.alignSelf == CSSAlignFlexEnd) { printf("alignSelf: 'flex-end', "); - } else if (node->style.align_self == CSS_ALIGN_STRETCH) { + } else if (node->style.alignSelf == CSSAlignStretch) { printf("alignSelf: 'stretch', "); } print_number_nan("flex", node->style.flex); - if (node->style.overflow == CSS_OVERFLOW_HIDDEN) { + if (node->style.overflow == CSSOverflowHidden) { printf("overflow: 'hidden', "); - } else if (node->style.overflow == CSS_OVERFLOW_VISIBLE) { + } else if (node->style.overflow == CSSOverflowVisible) { printf("overflow: 'visible', "); } if (four_equal(node->style.margin)) { - print_number_0("margin", node->style.margin[CSS_LEFT]); + print_number_0("margin", node->style.margin[CSSPositionLeft]); } else { - print_number_0("marginLeft", node->style.margin[CSS_LEFT]); - print_number_0("marginRight", node->style.margin[CSS_RIGHT]); - print_number_0("marginTop", node->style.margin[CSS_TOP]); - print_number_0("marginBottom", node->style.margin[CSS_BOTTOM]); - print_number_0("marginStart", node->style.margin[CSS_START]); - print_number_0("marginEnd", node->style.margin[CSS_END]); + print_number_0("marginLeft", node->style.margin[CSSPositionLeft]); + print_number_0("marginRight", node->style.margin[CSSPositionRight]); + print_number_0("marginTop", node->style.margin[CSSPositionTop]); + print_number_0("marginBottom", node->style.margin[CSSPositionBottom]); + print_number_0("marginStart", node->style.margin[CSSPositionStart]); + print_number_0("marginEnd", node->style.margin[CSSPositionEnd]); } if (four_equal(node->style.padding)) { - print_number_0("padding", node->style.padding[CSS_LEFT]); + print_number_0("padding", node->style.padding[CSSPositionLeft]); } else { - print_number_0("paddingLeft", node->style.padding[CSS_LEFT]); - print_number_0("paddingRight", node->style.padding[CSS_RIGHT]); - print_number_0("paddingTop", node->style.padding[CSS_TOP]); - print_number_0("paddingBottom", node->style.padding[CSS_BOTTOM]); - print_number_0("paddingStart", node->style.padding[CSS_START]); - print_number_0("paddingEnd", node->style.padding[CSS_END]); + print_number_0("paddingLeft", node->style.padding[CSSPositionLeft]); + print_number_0("paddingRight", node->style.padding[CSSPositionRight]); + print_number_0("paddingTop", node->style.padding[CSSPositionTop]); + print_number_0("paddingBottom", node->style.padding[CSSPositionBottom]); + print_number_0("paddingStart", node->style.padding[CSSPositionStart]); + print_number_0("paddingEnd", node->style.padding[CSSPositionEnd]); } if (four_equal(node->style.border)) { - print_number_0("borderWidth", node->style.border[CSS_LEFT]); + print_number_0("borderWidth", node->style.border[CSSPositionLeft]); } else { - print_number_0("borderLeftWidth", node->style.border[CSS_LEFT]); - print_number_0("borderRightWidth", node->style.border[CSS_RIGHT]); - print_number_0("borderTopWidth", node->style.border[CSS_TOP]); - print_number_0("borderBottomWidth", node->style.border[CSS_BOTTOM]); - print_number_0("borderStartWidth", node->style.border[CSS_START]); - print_number_0("borderEndWidth", node->style.border[CSS_END]); + print_number_0("borderLeftWidth", node->style.border[CSSPositionLeft]); + print_number_0("borderRightWidth", node->style.border[CSSPositionRight]); + print_number_0("borderTopWidth", node->style.border[CSSPositionTop]); + print_number_0("borderBottomWidth", node->style.border[CSSPositionBottom]); + print_number_0("borderStartWidth", node->style.border[CSSPositionStart]); + print_number_0("borderEndWidth", node->style.border[CSSPositionEnd]); } - print_number_nan("width", node->style.dimensions[CSS_WIDTH]); - print_number_nan("height", node->style.dimensions[CSS_HEIGHT]); - print_number_nan("maxWidth", node->style.maxDimensions[CSS_WIDTH]); - print_number_nan("maxHeight", node->style.maxDimensions[CSS_HEIGHT]); - print_number_nan("minWidth", node->style.minDimensions[CSS_WIDTH]); - print_number_nan("minHeight", node->style.minDimensions[CSS_HEIGHT]); + print_number_nan("width", node->style.dimensions[CSSDimensionWidth]); + print_number_nan("height", node->style.dimensions[CSSDimensionHeight]); + print_number_nan("maxWidth", node->style.maxDimensions[CSSDimensionWidth]); + print_number_nan("maxHeight", node->style.maxDimensions[CSSDimensionHeight]); + print_number_nan("minWidth", node->style.minDimensions[CSSDimensionWidth]); + print_number_nan("minHeight", node->style.minDimensions[CSSDimensionHeight]); - if (node->style.position_type == CSS_POSITION_ABSOLUTE) { + if (node->style.positionType == CSSPositionTypeAbsolute) { printf("position: 'absolute', "); } - print_number_nan("left", node->style.position[CSS_LEFT]); - print_number_nan("right", node->style.position[CSS_RIGHT]); - print_number_nan("top", node->style.position[CSS_TOP]); - print_number_nan("bottom", node->style.position[CSS_BOTTOM]); + print_number_nan("left", node->style.position[CSSPositionLeft]); + print_number_nan("right", node->style.position[CSSPositionRight]); + print_number_nan("top", node->style.position[CSSPositionTop]); + print_number_nan("bottom", node->style.position[CSSPositionBottom]); } - if (options & CSS_PRINT_CHILDREN && node->children_count > 0) { + unsigned int childCount = CSSNodeListCount(node->children); + if (options & CSSPrintOptionsChildren && childCount > 0) { printf("children: [\n"); - for (int i = 0; i < node->children_count; ++i) { - print_css_node_rec(node->get_child(node->context, i), options, level + 1); + for (unsigned int i = 0; i < childCount; ++i) { + print_css_node_rec(CSSNodeGetChild(node, i), options, level + 1); } indent(level); printf("]},\n"); @@ -473,46 +390,46 @@ static void print_css_node_rec( } } -void print_css_node(css_node_t* node, css_print_options_t options) { +void CSSNodePrint(CSSNode* node, CSSPrintOptions options) { print_css_node_rec(node, options, 0); } -static css_position_t leading[4] = { - /* CSS_FLEX_DIRECTION_COLUMN = */ CSS_TOP, - /* CSS_FLEX_DIRECTION_COLUMN_REVERSE = */ CSS_BOTTOM, - /* CSS_FLEX_DIRECTION_ROW = */ CSS_LEFT, - /* CSS_FLEX_DIRECTION_ROW_REVERSE = */ CSS_RIGHT +static CSSPosition leading[4] = { + /* CSSFlexDirectionColumn = */ CSSPositionTop, + /* CSSFlexDirectionColumnReverse = */ CSSPositionBottom, + /* CSSFlexDirectionRow = */ CSSPositionLeft, + /* CSSFlexDirectionRowReverse = */ CSSPositionRight }; -static css_position_t trailing[4] = { - /* CSS_FLEX_DIRECTION_COLUMN = */ CSS_BOTTOM, - /* CSS_FLEX_DIRECTION_COLUMN_REVERSE = */ CSS_TOP, - /* CSS_FLEX_DIRECTION_ROW = */ CSS_RIGHT, - /* CSS_FLEX_DIRECTION_ROW_REVERSE = */ CSS_LEFT +static CSSPosition trailing[4] = { + /* CSSFlexDirectionColumn = */ CSSPositionBottom, + /* CSSFlexDirectionColumnReverse = */ CSSPositionTop, + /* CSSFlexDirectionRow = */ CSSPositionRight, + /* CSSFlexDirectionRowReverse = */ CSSPositionLeft }; -static css_position_t pos[4] = { - /* CSS_FLEX_DIRECTION_COLUMN = */ CSS_TOP, - /* CSS_FLEX_DIRECTION_COLUMN_REVERSE = */ CSS_BOTTOM, - /* CSS_FLEX_DIRECTION_ROW = */ CSS_LEFT, - /* CSS_FLEX_DIRECTION_ROW_REVERSE = */ CSS_RIGHT +static CSSPosition pos[4] = { + /* CSSFlexDirectionColumn = */ CSSPositionTop, + /* CSSFlexDirectionColumnReverse = */ CSSPositionBottom, + /* CSSFlexDirectionRow = */ CSSPositionLeft, + /* CSSFlexDirectionRowReverse = */ CSSPositionRight }; -static css_dimension_t dim[4] = { - /* CSS_FLEX_DIRECTION_COLUMN = */ CSS_HEIGHT, - /* CSS_FLEX_DIRECTION_COLUMN_REVERSE = */ CSS_HEIGHT, - /* CSS_FLEX_DIRECTION_ROW = */ CSS_WIDTH, - /* CSS_FLEX_DIRECTION_ROW_REVERSE = */ CSS_WIDTH +static CSSDimension dim[4] = { + /* CSSFlexDirectionColumn = */ CSSDimensionHeight, + /* CSSFlexDirectionColumnReverse = */ CSSDimensionHeight, + /* CSSFlexDirectionRow = */ CSSDimensionWidth, + /* CSSFlexDirectionRowReverse = */ CSSDimensionWidth }; -static bool isRowDirection(css_flex_direction_t flex_direction) { - return flex_direction == CSS_FLEX_DIRECTION_ROW || - flex_direction == CSS_FLEX_DIRECTION_ROW_REVERSE; +static bool isRowDirection(CSSFlexDirection flexDirection) { + return flexDirection == CSSFlexDirectionRow || + flexDirection == CSSFlexDirectionRowReverse; } -static bool isColumnDirection(css_flex_direction_t flex_direction) { - return flex_direction == CSS_FLEX_DIRECTION_COLUMN || - flex_direction == CSS_FLEX_DIRECTION_COLUMN_REVERSE; +static bool isColumnDirection(CSSFlexDirection flexDirection) { + return flexDirection == CSSFlexDirectionColumn || + flexDirection == CSSFlexDirectionColumnReverse; } -static bool isFlexBasisAuto(css_node_t* node) { +static bool isFlexBasisAuto(CSSNode* node) { #if POSITIVE_FLEX_IS_AUTO // All flex values are auto. (void) node; @@ -523,7 +440,7 @@ static bool isFlexBasisAuto(css_node_t* node) { #endif } -static float getFlexGrowFactor(css_node_t* node) { +static float getFlexGrowFactor(CSSNode* node) { // Flex grow is implied by positive values for flex. if (node->style.flex > 0) { return node->style.flex; @@ -531,7 +448,7 @@ static float getFlexGrowFactor(css_node_t* node) { return 0; } -static float getFlexShrinkFactor(css_node_t* node) { +static float getFlexShrinkFactor(CSSNode* node) { #if POSITIVE_FLEX_IS_AUTO // A flex shrink factor of 1 is implied by non-zero values for flex. if (node->style.flex != 0) { @@ -546,27 +463,27 @@ static float getFlexShrinkFactor(css_node_t* node) { return 0; } -static float getLeadingMargin(css_node_t* node, css_flex_direction_t axis) { - if (isRowDirection(axis) && !isUndefined(node->style.margin[CSS_START])) { - return node->style.margin[CSS_START]; +static float getLeadingMargin(CSSNode* node, CSSFlexDirection axis) { + if (isRowDirection(axis) && !isUndefined(node->style.margin[CSSPositionStart])) { + return node->style.margin[CSSPositionStart]; } return node->style.margin[leading[axis]]; } -static float getTrailingMargin(css_node_t* node, css_flex_direction_t axis) { - if (isRowDirection(axis) && !isUndefined(node->style.margin[CSS_END])) { - return node->style.margin[CSS_END]; +static float getTrailingMargin(CSSNode* node, CSSFlexDirection axis) { + if (isRowDirection(axis) && !isUndefined(node->style.margin[CSSPositionEnd])) { + return node->style.margin[CSSPositionEnd]; } return node->style.margin[trailing[axis]]; } -static float getLeadingPadding(css_node_t* node, css_flex_direction_t axis) { +static float getLeadingPadding(CSSNode* node, CSSFlexDirection axis) { if (isRowDirection(axis) && - !isUndefined(node->style.padding[CSS_START]) && - node->style.padding[CSS_START] >= 0) { - return node->style.padding[CSS_START]; + !isUndefined(node->style.padding[CSSPositionStart]) && + node->style.padding[CSSPositionStart] >= 0) { + return node->style.padding[CSSPositionStart]; } if (node->style.padding[leading[axis]] >= 0) { @@ -576,11 +493,11 @@ static float getLeadingPadding(css_node_t* node, css_flex_direction_t axis) { return 0; } -static float getTrailingPadding(css_node_t* node, css_flex_direction_t axis) { +static float getTrailingPadding(CSSNode* node, CSSFlexDirection axis) { if (isRowDirection(axis) && - !isUndefined(node->style.padding[CSS_END]) && - node->style.padding[CSS_END] >= 0) { - return node->style.padding[CSS_END]; + !isUndefined(node->style.padding[CSSPositionEnd]) && + node->style.padding[CSSPositionEnd] >= 0) { + return node->style.padding[CSSPositionEnd]; } if (node->style.padding[trailing[axis]] >= 0) { @@ -590,11 +507,11 @@ static float getTrailingPadding(css_node_t* node, css_flex_direction_t axis) { return 0; } -static float getLeadingBorder(css_node_t* node, css_flex_direction_t axis) { +static float getLeadingBorder(CSSNode* node, CSSFlexDirection axis) { if (isRowDirection(axis) && - !isUndefined(node->style.border[CSS_START]) && - node->style.border[CSS_START] >= 0) { - return node->style.border[CSS_START]; + !isUndefined(node->style.border[CSSPositionStart]) && + node->style.border[CSSPositionStart] >= 0) { + return node->style.border[CSSPositionStart]; } if (node->style.border[leading[axis]] >= 0) { @@ -604,11 +521,11 @@ static float getLeadingBorder(css_node_t* node, css_flex_direction_t axis) { return 0; } -static float getTrailingBorder(css_node_t* node, css_flex_direction_t axis) { +static float getTrailingBorder(CSSNode* node, CSSFlexDirection axis) { if (isRowDirection(axis) && - !isUndefined(node->style.border[CSS_END]) && - node->style.border[CSS_END] >= 0) { - return node->style.border[CSS_END]; + !isUndefined(node->style.border[CSSPositionEnd]) && + node->style.border[CSSPositionEnd] >= 0) { + return node->style.border[CSSPositionEnd]; } if (node->style.border[trailing[axis]] >= 0) { @@ -618,103 +535,103 @@ static float getTrailingBorder(css_node_t* node, css_flex_direction_t axis) { return 0; } -static float getLeadingPaddingAndBorder(css_node_t* node, css_flex_direction_t axis) { +static float getLeadingPaddingAndBorder(CSSNode* node, CSSFlexDirection axis) { return getLeadingPadding(node, axis) + getLeadingBorder(node, axis); } -static float getTrailingPaddingAndBorder(css_node_t* node, css_flex_direction_t axis) { +static float getTrailingPaddingAndBorder(CSSNode* node, CSSFlexDirection axis) { return getTrailingPadding(node, axis) + getTrailingBorder(node, axis); } -static float getMarginAxis(css_node_t* node, css_flex_direction_t axis) { +static float getMarginAxis(CSSNode* node, CSSFlexDirection axis) { return getLeadingMargin(node, axis) + getTrailingMargin(node, axis); } -static float getPaddingAndBorderAxis(css_node_t* node, css_flex_direction_t axis) { +static float getPaddingAndBorderAxis(CSSNode* node, CSSFlexDirection axis) { return getLeadingPaddingAndBorder(node, axis) + getTrailingPaddingAndBorder(node, axis); } -static css_align_t getAlignItem(css_node_t* node, css_node_t* child) { - if (child->style.align_self != CSS_ALIGN_AUTO) { - return child->style.align_self; +static CSSAlign getAlignItem(CSSNode* node, CSSNode* child) { + if (child->style.alignSelf != CSSAlignAuto) { + return child->style.alignSelf; } - return node->style.align_items; + return node->style.alignItems; } -static css_direction_t resolveDirection(css_node_t* node, css_direction_t parentDirection) { - css_direction_t direction = node->style.direction; +static CSSDirection resolveDirection(CSSNode* node, CSSDirection parentDirection) { + CSSDirection direction = node->style.direction; - if (direction == CSS_DIRECTION_INHERIT) { - direction = parentDirection > CSS_DIRECTION_INHERIT ? parentDirection : CSS_DIRECTION_LTR; + if (direction == CSSDirectionInherit) { + direction = parentDirection > CSSDirectionInherit ? parentDirection : CSSDirectionLTR; } return direction; } -static css_flex_direction_t getFlexDirection(css_node_t* node) { - return node->style.flex_direction; +static CSSFlexDirection getFlexDirection(CSSNode* node) { + return node->style.flexDirection; } -static css_flex_direction_t resolveAxis(css_flex_direction_t flex_direction, css_direction_t direction) { - if (direction == CSS_DIRECTION_RTL) { - if (flex_direction == CSS_FLEX_DIRECTION_ROW) { - return CSS_FLEX_DIRECTION_ROW_REVERSE; - } else if (flex_direction == CSS_FLEX_DIRECTION_ROW_REVERSE) { - return CSS_FLEX_DIRECTION_ROW; +static CSSFlexDirection resolveAxis(CSSFlexDirection flexDirection, CSSDirection direction) { + if (direction == CSSDirectionRTL) { + if (flexDirection == CSSFlexDirectionRow) { + return CSSFlexDirectionRowReverse; + } else if (flexDirection == CSSFlexDirectionRowReverse) { + return CSSFlexDirectionRow; } } - return flex_direction; + return flexDirection; } -static css_flex_direction_t getCrossFlexDirection(css_flex_direction_t flex_direction, css_direction_t direction) { - if (isColumnDirection(flex_direction)) { - return resolveAxis(CSS_FLEX_DIRECTION_ROW, direction); +static CSSFlexDirection getCrossFlexDirection(CSSFlexDirection flexDirection, CSSDirection direction) { + if (isColumnDirection(flexDirection)) { + return resolveAxis(CSSFlexDirectionRow, direction); } else { - return CSS_FLEX_DIRECTION_COLUMN; + return CSSFlexDirectionColumn; } } -static float getFlex(css_node_t* node) { +static float getFlex(CSSNode* node) { return node->style.flex; } -static bool isFlex(css_node_t* node) { +static bool isFlex(CSSNode* node) { return ( - node->style.position_type == CSS_POSITION_RELATIVE && + node->style.positionType == CSSPositionTypeRelative && getFlex(node) != 0 ); } -static bool isFlexWrap(css_node_t* node) { - return node->style.flex_wrap == CSS_WRAP; +static bool isFlexWrap(CSSNode* node) { + return node->style.flexWrap == CSSWrapTypeWrap; } -static float getDimWithMargin(css_node_t* node, css_flex_direction_t axis) { - return node->layout.measured_dimensions[dim[axis]] + +static float getDimWithMargin(CSSNode* node, CSSFlexDirection axis) { + return node->layout.measuredDimensions[dim[axis]] + getLeadingMargin(node, axis) + getTrailingMargin(node, axis); } -static bool isStyleDimDefined(css_node_t* node, css_flex_direction_t axis) { +static bool isStyleDimDefined(CSSNode* node, CSSFlexDirection axis) { float value = node->style.dimensions[dim[axis]]; return !isUndefined(value) && value >= 0.0; } -static bool isLayoutDimDefined(css_node_t* node, css_flex_direction_t axis) { - float value = node->layout.measured_dimensions[dim[axis]]; +static bool isLayoutDimDefined(CSSNode* node, CSSFlexDirection axis) { + float value = node->layout.measuredDimensions[dim[axis]]; return !isUndefined(value) && value >= 0.0; } -static bool isPosDefined(css_node_t* node, css_position_t position) { +static bool isPosDefined(CSSNode* node, CSSPosition position) { return !isUndefined(node->style.position[position]); } -static bool isMeasureDefined(css_node_t* node) { +static bool isMeasureDefined(CSSNode* node) { return node->measure; } -static float getPosition(css_node_t* node, css_position_t position) { +static float getPosition(CSSNode* node, CSSPosition position) { float result = node->style.position[position]; if (!isUndefined(result)) { return result; @@ -722,16 +639,16 @@ static float getPosition(css_node_t* node, css_position_t position) { return 0; } -static float boundAxisWithinMinAndMax(css_node_t* node, css_flex_direction_t axis, float value) { - float min = CSS_UNDEFINED; - float max = CSS_UNDEFINED; +static float boundAxisWithinMinAndMax(CSSNode* node, CSSFlexDirection axis, float value) { + float min = CSSUndefined; + float max = CSSUndefined; if (isColumnDirection(axis)) { - min = node->style.minDimensions[CSS_HEIGHT]; - max = node->style.maxDimensions[CSS_HEIGHT]; + min = node->style.minDimensions[CSSDimensionHeight]; + max = node->style.maxDimensions[CSSDimensionHeight]; } else if (isRowDirection(axis)) { - min = node->style.minDimensions[CSS_WIDTH]; - max = node->style.maxDimensions[CSS_WIDTH]; + min = node->style.minDimensions[CSSDimensionWidth]; + max = node->style.maxDimensions[CSSDimensionWidth]; } float boundValue = value; @@ -748,20 +665,20 @@ static float boundAxisWithinMinAndMax(css_node_t* node, css_flex_direction_t axi // Like boundAxisWithinMinAndMax but also ensures that the value doesn't go below the // padding and border amount. -static float boundAxis(css_node_t* node, css_flex_direction_t axis, float value) { +static float boundAxis(CSSNode* node, CSSFlexDirection axis, float value) { return fmaxf(boundAxisWithinMinAndMax(node, axis, value), getPaddingAndBorderAxis(node, axis)); } -static void setTrailingPosition(css_node_t* node, css_node_t* child, css_flex_direction_t axis) { - float size = child->style.position_type == CSS_POSITION_ABSOLUTE ? +static void setTrailingPosition(CSSNode* node, CSSNode* child, CSSFlexDirection axis) { + float size = child->style.positionType == CSSPositionTypeAbsolute ? 0 : - child->layout.measured_dimensions[dim[axis]]; - child->layout.position[trailing[axis]] = node->layout.measured_dimensions[dim[axis]] - size - child->layout.position[pos[axis]]; + child->layout.measuredDimensions[dim[axis]]; + child->layout.position[trailing[axis]] = node->layout.measuredDimensions[dim[axis]] - size - child->layout.position[pos[axis]]; } // If both left and right are defined, then use left. Otherwise return // +left or -right depending on which is defined. -static float getRelativePosition(css_node_t* node, css_flex_direction_t axis) { +static float getRelativePosition(CSSNode* node, CSSFlexDirection axis) { float lead = node->style.position[leading[axis]]; if (!isUndefined(lead)) { return lead; @@ -769,9 +686,9 @@ static float getRelativePosition(css_node_t* node, css_flex_direction_t axis) { return -getPosition(node, trailing[axis]); } -static void setPosition(css_node_t* node, css_direction_t direction) { - css_flex_direction_t mainAxis = resolveAxis(getFlexDirection(node), direction); - css_flex_direction_t crossAxis = getCrossFlexDirection(mainAxis, direction); +static void setPosition(CSSNode* node, CSSDirection direction) { + CSSFlexDirection mainAxis = resolveAxis(getFlexDirection(node), direction); + CSSFlexDirection crossAxis = getCrossFlexDirection(mainAxis, direction); node->layout.position[leading[mainAxis]] = getLeadingMargin(node, mainAxis) + getRelativePosition(node, mainAxis); @@ -829,7 +746,7 @@ static void setPosition(css_node_t* node, css_direction_t direction) { // Input parameters: // - node: current node to be sized and layed out // - availableWidth & availableHeight: available size to be used for sizing the node -// or CSS_UNDEFINED if the size is not available; interpretation depends on layout +// or CSSUndefined if the size is not available; interpretation depends on layout // flags // - parentDirection: the inline (text) direction within the parent (left-to-right or // right-to-left) @@ -842,36 +759,35 @@ static void setPosition(css_node_t* node, css_direction_t direction) { // Details: // This routine is called recursively to lay out subtrees of flexbox elements. It uses the // information in node.style, which is treated as a read-only input. It is responsible for -// setting the layout.direction and layout.measured_dimensions fields for the input node as well -// as the layout.position and layout.line_index fields for its child nodes. The -// layout.measured_dimensions field includes any border or padding for the node but does +// setting the layout.direction and layout.measuredDimensions fields for the input node as well +// as the layout.position and layout.lineIndex fields for its child nodes. The +// layout.measuredDimensions field includes any border or padding for the node but does // not include margins. // // The spec describes four different layout modes: "fill available", "max content", "min content", // and "fit content". Of these, we don't use "min content" because we don't support default // minimum main sizes (see above for details). Each of our measure modes maps to a layout mode // from the spec (https://www.w3.org/TR/css3-sizing/#terms): -// - CSS_MEASURE_MODE_UNDEFINED: max content -// - CSS_MEASURE_MODE_EXACTLY: fill available -// - CSS_MEASURE_MODE_AT_MOST: fit content +// - CSSMeasureModeUndefined: max content +// - CSSMeasureModeExactly: fill available +// - CSSMeasureModeAtMost: fit content // // When calling layoutNodeImpl and layoutNodeInternal, if the caller passes an available size of -// undefined then it must also pass a measure mode of CSS_MEASURE_MODE_UNDEFINED in that dimension. +// undefined then it must also pass a measure mode of CSSMeasureModeUndefined in that dimension. // -static void layoutNodeImpl(css_node_t* node, float availableWidth, float availableHeight, - css_direction_t parentDirection, css_measure_mode_t widthMeasureMode, css_measure_mode_t heightMeasureMode, bool performLayout) { - /** START_GENERATED **/ +static void layoutNodeImpl(CSSNode* node, float availableWidth, float availableHeight, + CSSDirection parentDirection, CSSMeasureMode widthMeasureMode, CSSMeasureMode heightMeasureMode, bool performLayout) { - assert(isUndefined(availableWidth) ? widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED : true); // availableWidth is indefinite so widthMeasureMode must be CSS_MEASURE_MODE_UNDEFINED - assert(isUndefined(availableHeight) ? heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED : true); // availableHeight is indefinite so heightMeasureMode must be CSS_MEASURE_MODE_UNDEFINED + assert(isUndefined(availableWidth) ? widthMeasureMode == CSSMeasureModeUndefined : true); // availableWidth is indefinite so widthMeasureMode must be CSSMeasureModeUndefined + assert(isUndefined(availableHeight) ? heightMeasureMode == CSSMeasureModeUndefined : true); // availableHeight is indefinite so heightMeasureMode must be CSSMeasureModeUndefined - float paddingAndBorderAxisRow = getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW); - float paddingAndBorderAxisColumn = getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN); - float marginAxisRow = getMarginAxis(node, CSS_FLEX_DIRECTION_ROW); - float marginAxisColumn = getMarginAxis(node, CSS_FLEX_DIRECTION_COLUMN); + float paddingAndBorderAxisRow = getPaddingAndBorderAxis(node, CSSFlexDirectionRow); + float paddingAndBorderAxisColumn = getPaddingAndBorderAxis(node, CSSFlexDirectionColumn); + float marginAxisRow = getMarginAxis(node, CSSFlexDirectionRow); + float marginAxisColumn = getMarginAxis(node, CSSFlexDirectionColumn); // Set the resolved resolution in the node's layout. - css_direction_t direction = resolveDirection(node, parentDirection); + CSSDirection direction = resolveDirection(node, parentDirection); node->layout.direction = direction; // For content (text) nodes, determine the dimensions based on the text contents. @@ -879,35 +795,35 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab float innerWidth = availableWidth - marginAxisRow - paddingAndBorderAxisRow; float innerHeight = availableHeight - marginAxisColumn - paddingAndBorderAxisColumn; - if (widthMeasureMode == CSS_MEASURE_MODE_EXACTLY && heightMeasureMode == CSS_MEASURE_MODE_EXACTLY) { + if (widthMeasureMode == CSSMeasureModeExactly && heightMeasureMode == CSSMeasureModeExactly) { // Don't bother sizing the text if both dimensions are already defined. - node->layout.measured_dimensions[CSS_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, availableWidth - marginAxisRow); - node->layout.measured_dimensions[CSS_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, availableHeight - marginAxisColumn); + node->layout.measuredDimensions[CSSDimensionWidth] = boundAxis(node, CSSFlexDirectionRow, availableWidth - marginAxisRow); + node->layout.measuredDimensions[CSSDimensionHeight] = boundAxis(node, CSSFlexDirectionColumn, availableHeight - marginAxisColumn); } else if (innerWidth <= 0 || innerHeight <= 0) { // Don't bother sizing the text if there's no horizontal or vertical space. - node->layout.measured_dimensions[CSS_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, 0); - node->layout.measured_dimensions[CSS_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, 0); + node->layout.measuredDimensions[CSSDimensionWidth] = boundAxis(node, CSSFlexDirectionRow, 0); + node->layout.measuredDimensions[CSSDimensionHeight] = boundAxis(node, CSSFlexDirectionColumn, 0); } else { // Measure the text under the current constraints. - css_dim_t measureDim = node->measure( + CSSSize measuredSize = node->measure( node->context, - + innerWidth, widthMeasureMode, innerHeight, heightMeasureMode ); - node->layout.measured_dimensions[CSS_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, - (widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED || widthMeasureMode == CSS_MEASURE_MODE_AT_MOST) ? - measureDim.dimensions[CSS_WIDTH] + paddingAndBorderAxisRow : + node->layout.measuredDimensions[CSSDimensionWidth] = boundAxis(node, CSSFlexDirectionRow, + (widthMeasureMode == CSSMeasureModeUndefined || widthMeasureMode == CSSMeasureModeAtMost) ? + measuredSize.width + paddingAndBorderAxisRow : availableWidth - marginAxisRow); - node->layout.measured_dimensions[CSS_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, - (heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED || heightMeasureMode == CSS_MEASURE_MODE_AT_MOST) ? - measureDim.dimensions[CSS_HEIGHT] + paddingAndBorderAxisColumn : + node->layout.measuredDimensions[CSSDimensionHeight] = boundAxis(node, CSSFlexDirectionColumn, + (heightMeasureMode == CSSMeasureModeUndefined || heightMeasureMode == CSSMeasureModeAtMost) ? + measuredSize.height + paddingAndBorderAxisColumn : availableHeight - marginAxisColumn); } @@ -916,14 +832,14 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab // For nodes with no children, use the available values if they were provided, or // the minimum size as indicated by the padding and border sizes. - int childCount = node->children_count; + unsigned int childCount = CSSNodeListCount(node->children); if (childCount == 0) { - node->layout.measured_dimensions[CSS_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, - (widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED || widthMeasureMode == CSS_MEASURE_MODE_AT_MOST) ? + node->layout.measuredDimensions[CSSDimensionWidth] = boundAxis(node, CSSFlexDirectionRow, + (widthMeasureMode == CSSMeasureModeUndefined || widthMeasureMode == CSSMeasureModeAtMost) ? paddingAndBorderAxisRow : availableWidth - marginAxisRow); - node->layout.measured_dimensions[CSS_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, - (heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED || heightMeasureMode == CSS_MEASURE_MODE_AT_MOST) ? + node->layout.measuredDimensions[CSSDimensionHeight] = boundAxis(node, CSSFlexDirectionColumn, + (heightMeasureMode == CSSMeasureModeUndefined || heightMeasureMode == CSSMeasureModeAtMost) ? paddingAndBorderAxisColumn : availableHeight - marginAxisColumn); return; @@ -934,42 +850,42 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab if (!performLayout) { // If we're being asked to size the content with an at most constraint but there is no available width, // the measurement will always be zero. - if (widthMeasureMode == CSS_MEASURE_MODE_AT_MOST && availableWidth <= 0 && - heightMeasureMode == CSS_MEASURE_MODE_AT_MOST && availableHeight <= 0) { - node->layout.measured_dimensions[CSS_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, 0); - node->layout.measured_dimensions[CSS_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, 0); + if (widthMeasureMode == CSSMeasureModeAtMost && availableWidth <= 0 && + heightMeasureMode == CSSMeasureModeAtMost && availableHeight <= 0) { + node->layout.measuredDimensions[CSSDimensionWidth] = boundAxis(node, CSSFlexDirectionRow, 0); + node->layout.measuredDimensions[CSSDimensionHeight] = boundAxis(node, CSSFlexDirectionColumn, 0); return; } - if (widthMeasureMode == CSS_MEASURE_MODE_AT_MOST && availableWidth <= 0) { - node->layout.measured_dimensions[CSS_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, 0); - node->layout.measured_dimensions[CSS_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, isUndefined(availableHeight) ? 0 : (availableHeight - marginAxisColumn)); + if (widthMeasureMode == CSSMeasureModeAtMost && availableWidth <= 0) { + node->layout.measuredDimensions[CSSDimensionWidth] = boundAxis(node, CSSFlexDirectionRow, 0); + node->layout.measuredDimensions[CSSDimensionHeight] = boundAxis(node, CSSFlexDirectionColumn, isUndefined(availableHeight) ? 0 : (availableHeight - marginAxisColumn)); return; } - if (heightMeasureMode == CSS_MEASURE_MODE_AT_MOST && availableHeight <= 0) { - node->layout.measured_dimensions[CSS_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, isUndefined(availableWidth) ? 0 : (availableWidth - marginAxisRow)); - node->layout.measured_dimensions[CSS_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, 0); + if (heightMeasureMode == CSSMeasureModeAtMost && availableHeight <= 0) { + node->layout.measuredDimensions[CSSDimensionWidth] = boundAxis(node, CSSFlexDirectionRow, isUndefined(availableWidth) ? 0 : (availableWidth - marginAxisRow)); + node->layout.measuredDimensions[CSSDimensionHeight] = boundAxis(node, CSSFlexDirectionColumn, 0); return; } // If we're being asked to use an exact width/height, there's no need to measure the children. - if (widthMeasureMode == CSS_MEASURE_MODE_EXACTLY && heightMeasureMode == CSS_MEASURE_MODE_EXACTLY) { - node->layout.measured_dimensions[CSS_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, availableWidth - marginAxisRow); - node->layout.measured_dimensions[CSS_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, availableHeight - marginAxisColumn); + if (widthMeasureMode == CSSMeasureModeExactly && heightMeasureMode == CSSMeasureModeExactly) { + node->layout.measuredDimensions[CSSDimensionWidth] = boundAxis(node, CSSFlexDirectionRow, availableWidth - marginAxisRow); + node->layout.measuredDimensions[CSSDimensionHeight] = boundAxis(node, CSSFlexDirectionColumn, availableHeight - marginAxisColumn); return; } } // STEP 1: CALCULATE VALUES FOR REMAINDER OF ALGORITHM - css_flex_direction_t mainAxis = resolveAxis(getFlexDirection(node), direction); - css_flex_direction_t crossAxis = getCrossFlexDirection(mainAxis, direction); + CSSFlexDirection mainAxis = resolveAxis(getFlexDirection(node), direction); + CSSFlexDirection crossAxis = getCrossFlexDirection(mainAxis, direction); bool isMainAxisRow = isRowDirection(mainAxis); - css_justify_t justifyContent = node->style.justify_content; + CSSJustify justifyContent = node->style.justifyContent; bool isNodeFlexWrap = isFlexWrap(node); - css_node_t* firstAbsoluteChild = NULL; - css_node_t* currentAbsoluteChild = NULL; + CSSNode* firstAbsoluteChild = NULL; + CSSNode* currentAbsoluteChild = NULL; float leadingPaddingAndBorderMain = getLeadingPaddingAndBorder(node, mainAxis); float trailingPaddingAndBorderMain = getTrailingPaddingAndBorder(node, mainAxis); @@ -977,8 +893,8 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab float paddingAndBorderAxisMain = getPaddingAndBorderAxis(node, mainAxis); float paddingAndBorderAxisCross = getPaddingAndBorderAxis(node, crossAxis); - css_measure_mode_t measureModeMainDim = isMainAxisRow ? widthMeasureMode : heightMeasureMode; - css_measure_mode_t measureModeCrossDim = isMainAxisRow ? heightMeasureMode : widthMeasureMode; + CSSMeasureMode measureModeMainDim = isMainAxisRow ? widthMeasureMode : heightMeasureMode; + CSSMeasureMode measureModeCrossDim = isMainAxisRow ? heightMeasureMode : widthMeasureMode; // STEP 2: DETERMINE AVAILABLE SIZE IN MAIN AND CROSS DIRECTIONS float availableInnerWidth = availableWidth - marginAxisRow - paddingAndBorderAxisRow; @@ -987,24 +903,24 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab float availableInnerCrossDim = isMainAxisRow ? availableInnerHeight : availableInnerWidth; // STEP 3: DETERMINE FLEX BASIS FOR EACH ITEM - css_node_t* child; - int i; + CSSNode* child; + unsigned int i; float childWidth; float childHeight; - css_measure_mode_t childWidthMeasureMode; - css_measure_mode_t childHeightMeasureMode; + CSSMeasureMode childWidthMeasureMode; + CSSMeasureMode childHeightMeasureMode; for (i = 0; i < childCount; i++) { - child = node->get_child(node->context, i); + child = CSSNodeListGet(node->children, i); if (performLayout) { // Set the initial position (relative to the parent). - css_direction_t childDirection = resolveDirection(child, direction); + CSSDirection childDirection = resolveDirection(child, direction); setPosition(child, childDirection); } // Absolute-positioned children don't participate in flex layout. Add them // to a list that we can process later. - if (child->style.position_type == CSS_POSITION_ABSOLUTE) { + if (child->style.positionType == CSSPositionTypeAbsolute) { // Store a private linked list of absolutely positioned children // so that we can efficiently traverse them later. @@ -1012,39 +928,39 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab firstAbsoluteChild = child; } if (currentAbsoluteChild != NULL) { - currentAbsoluteChild->next_child = child; + currentAbsoluteChild->nextChild = child; } currentAbsoluteChild = child; - child->next_child = NULL; + child->nextChild = NULL; } else { - if (isMainAxisRow && isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW)) { + if (isMainAxisRow && isStyleDimDefined(child, CSSFlexDirectionRow)) { // The width is definite, so use that as the flex basis. - child->layout.flex_basis = fmaxf(child->style.dimensions[CSS_WIDTH], getPaddingAndBorderAxis(child, CSS_FLEX_DIRECTION_ROW)); - } else if (!isMainAxisRow && isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN)) { + child->layout.flexBasis = fmaxf(child->style.dimensions[CSSDimensionWidth], getPaddingAndBorderAxis(child, CSSFlexDirectionRow)); + } else if (!isMainAxisRow && isStyleDimDefined(child, CSSFlexDirectionColumn)) { // The height is definite, so use that as the flex basis. - child->layout.flex_basis = fmaxf(child->style.dimensions[CSS_HEIGHT], getPaddingAndBorderAxis(child, CSS_FLEX_DIRECTION_COLUMN)); + child->layout.flexBasis = fmaxf(child->style.dimensions[CSSDimensionHeight], getPaddingAndBorderAxis(child, CSSFlexDirectionColumn)); } else if (!isFlexBasisAuto(child) && !isUndefined(availableInnerMainDim)) { // If the basis isn't 'auto', it is assumed to be zero. - child->layout.flex_basis = fmaxf(0, getPaddingAndBorderAxis(child, mainAxis)); + child->layout.flexBasis = fmaxf(0, getPaddingAndBorderAxis(child, mainAxis)); } else { // Compute the flex basis and hypothetical main size (i.e. the clamped flex basis). - childWidth = CSS_UNDEFINED; - childHeight = CSS_UNDEFINED; - childWidthMeasureMode = CSS_MEASURE_MODE_UNDEFINED; - childHeightMeasureMode = CSS_MEASURE_MODE_UNDEFINED; + childWidth = CSSUndefined; + childHeight = CSSUndefined; + childWidthMeasureMode = CSSMeasureModeUndefined; + childHeightMeasureMode = CSSMeasureModeUndefined; - if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW)) { - childWidth = child->style.dimensions[CSS_WIDTH] + getMarginAxis(child, CSS_FLEX_DIRECTION_ROW); - childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; + if (isStyleDimDefined(child, CSSFlexDirectionRow)) { + childWidth = child->style.dimensions[CSSDimensionWidth] + getMarginAxis(child, CSSFlexDirectionRow); + childWidthMeasureMode = CSSMeasureModeExactly; } - if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN)) { - childHeight = child->style.dimensions[CSS_HEIGHT] + getMarginAxis(child, CSS_FLEX_DIRECTION_COLUMN); - childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY; + if (isStyleDimDefined(child, CSSFlexDirectionColumn)) { + childHeight = child->style.dimensions[CSSDimensionHeight] + getMarginAxis(child, CSSFlexDirectionColumn); + childHeightMeasureMode = CSSMeasureModeExactly; } // According to the spec, if the main size is not definite and the @@ -1053,15 +969,15 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab // the main size. Otherwise use "AT_MOST" in the cross axis. if (!isMainAxisRow && isUndefined(childWidth) && !isUndefined(availableInnerWidth)) { childWidth = availableInnerWidth; - childWidthMeasureMode = CSS_MEASURE_MODE_AT_MOST; + childWidthMeasureMode = CSSMeasureModeAtMost; } // The W3C spec doesn't say anything about the 'overflow' property, // but all major browsers appear to implement the following logic. - if (node->style.overflow == CSS_OVERFLOW_HIDDEN) { + if (node->style.overflow == CSSOverflowHidden) { if (isMainAxisRow && isUndefined(childHeight) && !isUndefined(availableInnerHeight)) { childHeight = availableInnerHeight; - childHeightMeasureMode = CSS_MEASURE_MODE_AT_MOST; + childHeightMeasureMode = CSSMeasureModeAtMost; } } @@ -1069,25 +985,25 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab // axis to be measured exactly with the available inner width if (!isMainAxisRow && !isUndefined(availableInnerWidth) && - !isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW) && - widthMeasureMode == CSS_MEASURE_MODE_EXACTLY && - getAlignItem(node, child) == CSS_ALIGN_STRETCH) { + !isStyleDimDefined(child, CSSFlexDirectionRow) && + widthMeasureMode == CSSMeasureModeExactly && + getAlignItem(node, child) == CSSAlignStretch) { childWidth = availableInnerWidth; - childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; + childWidthMeasureMode = CSSMeasureModeExactly; } if (isMainAxisRow && !isUndefined(availableInnerHeight) && - !isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN) && - heightMeasureMode == CSS_MEASURE_MODE_EXACTLY && - getAlignItem(node, child) == CSS_ALIGN_STRETCH) { + !isStyleDimDefined(child, CSSFlexDirectionColumn) && + heightMeasureMode == CSSMeasureModeExactly && + getAlignItem(node, child) == CSSAlignStretch) { childHeight = availableInnerHeight; - childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY; + childHeightMeasureMode = CSSMeasureModeExactly; } // Measure the child layoutNodeInternal(child, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, false, "measure"); - child->layout.flex_basis = fmaxf(isMainAxisRow ? child->layout.measured_dimensions[CSS_WIDTH] : child->layout.measured_dimensions[CSS_HEIGHT], getPaddingAndBorderAxis(child, mainAxis)); + child->layout.flexBasis = fmaxf(isMainAxisRow ? child->layout.measuredDimensions[CSSDimensionWidth] : child->layout.measuredDimensions[CSSDimensionHeight], getPaddingAndBorderAxis(child, mainAxis)); } } } @@ -1125,16 +1041,16 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab i = startOfLineIndex; // Maintain a linked list of the child nodes that can shrink and/or grow. - css_node_t* firstRelativeChild = NULL; - css_node_t* currentRelativeChild = NULL; + CSSNode* firstRelativeChild = NULL; + CSSNode* currentRelativeChild = NULL; // Add items to the current line until it's full or we run out of items. while (i < childCount) { - child = node->get_child(node->context, i); - child->line_index = lineCount; + child = CSSNodeListGet(node->children, i); + child->lineIndex = lineCount; - if (child->style.position_type != CSS_POSITION_ABSOLUTE) { - float outerFlexBasis = child->layout.flex_basis + getMarginAxis(child, mainAxis); + if (child->style.positionType != CSSPositionTypeAbsolute) { + float outerFlexBasis = child->layout.flexBasis + getMarginAxis(child, mainAxis); // If this is a multi-line flow and this item pushes us over the available size, we've // hit the end of the current line. Break out of the loop and lay out the current line. @@ -1150,7 +1066,7 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab // Unlike the grow factor, the shrink factor is scaled relative to the child // dimension. - totalFlexShrinkScaledFactors += getFlexShrinkFactor(child) * child->layout.flex_basis; + totalFlexShrinkScaledFactors += getFlexShrinkFactor(child) * child->layout.flexBasis; } // Store a private linked list of children that need to be layed out. @@ -1158,10 +1074,10 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab firstRelativeChild = child; } if (currentRelativeChild != NULL) { - currentRelativeChild->next_child = child; + currentRelativeChild->nextChild = child; } currentRelativeChild = child; - child->next_child = NULL; + child->nextChild = NULL; } i++; @@ -1169,7 +1085,7 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab } // If we don't need to measure the cross axis, we can skip the entire flex step. - bool canSkipFlex = !performLayout && measureModeCrossDim == CSS_MEASURE_MODE_EXACTLY; + bool canSkipFlex = !performLayout && measureModeCrossDim == CSSMeasureModeExactly; // In order to position the elements in the main axis, we have two // controls. The space between the beginning and the first element @@ -1219,7 +1135,7 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab float deltaFlexGrowFactors = 0; currentRelativeChild = firstRelativeChild; while (currentRelativeChild != NULL) { - childFlexBasis = currentRelativeChild->layout.flex_basis; + childFlexBasis = currentRelativeChild->layout.flexBasis; if (remainingFreeSpace < 0) { flexShrinkScaledFactor = getFlexShrinkFactor(currentRelativeChild) * childFlexBasis; @@ -1255,7 +1171,7 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab } } - currentRelativeChild = currentRelativeChild->next_child; + currentRelativeChild = currentRelativeChild->nextChild; } totalFlexShrinkScaledFactors += deltaFlexShrinkScaledFactors; @@ -1266,7 +1182,7 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab deltaFreeSpace = 0; currentRelativeChild = firstRelativeChild; while (currentRelativeChild != NULL) { - childFlexBasis = currentRelativeChild->layout.flex_basis; + childFlexBasis = currentRelativeChild->layout.flexBasis; float updatedMainSize = childFlexBasis; if (remainingFreeSpace < 0) { @@ -1290,48 +1206,48 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab deltaFreeSpace -= updatedMainSize - childFlexBasis; if (isMainAxisRow) { - childWidth = updatedMainSize + getMarginAxis(currentRelativeChild, CSS_FLEX_DIRECTION_ROW); - childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; + childWidth = updatedMainSize + getMarginAxis(currentRelativeChild, CSSFlexDirectionRow); + childWidthMeasureMode = CSSMeasureModeExactly; if (!isUndefined(availableInnerCrossDim) && - !isStyleDimDefined(currentRelativeChild, CSS_FLEX_DIRECTION_COLUMN) && - heightMeasureMode == CSS_MEASURE_MODE_EXACTLY && - getAlignItem(node, currentRelativeChild) == CSS_ALIGN_STRETCH) { + !isStyleDimDefined(currentRelativeChild, CSSFlexDirectionColumn) && + heightMeasureMode == CSSMeasureModeExactly && + getAlignItem(node, currentRelativeChild) == CSSAlignStretch) { childHeight = availableInnerCrossDim; - childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } else if (!isStyleDimDefined(currentRelativeChild, CSS_FLEX_DIRECTION_COLUMN)) { + childHeightMeasureMode = CSSMeasureModeExactly; + } else if (!isStyleDimDefined(currentRelativeChild, CSSFlexDirectionColumn)) { childHeight = availableInnerCrossDim; - childHeightMeasureMode = isUndefined(childHeight) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_AT_MOST; + childHeightMeasureMode = isUndefined(childHeight) ? CSSMeasureModeUndefined : CSSMeasureModeAtMost; } else { - childHeight = currentRelativeChild->style.dimensions[CSS_HEIGHT] + getMarginAxis(currentRelativeChild, CSS_FLEX_DIRECTION_COLUMN); - childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY; + childHeight = currentRelativeChild->style.dimensions[CSSDimensionHeight] + getMarginAxis(currentRelativeChild, CSSFlexDirectionColumn); + childHeightMeasureMode = CSSMeasureModeExactly; } } else { - childHeight = updatedMainSize + getMarginAxis(currentRelativeChild, CSS_FLEX_DIRECTION_COLUMN); - childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY; + childHeight = updatedMainSize + getMarginAxis(currentRelativeChild, CSSFlexDirectionColumn); + childHeightMeasureMode = CSSMeasureModeExactly; if (!isUndefined(availableInnerCrossDim) && - !isStyleDimDefined(currentRelativeChild, CSS_FLEX_DIRECTION_ROW) && - widthMeasureMode == CSS_MEASURE_MODE_EXACTLY && - getAlignItem(node, currentRelativeChild) == CSS_ALIGN_STRETCH) { + !isStyleDimDefined(currentRelativeChild, CSSFlexDirectionRow) && + widthMeasureMode == CSSMeasureModeExactly && + getAlignItem(node, currentRelativeChild) == CSSAlignStretch) { childWidth = availableInnerCrossDim; - childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } else if (!isStyleDimDefined(currentRelativeChild, CSS_FLEX_DIRECTION_ROW)) { + childWidthMeasureMode = CSSMeasureModeExactly; + } else if (!isStyleDimDefined(currentRelativeChild, CSSFlexDirectionRow)) { childWidth = availableInnerCrossDim; - childWidthMeasureMode = isUndefined(childWidth) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_AT_MOST; + childWidthMeasureMode = isUndefined(childWidth) ? CSSMeasureModeUndefined : CSSMeasureModeAtMost; } else { - childWidth = currentRelativeChild->style.dimensions[CSS_WIDTH] + getMarginAxis(currentRelativeChild, CSS_FLEX_DIRECTION_ROW); - childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; + childWidth = currentRelativeChild->style.dimensions[CSSDimensionWidth] + getMarginAxis(currentRelativeChild, CSSFlexDirectionRow); + childWidthMeasureMode = CSSMeasureModeExactly; } } bool requiresStretchLayout = !isStyleDimDefined(currentRelativeChild, crossAxis) && - getAlignItem(node, currentRelativeChild) == CSS_ALIGN_STRETCH; + getAlignItem(node, currentRelativeChild) == CSSAlignStretch; // Recursively call the layout algorithm for this child with the updated main size. layoutNodeInternal(currentRelativeChild, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, performLayout && !requiresStretchLayout, "flex"); - currentRelativeChild = currentRelativeChild->next_child; + currentRelativeChild = currentRelativeChild->nextChild; } } @@ -1346,25 +1262,25 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab // If we are using "at most" rules in the main axis, we won't distribute // any remaining space at this point. - if (measureModeMainDim == CSS_MEASURE_MODE_AT_MOST) { + if (measureModeMainDim == CSSMeasureModeAtMost) { remainingFreeSpace = 0; } // Use justifyContent to figure out how to allocate the remaining space // available in the main axis. - if (justifyContent != CSS_JUSTIFY_FLEX_START) { - if (justifyContent == CSS_JUSTIFY_CENTER) { + if (justifyContent != CSSJustifyFlexStart) { + if (justifyContent == CSSJustifyCenter) { leadingMainDim = remainingFreeSpace / 2; - } else if (justifyContent == CSS_JUSTIFY_FLEX_END) { + } else if (justifyContent == CSSJustifyFlexEnd) { leadingMainDim = remainingFreeSpace; - } else if (justifyContent == CSS_JUSTIFY_SPACE_BETWEEN) { + } else if (justifyContent == CSSJustifySpaceBetween) { remainingFreeSpace = fmaxf(remainingFreeSpace, 0); if (itemsOnLine > 1) { betweenMainDim = remainingFreeSpace / (itemsOnLine - 1); } else { betweenMainDim = 0; } - } else if (justifyContent == CSS_JUSTIFY_SPACE_AROUND) { + } else if (justifyContent == CSSJustifySpaceAround) { // Space on the edges is half of the space between elements betweenMainDim = remainingFreeSpace / itemsOnLine; leadingMainDim = betweenMainDim / 2; @@ -1375,9 +1291,9 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab float crossDim = 0; for (i = startOfLineIndex; i < endOfLineIndex; ++i) { - child = node->get_child(node->context, i); + child = CSSNodeListGet(node->children, i); - if (child->style.position_type == CSS_POSITION_ABSOLUTE && + if (child->style.positionType == CSSPositionTypeAbsolute && isPosDefined(child, leading[mainAxis])) { if (performLayout) { // In case the child is position absolute and has left/top being @@ -1397,11 +1313,11 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab // Now that we placed the element, we need to update the variables. // We need to do that only for relative elements. Absolute elements // do not take part in that phase. - if (child->style.position_type == CSS_POSITION_RELATIVE) { + if (child->style.positionType == CSSPositionTypeRelative) { if (canSkipFlex) { // If we skipped the flex step, then we can't rely on the measuredDims because // they weren't computed. This means we can't call getDimWithMargin. - mainDim += betweenMainDim + getMarginAxis(child, mainAxis) + child->layout.flex_basis; + mainDim += betweenMainDim + getMarginAxis(child, mainAxis) + child->layout.flexBasis; crossDim = availableInnerCrossDim; } else { // The main dimension is the sum of all the elements dimension plus @@ -1419,17 +1335,17 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab mainDim += trailingPaddingAndBorderMain; float containerCrossAxis = availableInnerCrossDim; - if (measureModeCrossDim == CSS_MEASURE_MODE_UNDEFINED || measureModeCrossDim == CSS_MEASURE_MODE_AT_MOST) { + if (measureModeCrossDim == CSSMeasureModeUndefined || measureModeCrossDim == CSSMeasureModeAtMost) { // Compute the cross axis from the max cross dimension of the children. containerCrossAxis = boundAxis(node, crossAxis, crossDim + paddingAndBorderAxisCross) - paddingAndBorderAxisCross; - if (measureModeCrossDim == CSS_MEASURE_MODE_AT_MOST) { + if (measureModeCrossDim == CSSMeasureModeAtMost) { containerCrossAxis = fminf(containerCrossAxis, availableInnerCrossDim); } } // If there's no flex wrap, the cross dimension is defined by the container. - if (!isNodeFlexWrap && measureModeCrossDim == CSS_MEASURE_MODE_EXACTLY) { + if (!isNodeFlexWrap && measureModeCrossDim == CSSMeasureModeExactly) { crossDim = availableInnerCrossDim; } @@ -1440,9 +1356,9 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab // We can skip child alignment if we're just measuring the container. if (performLayout) { for (i = startOfLineIndex; i < endOfLineIndex; ++i) { - child = node->get_child(node->context, i); + child = CSSNodeListGet(node->children, i); - if (child->style.position_type == CSS_POSITION_ABSOLUTE) { + if (child->style.positionType == CSSPositionTypeAbsolute) { // If the child is absolutely positioned and has a top/left/bottom/right // set, override all the previously computed positions to set it correctly. if (isPosDefined(child, leading[crossAxis])) { @@ -1458,35 +1374,35 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab // For a relative children, we're either using alignItems (parent) or // alignSelf (child) in order to determine the position in the cross axis - css_align_t alignItem = getAlignItem(node, child); + CSSAlign alignItem = getAlignItem(node, child); // If the child uses align stretch, we need to lay it out one more time, this time // forcing the cross-axis size to be the computed cross size for the current line. - if (alignItem == CSS_ALIGN_STRETCH) { - childWidth = child->layout.measured_dimensions[CSS_WIDTH] + getMarginAxis(child, CSS_FLEX_DIRECTION_ROW); - childHeight = child->layout.measured_dimensions[CSS_HEIGHT] + getMarginAxis(child, CSS_FLEX_DIRECTION_COLUMN); + if (alignItem == CSSAlignStretch) { + childWidth = child->layout.measuredDimensions[CSSDimensionWidth] + getMarginAxis(child, CSSFlexDirectionRow); + childHeight = child->layout.measuredDimensions[CSSDimensionHeight] + getMarginAxis(child, CSSFlexDirectionColumn); bool isCrossSizeDefinite = false; if (isMainAxisRow) { - isCrossSizeDefinite = isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN); + isCrossSizeDefinite = isStyleDimDefined(child, CSSFlexDirectionColumn); childHeight = crossDim; } else { - isCrossSizeDefinite = isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW); + isCrossSizeDefinite = isStyleDimDefined(child, CSSFlexDirectionRow); childWidth = crossDim; } // If the child defines a definite size for its cross axis, there's no need to stretch. if (!isCrossSizeDefinite) { - childWidthMeasureMode = isUndefined(childWidth) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_EXACTLY; - childHeightMeasureMode = isUndefined(childHeight) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_EXACTLY; + childWidthMeasureMode = isUndefined(childWidth) ? CSSMeasureModeUndefined : CSSMeasureModeExactly; + childHeightMeasureMode = isUndefined(childHeight) ? CSSMeasureModeUndefined : CSSMeasureModeExactly; layoutNodeInternal(child, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, true, "stretch"); } - } else if (alignItem != CSS_ALIGN_FLEX_START) { + } else if (alignItem != CSSAlignFlexStart) { float remainingCrossDim = containerCrossAxis - getDimWithMargin(child, crossAxis); - if (alignItem == CSS_ALIGN_CENTER) { + if (alignItem == CSSAlignCenter) { leadingCrossDim += remainingCrossDim / 2; - } else { // CSS_ALIGN_FLEX_END + } else { // CSSAlignFlexEnd leadingCrossDim += remainingCrossDim; } } @@ -1513,12 +1429,12 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab float crossDimLead = 0; float currentLead = leadingPaddingAndBorderCross; - css_align_t alignContent = node->style.align_content; - if (alignContent == CSS_ALIGN_FLEX_END) { + CSSAlign alignContent = node->style.alignContent; + if (alignContent == CSSAlignFlexEnd) { currentLead += remainingAlignContentDim; - } else if (alignContent == CSS_ALIGN_CENTER) { + } else if (alignContent == CSSAlignCenter) { currentLead += remainingAlignContentDim / 2; - } else if (alignContent == CSS_ALIGN_STRETCH) { + } else if (alignContent == CSSAlignStretch) { if (availableInnerCrossDim > totalLineCrossDim) { crossDimLead = (remainingAlignContentDim / lineCount); } @@ -1532,16 +1448,16 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab // compute the line's height and find the endIndex float lineHeight = 0; for (j = startIndex; j < childCount; ++j) { - child = node->get_child(node->context, j); - if (child->style.position_type != CSS_POSITION_RELATIVE) { + child = CSSNodeListGet(node->children, j); + if (child->style.positionType != CSSPositionTypeRelative) { continue; } - if (child->line_index != i) { + if (child->lineIndex != i) { break; } if (isLayoutDimDefined(child, crossAxis)) { lineHeight = fmaxf(lineHeight, - child->layout.measured_dimensions[dim[crossAxis]] + getMarginAxis(child, crossAxis)); + child->layout.measuredDimensions[dim[crossAxis]] + getMarginAxis(child, crossAxis)); } } endIndex = j; @@ -1549,20 +1465,20 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab if (performLayout) { for (j = startIndex; j < endIndex; ++j) { - child = node->get_child(node->context, j); - if (child->style.position_type != CSS_POSITION_RELATIVE) { + child = CSSNodeListGet(node->children, j); + if (child->style.positionType != CSSPositionTypeRelative) { continue; } - css_align_t alignContentAlignItem = getAlignItem(node, child); - if (alignContentAlignItem == CSS_ALIGN_FLEX_START) { + CSSAlign alignContentAlignItem = getAlignItem(node, child); + if (alignContentAlignItem == CSSAlignFlexStart) { child->layout.position[pos[crossAxis]] = currentLead + getLeadingMargin(child, crossAxis); - } else if (alignContentAlignItem == CSS_ALIGN_FLEX_END) { - child->layout.position[pos[crossAxis]] = currentLead + lineHeight - getTrailingMargin(child, crossAxis) - child->layout.measured_dimensions[dim[crossAxis]]; - } else if (alignContentAlignItem == CSS_ALIGN_CENTER) { - childHeight = child->layout.measured_dimensions[dim[crossAxis]]; + } else if (alignContentAlignItem == CSSAlignFlexEnd) { + child->layout.position[pos[crossAxis]] = currentLead + lineHeight - getTrailingMargin(child, crossAxis) - child->layout.measuredDimensions[dim[crossAxis]]; + } else if (alignContentAlignItem == CSSAlignCenter) { + childHeight = child->layout.measuredDimensions[dim[crossAxis]]; child->layout.position[pos[crossAxis]] = currentLead + (lineHeight - childHeight) / 2; - } else if (alignContentAlignItem == CSS_ALIGN_STRETCH) { + } else if (alignContentAlignItem == CSSAlignStretch) { child->layout.position[pos[crossAxis]] = currentLead + getLeadingMargin(child, crossAxis); // TODO(prenaux): Correctly set the height of items with indefinite // (auto) crossAxis dimension. @@ -1575,28 +1491,28 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab } // STEP 9: COMPUTING FINAL DIMENSIONS - node->layout.measured_dimensions[CSS_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, availableWidth - marginAxisRow); - node->layout.measured_dimensions[CSS_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, availableHeight - marginAxisColumn); + node->layout.measuredDimensions[CSSDimensionWidth] = boundAxis(node, CSSFlexDirectionRow, availableWidth - marginAxisRow); + node->layout.measuredDimensions[CSSDimensionHeight] = boundAxis(node, CSSFlexDirectionColumn, availableHeight - marginAxisColumn); // If the user didn't specify a width or height for the node, set the // dimensions based on the children. - if (measureModeMainDim == CSS_MEASURE_MODE_UNDEFINED) { + if (measureModeMainDim == CSSMeasureModeUndefined) { // Clamp the size to the min/max size, if specified, and make sure it // doesn't go below the padding and border amount. - node->layout.measured_dimensions[dim[mainAxis]] = boundAxis(node, mainAxis, maxLineMainDim); - } else if (measureModeMainDim == CSS_MEASURE_MODE_AT_MOST) { - node->layout.measured_dimensions[dim[mainAxis]] = fmaxf( + node->layout.measuredDimensions[dim[mainAxis]] = boundAxis(node, mainAxis, maxLineMainDim); + } else if (measureModeMainDim == CSSMeasureModeAtMost) { + node->layout.measuredDimensions[dim[mainAxis]] = fmaxf( fminf(availableInnerMainDim + paddingAndBorderAxisMain, boundAxisWithinMinAndMax(node, mainAxis, maxLineMainDim)), paddingAndBorderAxisMain); } - if (measureModeCrossDim == CSS_MEASURE_MODE_UNDEFINED) { + if (measureModeCrossDim == CSSMeasureModeUndefined) { // Clamp the size to the min/max size, if specified, and make sure it // doesn't go below the padding and border amount. - node->layout.measured_dimensions[dim[crossAxis]] = boundAxis(node, crossAxis, totalLineCrossDim + paddingAndBorderAxisCross); - } else if (measureModeCrossDim == CSS_MEASURE_MODE_AT_MOST) { - node->layout.measured_dimensions[dim[crossAxis]] = fmaxf( + node->layout.measuredDimensions[dim[crossAxis]] = boundAxis(node, crossAxis, totalLineCrossDim + paddingAndBorderAxisCross); + } else if (measureModeCrossDim == CSSMeasureModeAtMost) { + node->layout.measuredDimensions[dim[crossAxis]] = fmaxf( fminf(availableInnerCrossDim + paddingAndBorderAxisCross, boundAxisWithinMinAndMax(node, crossAxis, totalLineCrossDim + paddingAndBorderAxisCross)), paddingAndBorderAxisCross); @@ -1607,20 +1523,20 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab bool needsMainTrailingPos = false; bool needsCrossTrailingPos = false; - if (mainAxis == CSS_FLEX_DIRECTION_ROW_REVERSE || - mainAxis == CSS_FLEX_DIRECTION_COLUMN_REVERSE) { + if (mainAxis == CSSFlexDirectionRowReverse || + mainAxis == CSSFlexDirectionColumnReverse) { needsMainTrailingPos = true; } - if (crossAxis == CSS_FLEX_DIRECTION_ROW_REVERSE || - crossAxis == CSS_FLEX_DIRECTION_COLUMN_REVERSE) { + if (crossAxis == CSSFlexDirectionRowReverse || + crossAxis == CSSFlexDirectionColumnReverse) { needsCrossTrailingPos = true; } // Set trailing position if necessary. if (needsMainTrailingPos || needsCrossTrailingPos) { for (i = 0; i < childCount; ++i) { - child = node->get_child(node->context, i); + child = CSSNodeListGet(node->children, i); if (needsMainTrailingPos) { setTrailingPosition(node, child, mainAxis); @@ -1640,37 +1556,37 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab // absolutely-positioned children. if (performLayout) { - childWidth = CSS_UNDEFINED; - childHeight = CSS_UNDEFINED; + childWidth = CSSUndefined; + childHeight = CSSUndefined; - if (isStyleDimDefined(currentAbsoluteChild, CSS_FLEX_DIRECTION_ROW)) { - childWidth = currentAbsoluteChild->style.dimensions[CSS_WIDTH] + getMarginAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_ROW); + if (isStyleDimDefined(currentAbsoluteChild, CSSFlexDirectionRow)) { + childWidth = currentAbsoluteChild->style.dimensions[CSSDimensionWidth] + getMarginAxis(currentAbsoluteChild, CSSFlexDirectionRow); } else { // If the child doesn't have a specified width, compute the width based on the left/right offsets if they're defined. - if (isPosDefined(currentAbsoluteChild, CSS_LEFT) && isPosDefined(currentAbsoluteChild, CSS_RIGHT)) { - childWidth = node->layout.measured_dimensions[CSS_WIDTH] - - (getLeadingBorder(node, CSS_FLEX_DIRECTION_ROW) + getTrailingBorder(node, CSS_FLEX_DIRECTION_ROW)) - - (currentAbsoluteChild->style.position[CSS_LEFT] + currentAbsoluteChild->style.position[CSS_RIGHT]); - childWidth = boundAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_ROW, childWidth); + if (isPosDefined(currentAbsoluteChild, CSSPositionLeft) && isPosDefined(currentAbsoluteChild, CSSPositionRight)) { + childWidth = node->layout.measuredDimensions[CSSDimensionWidth] - + (getLeadingBorder(node, CSSFlexDirectionRow) + getTrailingBorder(node, CSSFlexDirectionRow)) - + (currentAbsoluteChild->style.position[CSSPositionLeft] + currentAbsoluteChild->style.position[CSSPositionRight]); + childWidth = boundAxis(currentAbsoluteChild, CSSFlexDirectionRow, childWidth); } } - if (isStyleDimDefined(currentAbsoluteChild, CSS_FLEX_DIRECTION_COLUMN)) { - childHeight = currentAbsoluteChild->style.dimensions[CSS_HEIGHT] + getMarginAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_COLUMN); + if (isStyleDimDefined(currentAbsoluteChild, CSSFlexDirectionColumn)) { + childHeight = currentAbsoluteChild->style.dimensions[CSSDimensionHeight] + getMarginAxis(currentAbsoluteChild, CSSFlexDirectionColumn); } else { // If the child doesn't have a specified height, compute the height based on the top/bottom offsets if they're defined. - if (isPosDefined(currentAbsoluteChild, CSS_TOP) && isPosDefined(currentAbsoluteChild, CSS_BOTTOM)) { - childHeight = node->layout.measured_dimensions[CSS_HEIGHT] - - (getLeadingBorder(node, CSS_FLEX_DIRECTION_COLUMN) + getTrailingBorder(node, CSS_FLEX_DIRECTION_COLUMN)) - - (currentAbsoluteChild->style.position[CSS_TOP] + currentAbsoluteChild->style.position[CSS_BOTTOM]); - childHeight = boundAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_COLUMN, childHeight); + if (isPosDefined(currentAbsoluteChild, CSSPositionTop) && isPosDefined(currentAbsoluteChild, CSSPositionBottom)) { + childHeight = node->layout.measuredDimensions[CSSDimensionHeight] - + (getLeadingBorder(node, CSSFlexDirectionColumn) + getTrailingBorder(node, CSSFlexDirectionColumn)) - + (currentAbsoluteChild->style.position[CSSPositionTop] + currentAbsoluteChild->style.position[CSSPositionBottom]); + childHeight = boundAxis(currentAbsoluteChild, CSSFlexDirectionColumn, childHeight); } } // If we're still missing one or the other dimension, measure the content. if (isUndefined(childWidth) || isUndefined(childHeight)) { - childWidthMeasureMode = isUndefined(childWidth) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_EXACTLY; - childHeightMeasureMode = isUndefined(childHeight) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_EXACTLY; + childWidthMeasureMode = isUndefined(childWidth) ? CSSMeasureModeUndefined : CSSMeasureModeExactly; + childHeightMeasureMode = isUndefined(childHeight) ? CSSMeasureModeUndefined : CSSMeasureModeExactly; // According to the spec, if the main size is not definite and the // child's inline axis is parallel to the main axis (i.e. it's @@ -1678,45 +1594,44 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab // the main size. Otherwise use "AT_MOST" in the cross axis. if (!isMainAxisRow && isUndefined(childWidth) && !isUndefined(availableInnerWidth)) { childWidth = availableInnerWidth; - childWidthMeasureMode = CSS_MEASURE_MODE_AT_MOST; + childWidthMeasureMode = CSSMeasureModeAtMost; } // The W3C spec doesn't say anything about the 'overflow' property, // but all major browsers appear to implement the following logic. - if (node->style.overflow == CSS_OVERFLOW_HIDDEN) { + if (node->style.overflow == CSSOverflowHidden) { if (isMainAxisRow && isUndefined(childHeight) && !isUndefined(availableInnerHeight)) { childHeight = availableInnerHeight; - childHeightMeasureMode = CSS_MEASURE_MODE_AT_MOST; + childHeightMeasureMode = CSSMeasureModeAtMost; } } layoutNodeInternal(currentAbsoluteChild, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, false, "abs-measure"); - childWidth = currentAbsoluteChild->layout.measured_dimensions[CSS_WIDTH] + getMarginAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_ROW); - childHeight = currentAbsoluteChild->layout.measured_dimensions[CSS_HEIGHT] + getMarginAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_COLUMN); + childWidth = currentAbsoluteChild->layout.measuredDimensions[CSSDimensionWidth] + getMarginAxis(currentAbsoluteChild, CSSFlexDirectionRow); + childHeight = currentAbsoluteChild->layout.measuredDimensions[CSSDimensionHeight] + getMarginAxis(currentAbsoluteChild, CSSFlexDirectionColumn); } - layoutNodeInternal(currentAbsoluteChild, childWidth, childHeight, direction, CSS_MEASURE_MODE_EXACTLY, CSS_MEASURE_MODE_EXACTLY, true, "abs-layout"); + layoutNodeInternal(currentAbsoluteChild, childWidth, childHeight, direction, CSSMeasureModeExactly, CSSMeasureModeExactly, true, "abs-layout"); - if (isPosDefined(currentAbsoluteChild, trailing[CSS_FLEX_DIRECTION_ROW]) && - !isPosDefined(currentAbsoluteChild, leading[CSS_FLEX_DIRECTION_ROW])) { - currentAbsoluteChild->layout.position[leading[CSS_FLEX_DIRECTION_ROW]] = - node->layout.measured_dimensions[dim[CSS_FLEX_DIRECTION_ROW]] - - currentAbsoluteChild->layout.measured_dimensions[dim[CSS_FLEX_DIRECTION_ROW]] - - getPosition(currentAbsoluteChild, trailing[CSS_FLEX_DIRECTION_ROW]); + if (isPosDefined(currentAbsoluteChild, trailing[CSSFlexDirectionRow]) && + !isPosDefined(currentAbsoluteChild, leading[CSSFlexDirectionRow])) { + currentAbsoluteChild->layout.position[leading[CSSFlexDirectionRow]] = + node->layout.measuredDimensions[dim[CSSFlexDirectionRow]] - + currentAbsoluteChild->layout.measuredDimensions[dim[CSSFlexDirectionRow]] - + getPosition(currentAbsoluteChild, trailing[CSSFlexDirectionRow]); } - if (isPosDefined(currentAbsoluteChild, trailing[CSS_FLEX_DIRECTION_COLUMN]) && - !isPosDefined(currentAbsoluteChild, leading[CSS_FLEX_DIRECTION_COLUMN])) { - currentAbsoluteChild->layout.position[leading[CSS_FLEX_DIRECTION_COLUMN]] = - node->layout.measured_dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] - - currentAbsoluteChild->layout.measured_dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] - - getPosition(currentAbsoluteChild, trailing[CSS_FLEX_DIRECTION_COLUMN]); + if (isPosDefined(currentAbsoluteChild, trailing[CSSFlexDirectionColumn]) && + !isPosDefined(currentAbsoluteChild, leading[CSSFlexDirectionColumn])) { + currentAbsoluteChild->layout.position[leading[CSSFlexDirectionColumn]] = + node->layout.measuredDimensions[dim[CSSFlexDirectionColumn]] - + currentAbsoluteChild->layout.measuredDimensions[dim[CSSFlexDirectionColumn]] - + getPosition(currentAbsoluteChild, trailing[CSSFlexDirectionColumn]); } } - currentAbsoluteChild = currentAbsoluteChild->next_child; + currentAbsoluteChild = currentAbsoluteChild->nextChild; } - /** END_GENERATED **/ } int gDepth = 0; @@ -1734,19 +1649,19 @@ static const char* getSpacer(unsigned long level) { return &spacer[spacerLen - level]; } -static const char* getModeName(css_measure_mode_t mode, bool performLayout) { - const char* kMeasureModeNames[CSS_MEASURE_MODE_COUNT] = { +static const char* getModeName(CSSMeasureMode mode, bool performLayout) { + const char* kMeasureModeNames[CSSMeasureModeCount] = { "UNDEFINED", "EXACTLY", "AT_MOST" }; - const char* kLayoutModeNames[CSS_MEASURE_MODE_COUNT] = { + const char* kLayoutModeNames[CSSMeasureModeCount] = { "LAY_UNDEFINED", "LAY_EXACTLY", "LAY_AT_MOST" }; - if (mode >= CSS_MEASURE_MODE_COUNT) { + if (mode >= CSSMeasureModeCount) { return ""; } @@ -1754,38 +1669,38 @@ static const char* getModeName(css_measure_mode_t mode, bool performLayout) { } static bool canUseCachedMeasurement( - bool is_text_node, - float available_width, - float available_height, + bool isTextNode, + float availableWidth, + float availableHeight, float margin_row, float margin_column, - css_measure_mode_t width_measure_mode, - css_measure_mode_t height_measure_mode, - css_cached_measurement_t cached_layout) { + CSSMeasureMode widthMeasureMode, + CSSMeasureMode heightMeasureMode, + CSSCachedMeasurement cached_layout) { bool is_height_same = - (cached_layout.height_measure_mode == CSS_MEASURE_MODE_UNDEFINED && height_measure_mode == CSS_MEASURE_MODE_UNDEFINED) || - (cached_layout.height_measure_mode == height_measure_mode && eq(cached_layout.available_height, available_height)); + (cached_layout.heightMeasureMode == CSSMeasureModeUndefined && heightMeasureMode == CSSMeasureModeUndefined) || + (cached_layout.heightMeasureMode == heightMeasureMode && eq(cached_layout.availableHeight, availableHeight)); bool is_width_same = - (cached_layout.width_measure_mode == CSS_MEASURE_MODE_UNDEFINED && width_measure_mode == CSS_MEASURE_MODE_UNDEFINED) || - (cached_layout.width_measure_mode == width_measure_mode && eq(cached_layout.available_width, available_width)); + (cached_layout.widthMeasureMode == CSSMeasureModeUndefined && widthMeasureMode == CSSMeasureModeUndefined) || + (cached_layout.widthMeasureMode == widthMeasureMode && eq(cached_layout.availableWidth, availableWidth)); if (is_height_same && is_width_same) { return true; } bool is_height_valid = - (cached_layout.height_measure_mode == CSS_MEASURE_MODE_UNDEFINED && height_measure_mode == CSS_MEASURE_MODE_AT_MOST && cached_layout.computed_height <= (available_height - margin_column)) || - (height_measure_mode == CSS_MEASURE_MODE_EXACTLY && eq(cached_layout.computed_height, available_height - margin_column)); + (cached_layout.heightMeasureMode == CSSMeasureModeUndefined && heightMeasureMode == CSSMeasureModeAtMost && cached_layout.computedHeight <= (availableHeight - margin_column)) || + (heightMeasureMode == CSSMeasureModeExactly && eq(cached_layout.computedHeight, availableHeight - margin_column)); if (is_width_same && is_height_valid) { return true; } bool is_width_valid = - (cached_layout.width_measure_mode == CSS_MEASURE_MODE_UNDEFINED && width_measure_mode == CSS_MEASURE_MODE_AT_MOST && cached_layout.computed_width <= (available_width - margin_row)) || - (width_measure_mode == CSS_MEASURE_MODE_EXACTLY && eq(cached_layout.computed_width, available_width - margin_row)); + (cached_layout.widthMeasureMode == CSSMeasureModeUndefined && widthMeasureMode == CSSMeasureModeAtMost && cached_layout.computedWidth <= (availableWidth - margin_row)) || + (widthMeasureMode == CSSMeasureModeExactly && eq(cached_layout.computedWidth, availableWidth - margin_row)); if (is_height_same && is_width_valid) { return true; @@ -1796,29 +1711,29 @@ static bool canUseCachedMeasurement( } // We know this to be text so we can apply some more specialized heuristics. - if (is_text_node) { + if (isTextNode) { if (is_width_same) { - if (height_measure_mode == CSS_MEASURE_MODE_UNDEFINED) { + if (heightMeasureMode == CSSMeasureModeUndefined) { // Width is the same and height is not restricted. Re-use cahced value. return true; } - if (height_measure_mode == CSS_MEASURE_MODE_AT_MOST && - cached_layout.computed_height < (available_height - margin_column)) { + if (heightMeasureMode == CSSMeasureModeAtMost && + cached_layout.computedHeight < (availableHeight - margin_column)) { // Width is the same and height restriction is greater than the cached height. Re-use cached value. return true; } // Width is the same but height restriction imposes smaller height than previously measured. // Update the cached value to respect the new height restriction. - cached_layout.computed_height = available_height - margin_column; + cached_layout.computedHeight = availableHeight - margin_column; return true; } - if (cached_layout.width_measure_mode == CSS_MEASURE_MODE_UNDEFINED) { - if (width_measure_mode == CSS_MEASURE_MODE_UNDEFINED || - (width_measure_mode == CSS_MEASURE_MODE_AT_MOST && - cached_layout.computed_width <= (available_width - margin_row))) { + if (cached_layout.widthMeasureMode == CSSMeasureModeUndefined) { + if (widthMeasureMode == CSSMeasureModeUndefined || + (widthMeasureMode == CSSMeasureModeAtMost && + cached_layout.computedWidth <= (availableWidth - margin_row))) { // Previsouly this text was measured with no width restriction, if width is now restricted // but to a larger value than the previsouly measured width we can re-use the measurement // as we know it will fit. @@ -1838,23 +1753,23 @@ static bool canUseCachedMeasurement( // Input parameters are the same as layoutNodeImpl (see above) // Return parameter is true if layout was performed, false if skipped // -bool layoutNodeInternal(css_node_t* node, float availableWidth, float availableHeight, - css_direction_t parentDirection, css_measure_mode_t widthMeasureMode, css_measure_mode_t heightMeasureMode, bool performLayout, char* reason) { - css_layout_t* layout = &node->layout; +bool layoutNodeInternal(CSSNode* node, float availableWidth, float availableHeight, + CSSDirection parentDirection, CSSMeasureMode widthMeasureMode, CSSMeasureMode heightMeasureMode, bool performLayout, char* reason) { + CSSLayout* layout = &node->layout; gDepth++; - bool needToVisitNode = (node->is_dirty(node->context) && layout->generation_count != gCurrentGenerationCount) || - layout->last_parent_direction != parentDirection; + bool needToVisitNode = (node->isDirty && layout->generationCount != gCurrentGenerationCount) || + layout->lastParentDirection != parentDirection; if (needToVisitNode) { // Invalidate the cached results. - layout->next_cached_measurements_index = 0; - layout->cached_layout.width_measure_mode = (css_measure_mode_t)-1; - layout->cached_layout.height_measure_mode = (css_measure_mode_t)-1; + layout->nextCachedMeasurementsIndex = 0; + layout->cached_layout.widthMeasureMode = (CSSMeasureMode)-1; + layout->cached_layout.heightMeasureMode = (CSSMeasureMode)-1; } - css_cached_measurement_t* cachedResults = NULL; + CSSCachedMeasurement* cachedResults = NULL; // Determine whether the results are already cached. We maintain a separate // cache for layouts and measurements. A layout operation modifies the positions @@ -1864,47 +1779,47 @@ bool layoutNodeInternal(css_node_t* node, float availableWidth, float availableH // We handle nodes with measure functions specially here because they are the most // expensive to measure, so it's worth avoiding redundant measurements if at all possible. if (isMeasureDefined(node)) { - float marginAxisRow = getMarginAxis(node, CSS_FLEX_DIRECTION_ROW); - float marginAxisColumn = getMarginAxis(node, CSS_FLEX_DIRECTION_COLUMN); + float marginAxisRow = getMarginAxis(node, CSSFlexDirectionRow); + float marginAxisColumn = getMarginAxis(node, CSSFlexDirectionColumn); // First, try to use the layout cache. - if (canUseCachedMeasurement(node->is_text_node && node->is_text_node(node->context), availableWidth, availableHeight, marginAxisRow, marginAxisColumn, + if (canUseCachedMeasurement(node->isTextNode, availableWidth, availableHeight, marginAxisRow, marginAxisColumn, widthMeasureMode, heightMeasureMode, layout->cached_layout)) { cachedResults = &layout->cached_layout; } else { // Try to use the measurement cache. - for (int i = 0; i < layout->next_cached_measurements_index; i++) { - if (canUseCachedMeasurement(node->is_text_node && node->is_text_node(node->context), availableWidth, availableHeight, marginAxisRow, marginAxisColumn, - widthMeasureMode, heightMeasureMode, layout->cached_measurements[i])) { - cachedResults = &layout->cached_measurements[i]; + for (int i = 0; i < layout->nextCachedMeasurementsIndex; i++) { + if (canUseCachedMeasurement(node->isTextNode, availableWidth, availableHeight, marginAxisRow, marginAxisColumn, + widthMeasureMode, heightMeasureMode, layout->cachedMeasurements[i])) { + cachedResults = &layout->cachedMeasurements[i]; break; } } } } else if (performLayout) { - if (eq(layout->cached_layout.available_width, availableWidth) && - eq(layout->cached_layout.available_height, availableHeight) && - layout->cached_layout.width_measure_mode == widthMeasureMode && - layout->cached_layout.height_measure_mode == heightMeasureMode) { + if (eq(layout->cached_layout.availableWidth, availableWidth) && + eq(layout->cached_layout.availableHeight, availableHeight) && + layout->cached_layout.widthMeasureMode == widthMeasureMode && + layout->cached_layout.heightMeasureMode == heightMeasureMode) { cachedResults = &layout->cached_layout; } } else { - for (int i = 0; i < layout->next_cached_measurements_index; i++) { - if (eq(layout->cached_measurements[i].available_width, availableWidth) && - eq(layout->cached_measurements[i].available_height, availableHeight) && - layout->cached_measurements[i].width_measure_mode == widthMeasureMode && - layout->cached_measurements[i].height_measure_mode == heightMeasureMode) { + for (int i = 0; i < layout->nextCachedMeasurementsIndex; i++) { + if (eq(layout->cachedMeasurements[i].availableWidth, availableWidth) && + eq(layout->cachedMeasurements[i].availableHeight, availableHeight) && + layout->cachedMeasurements[i].widthMeasureMode == widthMeasureMode && + layout->cachedMeasurements[i].heightMeasureMode == heightMeasureMode) { - cachedResults = &layout->cached_measurements[i]; + cachedResults = &layout->cachedMeasurements[i]; break; } } } if (!needToVisitNode && cachedResults != NULL) { - layout->measured_dimensions[CSS_WIDTH] = cachedResults->computed_width; - layout->measured_dimensions[CSS_HEIGHT] = cachedResults->computed_height; + layout->measuredDimensions[CSSDimensionWidth] = cachedResults->computedWidth; + layout->measuredDimensions[CSSDimensionHeight] = cachedResults->computedHeight; if (gPrintChanges && gPrintSkips) { printf("%s%d.{[skipped] ", getSpacer(gDepth), gDepth); @@ -1915,7 +1830,7 @@ bool layoutNodeInternal(css_node_t* node, float availableWidth, float availableH getModeName(widthMeasureMode, performLayout), getModeName(heightMeasureMode, performLayout), availableWidth, availableHeight, - cachedResults->computed_width, cachedResults->computed_height, reason); + cachedResults->computedWidth, cachedResults->computedHeight, reason); } } else { @@ -1940,76 +1855,77 @@ bool layoutNodeInternal(css_node_t* node, float availableWidth, float availableH printf("wm: %s, hm: %s, d: (%f, %f) %s\n", getModeName(widthMeasureMode, performLayout), getModeName(heightMeasureMode, performLayout), - layout->measured_dimensions[CSS_WIDTH], layout->measured_dimensions[CSS_HEIGHT], reason); + layout->measuredDimensions[CSSDimensionWidth], layout->measuredDimensions[CSSDimensionHeight], reason); } - layout->last_parent_direction = parentDirection; + layout->lastParentDirection = parentDirection; if (cachedResults == NULL) { - if (layout->next_cached_measurements_index == CSS_MAX_CACHED_RESULT_COUNT) { + if (layout->nextCachedMeasurementsIndex == CSS_MAX_CACHED_RESULT_COUNT) { if (gPrintChanges) { printf("Out of cache entries!\n"); } - layout->next_cached_measurements_index = 0; + layout->nextCachedMeasurementsIndex = 0; } - css_cached_measurement_t* newCacheEntry; + CSSCachedMeasurement* newCacheEntry; if (performLayout) { // Use the single layout cache entry. newCacheEntry = &layout->cached_layout; } else { // Allocate a new measurement cache entry. - newCacheEntry = &layout->cached_measurements[layout->next_cached_measurements_index]; - layout->next_cached_measurements_index++; + newCacheEntry = &layout->cachedMeasurements[layout->nextCachedMeasurementsIndex]; + layout->nextCachedMeasurementsIndex++; } - newCacheEntry->available_width = availableWidth; - newCacheEntry->available_height = availableHeight; - newCacheEntry->width_measure_mode = widthMeasureMode; - newCacheEntry->height_measure_mode = heightMeasureMode; - newCacheEntry->computed_width = layout->measured_dimensions[CSS_WIDTH]; - newCacheEntry->computed_height = layout->measured_dimensions[CSS_HEIGHT]; + newCacheEntry->availableWidth = availableWidth; + newCacheEntry->availableHeight = availableHeight; + newCacheEntry->widthMeasureMode = widthMeasureMode; + newCacheEntry->heightMeasureMode = heightMeasureMode; + newCacheEntry->computedWidth = layout->measuredDimensions[CSSDimensionWidth]; + newCacheEntry->computedHeight = layout->measuredDimensions[CSSDimensionHeight]; } } if (performLayout) { - node->layout.dimensions[CSS_WIDTH] = node->layout.measured_dimensions[CSS_WIDTH]; - node->layout.dimensions[CSS_HEIGHT] = node->layout.measured_dimensions[CSS_HEIGHT]; - layout->should_update = true; + node->layout.dimensions[CSSDimensionWidth] = node->layout.measuredDimensions[CSSDimensionWidth]; + node->layout.dimensions[CSSDimensionHeight] = node->layout.measuredDimensions[CSSDimensionHeight]; + node->shouldUpdate = true; + node->isDirty = false; } gDepth--; - layout->generation_count = gCurrentGenerationCount; + layout->generationCount = gCurrentGenerationCount; return (needToVisitNode || cachedResults == NULL); } -void layoutNode(css_node_t* node, float availableWidth, float availableHeight, css_direction_t parentDirection) { +void CSSNodeCalculateLayout(CSSNode* node, float availableWidth, float availableHeight, CSSDirection parentDirection) { // Increment the generation count. This will force the recursive routine to visit // all dirty nodes at least once. Subsequent visits will be skipped if the input // parameters don't change. gCurrentGenerationCount++; - css_measure_mode_t widthMeasureMode = CSS_MEASURE_MODE_UNDEFINED; - css_measure_mode_t heightMeasureMode = CSS_MEASURE_MODE_UNDEFINED; + CSSMeasureMode widthMeasureMode = CSSMeasureModeUndefined; + CSSMeasureMode heightMeasureMode = CSSMeasureModeUndefined; if (!isUndefined(availableWidth)) { - widthMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } else if (isStyleDimDefined(node, CSS_FLEX_DIRECTION_ROW)) { - availableWidth = node->style.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] + getMarginAxis(node, CSS_FLEX_DIRECTION_ROW); - widthMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } else if (node->style.maxDimensions[CSS_WIDTH] >= 0.0) { - availableWidth = node->style.maxDimensions[CSS_WIDTH]; - widthMeasureMode = CSS_MEASURE_MODE_AT_MOST; + widthMeasureMode = CSSMeasureModeExactly; + } else if (isStyleDimDefined(node, CSSFlexDirectionRow)) { + availableWidth = node->style.dimensions[dim[CSSFlexDirectionRow]] + getMarginAxis(node, CSSFlexDirectionRow); + widthMeasureMode = CSSMeasureModeExactly; + } else if (node->style.maxDimensions[CSSDimensionWidth] >= 0.0) { + availableWidth = node->style.maxDimensions[CSSDimensionWidth]; + widthMeasureMode = CSSMeasureModeAtMost; } if (!isUndefined(availableHeight)) { - heightMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } else if (isStyleDimDefined(node, CSS_FLEX_DIRECTION_COLUMN)) { - availableHeight = node->style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] + getMarginAxis(node, CSS_FLEX_DIRECTION_COLUMN); - heightMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } else if (node->style.maxDimensions[CSS_HEIGHT] >= 0.0) { - availableHeight = node->style.maxDimensions[CSS_HEIGHT]; - heightMeasureMode = CSS_MEASURE_MODE_AT_MOST; + heightMeasureMode = CSSMeasureModeExactly; + } else if (isStyleDimDefined(node, CSSFlexDirectionColumn)) { + availableHeight = node->style.dimensions[dim[CSSFlexDirectionColumn]] + getMarginAxis(node, CSSFlexDirectionColumn); + heightMeasureMode = CSSMeasureModeExactly; + } else if (node->style.maxDimensions[CSSDimensionHeight] >= 0.0) { + availableHeight = node->style.maxDimensions[CSSDimensionHeight]; + heightMeasureMode = CSSMeasureModeAtMost; } if (layoutNodeInternal(node, availableWidth, availableHeight, parentDirection, widthMeasureMode, heightMeasureMode, true, "initial")) { @@ -2017,9 +1933,7 @@ void layoutNode(css_node_t* node, float availableWidth, float availableHeight, c setPosition(node, node->layout.direction); if (gPrintTree) { - print_css_node(node, CSS_PRINT_LAYOUT | CSS_PRINT_CHILDREN | CSS_PRINT_STYLE); + CSSNodePrint(node, CSSPrintOptionsLayout | CSSPrintOptionsChildren | CSSPrintOptionsStyle); } } } - -#endif // CSS_LAYOUT_IMPLEMENTATION \ No newline at end of file diff --git a/CSSLayout/CSSLayout.h b/CSSLayout/CSSLayout.h new file mode 100644 index 00000000..23d38372 --- /dev/null +++ b/CSSLayout/CSSLayout.h @@ -0,0 +1,210 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#ifndef __CSS_LAYOUT_H +#define __CSS_LAYOUT_H + +#include +#ifndef __cplusplus +#include +#endif + +// Not defined in MSVC++ +#ifndef NAN +static const unsigned long __nan[2] = {0xffffffff, 0x7fffffff}; +#define NAN (*(const float *)__nan) +#endif + +#define CSSUndefined NAN + +#include + +CSS_EXTERN_C_BEGIN + +typedef enum CSSDirection { + CSSDirectionInherit, + CSSDirectionLTR, + CSSDirectionRTL, +} CSSDirection; + +typedef enum CSSFlexDirection { + CSSFlexDirectionColumn, + CSSFlexDirectionColumnReverse, + CSSFlexDirectionRow, + CSSFlexDirectionRowReverse, +} CSSFlexDirection; + +typedef enum CSSJustify { + CSSJustifyFlexStart, + CSSJustifyCenter, + CSSJustifyFlexEnd, + CSSJustifySpaceBetween, + CSSJustifySpaceAround, +} CSSJustify; + +typedef enum CSSOverflow { + CSSOverflowVisible, + CSSOverflowHidden, +} CSSOverflow; + +// Note: auto is only a valid value for alignSelf. It is NOT a valid value for +// alignItems. +typedef enum CSSAlign { + CSSAlignAuto, + CSSAlignFlexStart, + CSSAlignCenter, + CSSAlignFlexEnd, + CSSAlignStretch, +} CSSAlign; + +typedef enum CSSPositionType { + CSSPositionTypeRelative, + CSSPositionTypeAbsolute, +} CSSPositionType; + +typedef enum CSSWrapType { + CSSWrapTypeNoWrap, + CSSWrapTypeWrap, +} CSSWrapType; + +// Note: left and top are shared between position[2] and position[4], so +// they have to be before right and bottom. +typedef enum CSSPosition { + CSSPositionLeft, + CSSPositionTop, + CSSPositionRight, + CSSPositionBottom, + CSSPositionStart, + CSSPositionEnd, + CSSPositionCount, +} CSSPosition; + +typedef enum CSSMeasureMode { + CSSMeasureModeUndefined, + CSSMeasureModeExactly, + CSSMeasureModeAtMost, + CSSMeasureModeCount, +} CSSMeasureMode; + +typedef enum CSSDimension { + CSSDimensionWidth, + CSSDimensionHeight, +} CSSDimension; + +typedef enum CSSPrintOptions { + CSSPrintOptionsLayout = 1, + CSSPrintOptionsStyle = 2, + CSSPrintOptionsChildren = 4, +} CSSPrintOptions; + +typedef struct CSSSize { + float width; + float height; +} CSSSize; + +typedef struct CSSNode * CSSNodeRef; +typedef CSSSize (*CSSMeasureFunc)(void *context, float width, CSSMeasureMode widthMode, float height, CSSMeasureMode heightMode); +typedef void (*CSSPrintFunc)(void *context); + +// CSSNode +CSSNodeRef CSSNodeNew(); +void CSSNodeInit(CSSNodeRef node); +void CSSNodeFree(CSSNodeRef node); + +void CSSNodeInsertChild(CSSNodeRef node, CSSNodeRef child, unsigned int index); +void CSSNodeRemoveChild(CSSNodeRef node, CSSNodeRef child); +CSSNodeRef CSSNodeGetChild(CSSNodeRef node, unsigned int index); +unsigned int CSSNodeChildCount(CSSNodeRef node); + +void CSSNodeCalculateLayout( + CSSNodeRef node, + float availableWidth, + float availableHeight, + CSSDirection parentDirection); + +// Mark a node as dirty. Only valid for nodes with a custom measure function set. +// CSSLayout knows when to mark all other nodes as dirty but because nodes with measure functions +// depends on information not known to CSSLayout they must perform this dirty marking manually. +void CSSNodeMarkDirty(CSSNodeRef node); + +void CSSNodePrint(CSSNodeRef node, CSSPrintOptions options); + +bool isUndefined(float value); + +#define CSS_NODE_PROPERTY(type, name, paramName) \ +void CSSNodeSet##name(CSSNodeRef node, type paramName); \ +type CSSNodeGet##name(CSSNodeRef node); + +#define CSS_NODE_STYLE_PROPERTY(type, name, paramName) \ +void CSSNodeStyleSet##name(CSSNodeRef node, type paramName); \ +type CSSNodeStyleGet##name(CSSNodeRef node); + +#define CSS_NODE_LAYOUT_PROPERTY(type, name) \ +type CSSNodeLayoutGet##name(CSSNodeRef node); + +CSS_NODE_PROPERTY(void*, Context, context); +CSS_NODE_PROPERTY(CSSMeasureFunc, MeasureFunc, measureFunc); +CSS_NODE_PROPERTY(CSSPrintFunc, PrintFunc, printFunc); +CSS_NODE_PROPERTY(bool, IsTextnode, isTextNode); +CSS_NODE_PROPERTY(bool, ShouldUpdate, shouldUpdate); + +CSS_NODE_STYLE_PROPERTY(CSSDirection, Direction, direction); +CSS_NODE_STYLE_PROPERTY(CSSFlexDirection, FlexDirection, flexDirection); +CSS_NODE_STYLE_PROPERTY(CSSJustify, JustifyContent, justifyContent); +CSS_NODE_STYLE_PROPERTY(CSSAlign, AlignContent, alignContent); +CSS_NODE_STYLE_PROPERTY(CSSAlign, AlignItems, alignItems); +CSS_NODE_STYLE_PROPERTY(CSSAlign, AlignSelf, alignSelf); +CSS_NODE_STYLE_PROPERTY(CSSPositionType, PositionType, positionType); +CSS_NODE_STYLE_PROPERTY(CSSWrapType, FlexWrap, flexWrap); +CSS_NODE_STYLE_PROPERTY(CSSOverflow, Overflow, overflow); +CSS_NODE_STYLE_PROPERTY(float, Flex, flex); + +CSS_NODE_STYLE_PROPERTY(float, PositionLeft, positionLeft); +CSS_NODE_STYLE_PROPERTY(float, PositionTop, positionTop); +CSS_NODE_STYLE_PROPERTY(float, PositionRight, positionRight); +CSS_NODE_STYLE_PROPERTY(float, PositionBottom, positionBottom); + +CSS_NODE_STYLE_PROPERTY(float, MarginLeft, marginLeft); +CSS_NODE_STYLE_PROPERTY(float, MarginTop, marginTop); +CSS_NODE_STYLE_PROPERTY(float, MarginRight, marginRight); +CSS_NODE_STYLE_PROPERTY(float, MarginBottom, marginBottom); +CSS_NODE_STYLE_PROPERTY(float, MarginStart, marginStart); +CSS_NODE_STYLE_PROPERTY(float, MarginEnd, marginEnd); + +CSS_NODE_STYLE_PROPERTY(float, PaddingLeft, paddingLeft); +CSS_NODE_STYLE_PROPERTY(float, PaddingTop, paddingTop); +CSS_NODE_STYLE_PROPERTY(float, PaddingRight, paddingRight); +CSS_NODE_STYLE_PROPERTY(float, PaddingBottom, paddingBottom); +CSS_NODE_STYLE_PROPERTY(float, PaddingStart, paddingStart); +CSS_NODE_STYLE_PROPERTY(float, PaddingEnd, paddingEnd); + +CSS_NODE_STYLE_PROPERTY(float, BorderLeft, borderLeft); +CSS_NODE_STYLE_PROPERTY(float, BorderTop, borderTop); +CSS_NODE_STYLE_PROPERTY(float, BorderRight, borderRight); +CSS_NODE_STYLE_PROPERTY(float, BorderBottom, borderBottom); +CSS_NODE_STYLE_PROPERTY(float, BorderStart, borderStart); +CSS_NODE_STYLE_PROPERTY(float, BorderEnd, borderEnd); + +CSS_NODE_STYLE_PROPERTY(float, Width, width); +CSS_NODE_STYLE_PROPERTY(float, Height, height); +CSS_NODE_STYLE_PROPERTY(float, MinWidth, minWidth); +CSS_NODE_STYLE_PROPERTY(float, MinHeight, minHeight); +CSS_NODE_STYLE_PROPERTY(float, MaxWidth, maxWidth); +CSS_NODE_STYLE_PROPERTY(float, MaxHeight, maxHeight); + +CSS_NODE_LAYOUT_PROPERTY(float, Left); +CSS_NODE_LAYOUT_PROPERTY(float, Top); +CSS_NODE_LAYOUT_PROPERTY(float, Right); +CSS_NODE_LAYOUT_PROPERTY(float, Bottom); +CSS_NODE_LAYOUT_PROPERTY(float, Width); +CSS_NODE_LAYOUT_PROPERTY(float, Height); + +CSS_EXTERN_C_END + +#endif diff --git a/java/csharp/Facebook.CSSLayout/CSSAlign.cs b/CSSLayout/CSSMacros.h similarity index 50% rename from java/csharp/Facebook.CSSLayout/CSSAlign.cs rename to CSSLayout/CSSMacros.h index eb964247..a2fc8e37 100644 --- a/java/csharp/Facebook.CSSLayout/CSSAlign.cs +++ b/CSSLayout/CSSMacros.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2014, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the @@ -7,14 +7,15 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -namespace Facebook.CSSLayout -{ - public enum CSSAlign - { - Auto, - FlexStart, - Center, - FlexEnd, - Stretch, - } -} +#ifndef __CSS_MACROS_H +#define __CSS_MACROS_H + +#ifdef __cplusplus +# define CSS_EXTERN_C_BEGIN extern "C" { +# define CSS_EXTERN_C_END } +#else +# define CSS_EXTERN_C_BEGIN +# define CSS_EXTERN_C_END +#endif + +#endif diff --git a/CSSLayout/CSSNodeList.c b/CSSLayout/CSSNodeList.c new file mode 100644 index 00000000..4baf95ee --- /dev/null +++ b/CSSLayout/CSSNodeList.c @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#include +#include +#include + +#include "CSSNodeList.h" + +struct CSSNodeList { + int capacity; + int count; + void **items; +}; + +CSSNodeListRef CSSNodeListNew(unsigned int initialCapacity) { + CSSNodeListRef list = malloc(sizeof(struct CSSNodeList)); + assert(list != NULL); + + list->capacity = initialCapacity; + list->count = 0; + list->items = malloc(sizeof(void*) * list->capacity); + assert(list->items != NULL); + + return list; +} + +void CSSNodeListFree(CSSNodeListRef list) { + free(list); +} + +unsigned int CSSNodeListCount(CSSNodeListRef list) { + return list->count; +} + +void CSSNodeListAdd(CSSNodeListRef list, CSSNodeRef node) { + CSSNodeListInsert(list, node, list->count); +} + +void CSSNodeListInsert(CSSNodeListRef list, CSSNodeRef node, unsigned int index) { + if (list->count == list->capacity) { + list->capacity *= 2; + list->items = realloc(list->items, sizeof(void*) * list->capacity); + assert(list->items != NULL); + } + + for (unsigned int i = list->count; i > index; i--) { + list->items[i] = list->items[i - 1]; + } + + list->count++; + list->items[index] = node; +} + +CSSNodeRef CSSNodeListRemove(CSSNodeListRef list, unsigned int index) { + CSSNodeRef removed = list->items[index]; + list->items[index] = NULL; + + for (unsigned int i = index; i < list->count - 1; i++) { + list->items[i] = list->items[i + 1]; + list->items[i + 1] = NULL; + } + + list->count--; + return removed; +} + +CSSNodeRef CSSNodeListDelete(CSSNodeListRef list, CSSNodeRef node) { + for (unsigned int i = 0; i < list->count; i++) { + if (list->items[i] == node) { + return CSSNodeListRemove(list, i); + } + } + + return NULL; +} + +CSSNodeRef CSSNodeListGet(CSSNodeListRef list, unsigned int index) { + return list->items[index]; +} diff --git a/CSSLayout/CSSNodeList.h b/CSSLayout/CSSNodeList.h new file mode 100644 index 00000000..e59a30f5 --- /dev/null +++ b/CSSLayout/CSSNodeList.h @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#ifndef __CSS_NODE_LIST_H +#define __CSS_NODE_LIST_H + +#include + +CSS_EXTERN_C_BEGIN + +typedef struct CSSNodeList * CSSNodeListRef; + +CSSNodeListRef CSSNodeListNew(unsigned int initialCapacity); +void CSSNodeListFree(CSSNodeListRef list); +unsigned int CSSNodeListCount(CSSNodeListRef list); +void CSSNodeListAdd(CSSNodeListRef list, CSSNodeRef node); +void CSSNodeListInsert(CSSNodeListRef list, CSSNodeRef node, unsigned int index); +CSSNodeRef CSSNodeListRemove(CSSNodeListRef list, unsigned int index); +CSSNodeRef CSSNodeListDelete(CSSNodeListRef list, CSSNodeRef node); +CSSNodeRef CSSNodeListGet(CSSNodeListRef list, unsigned int index); + +CSS_EXTERN_C_END + +#endif diff --git a/Gruntfile.js b/Gruntfile.js deleted file mode 100644 index 69432cb9..00000000 --- a/Gruntfile.js +++ /dev/null @@ -1,198 +0,0 @@ -'use strict'; - -module.exports = function(grunt) { - var path = require('path'); - var isWindows = (/^win/).test(process.platform); - - require('load-grunt-tasks')(grunt); - - // config - var config = { - delimiter: path.delimiter, - libName: 'css-layout', - distFolder: 'dist', - srcFolder: 'src', - testFolder: 'src/__tests__', - javaLibFolder: 'src/java/lib', - javaSource: 'src/java/tests/com/facebook/csslayout/*.java', - javaTestFiles: 'org.junit.runner.JUnitCore com.facebook.csslayout.LayoutEngineTest com.facebook.csslayout.LayoutCachingTest com.facebook.csslayout.CSSNodeTest' - }; - - // C compilation configuration - if (isWindows) { - // Windows build, assumes cl is in the path (see https://msdn.microsoft.com/en-us/library/f2ccy3wt.aspx). - config.cTestOutput = 'c_test.exe'; - config.cTestCompile = 'cl -nologo -Zi -Tpsrc/__tests__/Layout-test.c -Tpsrc/Layout.c -Tpsrc/Layout-test-utils.c -link -incremental:no -out:"<%= config.cTestOutput %>"'; - config.cTestExecute = '<%= config.cTestOutput %>'; - config.cTestClean = ['<%= config.cTestOutput %>', '*.obj', '*.pdb']; - } else { - // GCC build (OSX, Linux, ...), assumes gcc is in the path. - config.cTestOutput = 'c_test'; - config.cTestCompile = 'gcc -std=c99 -Werror -Wno-padded src/__tests__/Layout-test.c src/Layout.c src/Layout-test-utils.c -lm -o "./<%= config.cTestOutput %>"'; - config.cTestExecute = './<%= config.cTestOutput %>'; - config.cTestClean = ['<%= config.cTestOutput %>']; - } - - grunt.initConfig({ - config: config, - - mkdir: { - dist: { - options: { - create: ['<%= config.distFolder %>'] - } - } - }, - - clean: { - dist: ['<%= config.distFolder %>/css-layout.*'], - cTest: config.cTestClean, - javaTest: ['**/*.class'] - }, - - eslint: { - options: { - configFile: '.eslintrc' - }, - target: ['<%= config.srcFolder %>/**/*.js', './Gruntfile.js'] - }, - - includereplace: { - options: { - prefix: '// @@' - }, - main: { - src: '<%= config.srcFolder %>/<%= config.libName %>.js', - dest: '<%= config.distFolder %>/<%= config.libName %>.js' - } - }, - - uglify: { - options: { - sourceMap: true, - sourceMapIncludeSources: true - }, - main: { - files: { - '<%= config.distFolder %>/<%= config.libName %>.min.js': - ['<%= config.distFolder %>/<%= config.libName %>.js'] - } - } - }, - - karma: { - main: { - options: { - files: [ - '<%= config.srcFolder %>/Layout.js', - '<%= config.srcFolder %>/Layout-test-utils.js', - '<%= config.testFolder %>/Layout-test.js', - '<%= config.testFolder %>/Layout-consts-test.js' - ], - browsers: ['Chrome'], - frameworks: ['jasmine'], - singleRun: true - } - } - }, - - execute: { - transpile: { - src: ['<%= config.srcFolder %>/transpile.js'] - } - }, - - concat: { - options: { - separator: '\n', - // Replace all 'use strict' statements in the code with a single one at the top - banner: [ - '/*', - ' * #define CSS_LAYOUT_IMPLEMENTATION', - ' * before you include this file in *one* C or C++ file to create the implementation.', - ' */\n' - ].join('\n'), - process: function(src, filepath) { - if (path.extname(filepath) === '.c') { - return [ - '#ifdef CSS_LAYOUT_IMPLEMENTATION', - src, - '#endif // CSS_LAYOUT_IMPLEMENTATION' - ].join('\n'); - } else { - return src; - } - } - }, - dist: { - src: ['<%= config.srcFolder %>/Layout.h', '<%= config.srcFolder %>/Layout.c'], - dest: '<%= config.distFolder %>/css-layout.h' - } - }, - - shell: { - cCompile: { - command: config.cTestCompile - }, - cTestExecute: { - command: config.cTestExecute - }, - javaCompile: { - command: 'javac -cp <%= config.javaLibFolder %>/junit4.jar<%= config.delimiter %><%= config.javaLibFolder %>/jsr305.jar<%= config.delimiter %><%= config.javaLibFolder %>/infer-annotations-1.4.jar' + ' -sourcepath ./src/java/src<%= config.delimiter %>./src/java/tests' + ' <%= config.javaSource %>' - }, - javaTestExecute: { - command: 'java -cp ./src/java/src<%= config.delimiter %>./src/java/tests<%= config.delimiter %><%= config.javaLibFolder %>/junit4.jar<%= config.delimiter %><%= config.javaLibFolder %>/infer-annotations-1.4.jar <%= config.javaTestFiles %>' - }, - javaPackage: { - command: 'jar cf <%= config.distFolder %>/<%= config.libName %>.jar <%= config.javaSource %>' - }, - csharpCompile: { - command: 'xbuild /verbosity:m /nologo src/csharp/Facebook.CSSLayout.sln /p:Configuration=Release /t:"Facebook_CSSLayout:Rebuild;Facebook_CSSLayout_Tests:Rebuild"' - }, - csharpTestExecute: { - command: 'nunit-console -nologo src/csharp/Facebook.CSSLayout.Tests/bin/Release/Facebook.CSSLayout.Tests.dll' - } - }, - - watch: { - files: ['src/Layout.js'], - tasks: ['ci'] - } - }); - - // Compiles and runs the Java tests - grunt.registerTask('test-java', ['shell:javaCompile', 'shell:javaTestExecute', 'clean:javaTest']); - - // Compiles and runs the CSharp tests - grunt.registerTask('test-csharp', ['shell:csharpCompile', 'shell:csharpTestExecute']); - - // Compiles and runs the C tests - grunt.registerTask('test-c', ['shell:cCompile', 'shell:cTestExecute', 'clean:cTest']); - - // Transpiles the JavaScript to C and Java, running tests - grunt.registerTask('transpile', ['execute:transpile', 'test-c', 'test-java', 'test-csharp']); - - // Lints and tests the JavaScritp using Chrome - grunt.registerTask('test-javascript', ['eslint', 'karma']); - - // Packages the JavaScript as a single UMD module and minifies - grunt.registerTask('package-javascript', ['includereplace', 'uglify']); - - // Packages the Java as a JAR - grunt.registerTask('package-java', ['shell:javaPackage']); - - // Packages the C code as a single header - grunt.registerTask('package-c', ['concat']); - - // Packages all languages - grunt.registerTask('package-all', ['package-javascript', 'package-java', 'package-c']); - - // Default build, performs the full works! - grunt.registerTask('build', ['test-javascript', 'transpile', 'clean:dist', 'mkdir:dist', 'package-all']); - - // The JavaScript unit tests require Chrome (they need a faithful flexbox implementation - // to test against), so under CI this step is skipped. - grunt.registerTask('ci', ['eslint', 'transpile', 'clean:dist', 'mkdir:dist', 'package-all']); - - grunt.registerTask('default', ['build']); -}; diff --git a/LICENSE b/LICENSE index 662b6f76..864c3963 100644 --- a/LICENSE +++ b/LICENSE @@ -2,7 +2,7 @@ BSD License For css-layout software -Copyright (c) 2014, Facebook, Inc. All rights reserved. +Copyright (c) 2014-present, Facebook, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/README b/README new file mode 100644 index 00000000..9fbacf65 --- /dev/null +++ b/README @@ -0,0 +1,9 @@ +# CSSLayout [![Build Status](https://travis-ci.org/facebook/css-layout.svg?branch=master)](https://travis-ci.org/facebook/css-layout) + +``` +css-layout is currently in the process of big changes. If you are looking at using the latest stable version please have a look at the `deprecated` branch. This includes a js version and a C-sharp version not currently available on master. +``` + +CSSLayout is a cross platform implementation of the flexbox specification. CSSLayout targets native mobile development and is therefor disconnected from the web browser. CSSLayout is implemented in C for portability reasons and uses JNI to expose public methods to Java. + +See CSSLayout/CSSLayout.h for a look at the public API being exposed. diff --git a/README.md b/README.md deleted file mode 100644 index 6c0dedf6..00000000 --- a/README.md +++ /dev/null @@ -1,157 +0,0 @@ -css-layout [![Build Status](https://travis-ci.org/facebook/css-layout.svg?branch=master)](https://travis-ci.org/facebook/css-layout) -========== - -This project implements a subset of CSS including flexbox and the box model using pure JavaScript, then transpiled to C, Java and C#. The goal is to have a small standalone library to layout elements. It doesn't rely on the DOM at all. - -The Java, C and JavaScript version of the code is available via [npm](https://www.npmjs.com/package/css-layout) or directly from the `dist` folder of this repo. The JavaScript version is also available via [cdnjs](https://cdnjs.com/libraries/css-layout). - -In order to make sure that the code is correct, it is developed in JavaScript using TDD where each commit adds a unit test and the associated code to make it work. All the unit tests are tested against Chrome's implementation of CSS. - -The JavaScript version has been implemented in a way that can be easily transpiled to C and Java via regexes. The layout function doesn't do any allocation nor uses any of the dynamic aspects of JavaScript. The tests are also transpiled to make sure that the implementations are correct everywhere. - - -Usage ------ - -A single function `computeLayout` is exposed that - - takes a tree of nodes: `{ style: { ... }, children: [ nodes ] }` - - computes the layout and writes it back to the node tree. - -For example, - -```javascript -// create an initial tree of nodes -var nodeTree = { - "style": { - "padding": 50 - }, - "children": [ - { - "style": { - "padding": 10, - "alignSelf": "stretch" - } - } - ] - }; - -// compute the layout -computeLayout(nodeTree); - -// the layout information is written back to the node tree, with -// each node now having a layout property: - -// JSON.stringify(nodeTree, null, 2); -{ - "style": { - "padding": 50 - }, - "children": [ - { - "style": { - "padding": 10, - "alignSelf": "stretch" - }, - "layout": { - "width": 20, - "height": 20, - "top": 50, - "left": 50, - "right": 50, - "bottom": 50, - "direction": "ltr" - }, - "children": [], - "lineIndex": 0 - } - ], - "layout": { - "width": 120, - "height": 120, - "top": 0, - "left": 0, - "right": 0, - "bottom": 0, - "direction": "ltr" - } -} -``` - -Supported Attributes --------------------- - -Name | Value -----:|------ -width, height | positive number -minWidth, minHeight | positive number -maxWidth, maxHeight | positive number -left, right, top, bottom | number -margin, marginLeft, marginRight, marginTop, marginBottom | number -padding, paddingLeft, paddingRight, paddingTop, paddingBottom | positive number -borderWidth, borderLeftWidth, borderRightWidth, borderTopWidth, borderBottomWidth | positive number -flexDirection | 'column', 'row' -justifyContent | 'flex-start', 'center', 'flex-end', 'space-between', 'space-around' -alignItems, alignSelf | 'flex-start', 'center', 'flex-end', 'stretch' -flex | number -flexWrap | 'wrap', 'nowrap' -position | 'relative', 'absolute' -overflow | 'visible', 'hidden' - -- Rather than allowing arbitrary combinations of `flex-grow`, `flex-shrink`, and `flex-basis` the implementation only supports a few common combinations expressed as a single number using the `flex` attribute: - - css-layout `flex` value | W3C `flex` short-hand equivalent - ---|--- - n (where n > 0) | n 0 0 - 0 | 0 0 auto - -1 | 0 1 auto - -- `inherit` value is not implemented because it's a way to disambiguate between multiple colliding rules. This should be done in a pre-processing step, not in the actual layout algorithm. - - - -Default values --------------- -Since we are only using flexbox, we can use defaults that are much more sensible. This is the configuration to use in order to get the same behavior using the DOM and CSS. You can try those default settings with the [following JSFiddle](http://jsfiddle.net/vjeux/y11txxv9/). - -```css -div, span { - box-sizing: border-box; - position: relative; - - display: flex; - flex-direction: column; - align-items: stretch; - flex-shrink: 0; - align-content: flex-start; - - border: 0 solid black; - margin: 0; - padding: 0; - min-width: 0; -} -``` - -- `box-sizing: border-box` is the most convenient way to express the relation between `width` and `borderWidth`. -- Everything is `display: flex` by default. All the behaviors of `block` and `inline-block` can be expressed in term of `flex` but not the opposite. -- All the flex elements are oriented from top to bottom, left to right and do not shrink. This is how things are laid out using the default CSS settings and what you'd expect. -- Everything is `position: relative`. This makes `position: absolute` target the direct parent and not some parent which is either `relative` or `absolute`. If you want to position an element relative to something else, you should move it in the DOM instead of relying of CSS. It also makes `top, left, right, bottom` do something when not specifying `position: absolute`. - -Native Usage Notes ------------------- - -The C equivalent of `computeLayout` is [`layoutNode`](dist/css-layout.h#L1378). - -In order for layout to properly layout reflowable text, the `measure` function must be set on the `css_node` structure. The property can be found in [`css-layout.h`](dist/css-layout.h#L146). This function must take a void pointer to a `context` that will affect the size of the node and the `width` as computed by the layout engine, and must return a `css_dim_t` structure defining the actual needed size of the node. For the most part, the `context` field can be the text inside the node. No C implementation of this function is provided in provided - it depends on your use of css-layout. However an implementation of the function in JavaScript can be used for reference in the [test utilities](src/Layout-test-utils.js#L383). - -Development ------------ - -The core logic resides with `Layout.js`, which is transpiled into equivalent C and Java implementations. - -The JavaScript build process is managed via Grunt. The build performs linting, runs the tests against Chrome, transpiles and packages the code (JavaScript and Java) into the `dist` folder. For JavaScript, the build output uses the Universal Module Format (UMD) so that it can be used via AMD / RequireJS, CommonJS or included directly into an HTML page. - -While developing you can just run the lint / Chrome-based tests a follows: - -``` -grunt test-javascript -``` diff --git a/TestResult.xml b/TestResult.xml deleted file mode 100644 index a2bb5a16..00000000 --- a/TestResult.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/dist/README.md b/dist/README.md deleted file mode 100644 index 5be886d2..00000000 --- a/dist/README.md +++ /dev/null @@ -1,20 +0,0 @@ -Releases can be found on [npm](https://www.npmjs.com/package/css-layout). - -#Release Process - -```bash -# Ensure that the local codebase is up to date -git fetch upstream master && git checkout FETCH_HEAD - -# build the latest version of the library -grunt - -# increment the version number and tag the release -npm version [ | major | minor | patch | premajor | preminor | prepatch | prerelease] - -# push the the commit and tag back to upstream -git push --tags upstream HEAD:master - -# publish this new version to npm -npm publish -``` diff --git a/dist/css-layout.jar b/dist/css-layout.jar deleted file mode 100644 index 0e00efe75bcda0b4c0c7f8a4a818a5942a7cfd57..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16324 zcmbWe1C%9AwC`EAZQFL2ZM&+=wr$&1mu=g&jV{~Pbbs&7z2Chvv(|kR|8>^MTxUn_ z%#%AJc4ov+UJ4il1pop90zldML>%B>1rh)RKt@DafL20Ql>TcR000<3UJ4xIuLaQm zHk1GVtc>!<;y)_O2*^r^iYO`5$%x*|OioBk(bCPqO3_kHPtG(bGAuIh9y-uT%Fsy2 z%sH2XK&qc$4r*ahnZ2Nsk{uUPaU7$g9-xz^03=)9Iovt`{&NzqPtc!2e_ROv`TXZe zeAEs6mn&fV^Q)tSA-#pZi$1-Rv7?hCy`il&y@|e|v4O3vCB31eqm{n9t+Nxokdl(D zt&y?v9~-*A)=i09G3yKn!PoaFj+pXTK8xJS<_j!Uahi>acR<5<0g-h|8^0n|J3TK4 zt@O}URf>+t^pEa2_tW*6@WdEGv{}Wb&Z~mcV)S^ky`^`lf3>Pwr1mP#FDj)Y%qoDf zU@d|h@m?t{rC>9ZFQNETh3xu3$tqwO%}Rz~U7+nbz8(hFiTNLsSS3vWrSe_|chlb+ zsG!yE!JQ4{CD-@1idrP|2CTQ9=$Wz_K&6B9W3*^X5alfkYtkRDhNve!X>*VwEw41+ zq^S&*Q`PXmuI=xh)^LVn3Az?Op>LLC&SocJ5sxY~xgd&o?NC??oN|4xN!lzxO^Ix( z8*p}sn+`kA6&HG<_Gl7K{=VK-p$a8{U!_xDVWQ0C(4@-b9i8b>(uo4y)YS zaGb;kG@}4=v&*-|Ee}3~sg6F5G0~!3Yioud?m`LWIUVMRqzZ3Cs_l> z5qT=pd5qNRTsNV~dbI=yUiCeT<+m`AW$0zGDOrF&rU+3PPO+7*e=A&f>zmWKkuVqS zJsO^LW=u`>Sb&nSGho)r0qg<@*^Iiq6%97va8RkdjNp_n)}x@|>x700aO4 z2mN`XAACscvoin*-r%x+X2QaiZu~yKPr;ilKm3 znXP8rQ$r@qU}&9VGjOEp$1^s!1SBosc=BcQx+HD%aXR`8Pfipk_Ydn{N+*@}S+6X0 zGf{FoyykB!fm{){n#DrUR3<2#a$*p-B*18}M;ODFE8&44YzC?YM8QG>5Dyd{L34%> z>EY5oG6-LI-f#U2K|RW#cp^%>)4}Q4CF2%X=99iKWQw0)RY}2VmQj`S(DKBZI&BSD zjD9g7Xd{~rr0ITjCi7g5K{Dwg<`ccdWP3haw42T$U734&QziOJ+OJL&wCB3q?Y$ao}py(n}9bsn@fQ=hn+$Ff~bjo0jYVwstZJrXKh=9TTD z-X*!^rer#vo7J#@h1X~*@mrfTpF3J^$ClQu$;ktEqKimJKv+JdA#6(@MBXXW@(YKq zn|HNeAL1d{e1WK3)ntaD&QkD*^X)=AyQF%i17;waqL_#kRs(8fmu&<(;zah^Rm)lw zqte2d1d=Gino`pHC1Js33G5NXn#eYgeh7nwBpmqt*DyljAJ76 z6vsuAud!Rmxa%5P$Xth-qYlzxUvgo~vNM>0Umd$+*D zHp6p+dCt8{5QxNy9q{^(p4&hidf!)=<2HqsdBZfZV|zRio{w31l&DCCpl=0@F=jkF zuIskcT#K3cYH|m}9s&%FPJw+9=FPdTzH7p|q|OYKcA;Cgq@Q-s{hYWkMXskuY3RXx zU61NC$)LlS0^D*mdxEd__#_lT?gr$wv2J{yugkK>CB8m6BdPM8>*nUY%3+IPVruj~ z>Xm1w!i^scMRLkrxIs$nH4Q!zRe|`P^_iIVG!KD(R|C*_ot0I}QG`iYY@F6Q; zAM18y@Z&A#H>MZRaW3s{VP4D_QRh)R=b384>-I^0C;=sQ-SKO)Ecx<0?SE<#dRaP$ zqPZ>EgQWX8?LYKpZL%<#!h2t$l2%Ix(Me2&f!h#?C4Lpia10+;^sUWX0o8LP-);2) z{&%=F2{0O@0098-#`<@Ur1;;)YVQBT9!bQ;)ZFGjhr3H}OUI4Ygs0~ZC>!1^2M4QY zN{!~ki;HSQ>cp%&Qe#UtrKXOauWJKoYv> zV{?{v?4B;~cS+BR?DYxs5ihrg#_Tn0>((0l3ya(+%=U)M>yCAFOEw6}Y#KC8_3)*^I8+!yIui%q?XKtb^9TZcw=Io_61RTT3 z+S*JP>~!mHd8PZbwRir=^~&(ktNzjTHm>{nHi4hZx&3)-!PV8CSMB?B*pD8$3%Jvr zCBx^q_{|f}b#vAt{t%dM=k0FS`286hZ0^01kA-~R*Em~awyowGxl0N?;M~#;cV_YZ zewJKJi+dkRZz|z=HN_A0x$^VPQs2%W#`Q2yj@lA!wB!ivu^#{HijVZAZq`v@D4Tt5 zg5{F0+J|6-@tER++GYoSBg;}wAvya6G2`&tR;}abYDmeCOvh_`b~lfY-N-!Qms64Q zRbr?V$!hHfdu4{N4~s)uHQl@ElbXC}1-SrSvZQyP^SR!M&~*=v)?#;6 zdvvyGCgYhz930J@hwmhu9&el@<8#`Ek|w^;7bdDR3E)FT8i!m|u}M#T z7Mo&w?OMxy^jD#yvQfQ}uH>J!bVB<;=*Ce#OO0mfW=YHO?fCp?dqRbeuV~1t({u?5 z!`Eho31Sjqac?WT$HRT+G#WflK1`Q0yK@XlAw=!|8d!l;TXvoBX%=*GujyL;sx~e$ zhz3^h4E+9n^CP?n+gOM?R1;m^lxgMA-%hi%*vjOa zn<=VU%XcrFBAL=SmnyOELDTa6%%LFH3U>M39Bhj*88u|pbd!meytd{cs67wS^t;rL z8*+Jky1mPuoB8rxe%bctHT=k!fT{t4U*L~^@bXUMz=#Z z|JM`sdysQ1dv=$UNBUy=M&I$3={|V-t*eQ`XVWxJ^O;g!Cs{PsAh%!9Wr%10_xd{5 z=S;PWn!@ksr(!``cHaM3oeFS@hAxtU=ffa-Y?eSgEALv7rq|^{bA!*W;~H9^ zcv*Pc##p8V*d@)3eew{GO8et0jCI|c!yb!3{(|M}m73e<;`OPA0}qe)kpqX{)P9M~ zmsLH;kFGv|7oF?d_n^JL7OiH!$I;(159KTfU{8r!)a%}danxs=HZy38ty|CMmFMII zDBjFr2tC3e1(!hXRqFX476XOrHEJ(cGzK7g*YXBUYZlt4?Xba#wO$ZJL#Srp(R#QB zqO^+;x*f4k7L2iN+RQ8~Vh33TXde(Ve(lE}fLva#t z3y;d};5%jYv0|;>B?99H?=vrho@+JwMKSMv<)9{2q!%GC<{w{eC z3tXtU=cA{yts(#BZ0k<4IdI1nXG4n*p|3U!bdT+LR11L{Es|KyK} zU=Bj0vPor|3Um6whQ4(}bORGRU0 z7zHQ3l2YT&Flg-A#W0G9;0drY2@Npb!o;ISn}$`|F$ozJ?PC&A<4hwIQ=I;4XJRf) ztRbw=cMl>-BdniyPpZuLrK~_&g$-*#x#h&0zq6y%KATi6`kS$GqMOm^w(Hl!FLOH( zjLulmP#C7Xi6p>?%NFd5rs&{O;zD8$!2lT$DcCiIMGC5w@NO>PJu{Jeg&Y06)=ow3B#Z@B(pVS1Jt9_XLUZx$_S;&3Gws& zm82xitlZ3rX+t2?-38c5RaFaKr^K!iDRHI#F-Q{V9~Bi2F8i%rt21^`7do%%&O^ca zZU>}xC{OBf0T}=o#PP!ri|S%TcZfji5P?n>SYrEuN$gES*ks;o=y}6E7`+75y2H}b zJF$Y2*+KtNB!SJGMkj6iAl>HynmsQ#my!GhcuSC{S`T37)D>f(-&%Pj%>2PukT*a~ zy4TWIn?u*E#n1#&9Gy%NDy%fHbV0th>RU()kOg<0R{SsvPzzav32S*U!vh#ZAbOe- zQm|BIiY|Pn>|&xB(@wH9V8*mwJM-q%v`Z+14wm=o8}A#<>0)iGlEhqsjd8@Rvz4PG zTVYXUtjf7gr(`@-1FSUSOCHAL8Q10*M8iaKp3PibIe>w3pq36acjuag6R@;$hg%r+ zZlkscRNvN4TQ$zghkt9=l`|*g$$AI5t>n;eIn-@Nk!W-Nw}Kl+IQY_-Jg$HR>#w0{Dm?EjAmaG0jng!FOELi*04|kIh zLw&MpZ0Ya=>B&BW3_u0Lu~n-HuWnxfqJ7yog4H0ihekK%p%P#anExn!BmAKCI?79V zvO3$)$e&w>(>wxb1mpheaIu-k$Q_aUoA}M@=G5zM#X3zu1&Q1>S3rfBo)og|kj=?1 zH?{4DRj?d6HoCRp^ZP7J$MGA?p}oVLylg)aBDTnG1MMv^uT&M;ZUfwnhJ+*$E1(Wb zK@+j0082smh8gUk5lcBq@z^2eEYcq(Bp_{YDx=9rRqY$=Y6>oArG~F(3PG;Ykb3l* zlqG{$Ed#PyW-m#zWHwd41GP%;f=S6v7c)t=zj`=uwS97=`(#Sf`KS8*QBu-sOdr!l z-KzVT4i!39M2)&=B4cizFrGVL=aV}Dhj&=~-*Q?NLBaWV{KyJu17P2ec~T_9$} z%X3Gjj4>ursz);kejXW`vnk%i3;7ko0`ZcwC!L?Cmnfl!f7?QzGfOH48n;{m_vjJ0 z4y5!Jbzt-ZL7xH$4H#{rhET5#u2wxUXGZc){d`{3?mmr!c}`sR4TJ}`FC0`JQ9iyO zNoydad~kS2kjh|P5f^2LFP{z*lG7c3Y|KG^Cj<%u=8vTH!>f#$muTS(*JYd120(0z z4+_O8>MjMqI0=Xeh*e0NLoSse-CE)z(wdb>QL5=sA;&|w5)udUj*zMJ82{>zO$x0_ zi(8br)RF}ra%)*aA_(9~DX0^Q>^!XICi;e+f3IJ!9yVBsCh7xffcWp4t73}i)UE>~ z4nJ5-27{VKudhlTS@mYzG$ci`u#X*NW;)!BMH3sph>-YoQ zy+KU3Gy$3aXYLW49k|^JeXHe*EWnx{xvUJg8O>rhf}@k0G_`}G*ff-sTspQSLS!~ z&uGn}Aen#n2FNj+VV7icdTu5r>ss>nSizp}xJCx{Tqv%Y%_$m?_^BgIyCS$4G6m5V zZH9|>j=AH#_UJy=z-q|Wp!NlXYRGkcMC#(F=BFk(Y09em2we?Qz8uY|IdLaI7Fjsh zC?{u|x{{nL686Q_-dWx^SLn-f2kcs zg3_@k404pu*H(Y{Z%33h{&-C#iGI+54Cs3GMyeagJg`3!MO%c}3}V644eG4vK6$CA zWALkMH6rt=Yt^Iks%tgl^{8vLqI0WjJyE?N0)X+JBvJq?G-f&LjLf@bh~cFJ8hx1$ zP$?m*aivt`0M{X`z*c|&rjKI9%L8B_b0r6sz;A~+j4Fwv!WXP>9WCz=qXu=1pQech zMU-%ko!ZuqXCx?M1eW9G!sDu&6jDb!Mo`qoI)_)(#yN&l)aE*e1sWAst-u{!1$vGm zq-Tm48|Ss*nJkl^+9F?el#nDlLzh@0)mNrJm0K_2t`K$k8P9(MK zcSWEi4Stm#=t6y5!KchU-{W_cKk*x)ylQwX2l;qo%}%j*belE)e5*Awnk++l?F&{C zt13wXtL@rp$tjO4ta?xu#d9v z&oK7NRNhf^Yho@dnqA5@?jROnI}jxWpZ7R1MypAefREj9FzoYjgT{EC8Ql=Y7XIhX ztIALZI!ww51c&>_11ASh2k%F6%M^rpYaSe9>TBkjJBg<`J+Ga#`PqZl5n?8MysoXw zZ0$H7+Znry_hRW$+5AOpQppV-jC7RteP{utvox+rGP?eY+v%fiM#}njP#f7c06P{{EsCLqBku<{<%VUzw#LeGFGFVU0)L^qqE=9(eP}V&s z?^Md3fyi=?l=-fDJ*Qe7FNenWqlGxFCP9BL`@=E=qvp8yC6d&{l;%h0N%=ow_ll=? z+^-VSg+0|WqPrDMdoMf#gn{G`?W7VCz!SiO-mF|@ z-*Xr<=N~VAl{4kO>*I&m;Rp!cujqYg(Jm#OzmL2;@+Ci zVsin$|0A>UMtF%1%$NqBx|>`n_v!qEJc3ZO78+Eez@$`ZI;^Z zwjoRFD5IqXy*pt^-Dud8kgUCj+^owRI2Y~?Yxhhk8|5P6ZjRleo5S<^{!%CtERVLl zn!Y&TY`zP((&}O;V_{hZO*s2wQ|Z0(@p@+ISG^7uy#;&Dgzl=fy5GlNT>|p)`_zrn zUpdqhbH<~v9x8HB{j6i6Gb*m-f56C#J-a!y&KB{%y*aqS)e+&1f&%4X!hfM4At`(i zSCyVZ11Rb>^?)l?3DV>wSM;Opx6lcu6&;e~wF;>5n7mqdBDgajHQVxL}EPWesK)MI+ZrJBu)dt)am{UvNZr#-h`+QZO-U81% zp4bPheE~o$1q*_z^;c#?;Rgv=^x{m-P}X6gz%QoObQ{gY2CO#Ub<#+rB0k$ite8Oy z1yFOwyEi**pK-3X_~xJf?Dshu+LqP1a-`U43Zy^5N5EuH{k?e5&EYBTPcnyyJmTkRmBb_*ufZe%RPv7E9x-DUHF+IUJyo^~y>Q2#A(x#~BinP_? z$epYck_+R(R-oEtn{?K#7eTk4y>w+7R^iv|rGI~47FMegcOlx1HI!=e3tOUDG`a&; z>>Z_^PIjC#K9{VzA{WJonQo5ic@5u6K>1_X5e>O*} zm8GcM;t9x-Yop-hB;5jvt!^1t6>WdldxU4V0Izf7;0DZeS?6BOQ9`oS6S^4R_8MI>-a+zyc$PsW5H=c&WPJ% z$w!g=^{z{Z_T7u@EdG=`#%*kgO>V^1!Z#Q^>D4*f6FuP=vP5n5lfIite2R92cy!_e zVUb!6dgW`YA^<4fBfV=31k$E>AmLvkNm#BSv0qoV{%jmbo=c%{Pn04?Rkb&QQ8Z%j zU^wMeQ?69}ii>3YB>aVP8=>e`A|#Bw3fEZAg3qaBOq;U6$W z)J+lg{^r~s&f~RN2gi#PFbOq&2Mq!2B?l$5UTVzvG#ijhTOP}SAT3-73id>AbT9fy z^U5+zLJhdkM{jM;{f+sMDFu-c7z92nG)-8GI2(d(N6V;?syZT;lJ~rE>nltuiM98o z%PJo$yZ5OL4P(XvxDHf9(s4OCc@HT1Waj@XZDL~Zm}4OY#U!)PNwzDO+$fwdU#L+# z_4S0@r*z8$x-D?{8QmSk6;0vIqj<`9r;As}p}OQfS%8WIAQBfVm{NYO2ga-w?lvK% z-lWHWy4RfIpLZSm@~b!BE7>;i{1vL?9JArtCVIViN0zh-sJ}(Fi;qDs+P#320Ro&G zK@|~?^UY`9#&c7#xpswbS?DZfKo@!&QA-=7>EN<@MlASneCgSkbb?mJ{h*|n&~a;o zQpJOLLn1=8pNxi9LD{lV>x-b08)3YYYt^XrE+sur!*KpWVU=IAv$I!=@ ziGI_Gt z+mF;H!eSCw8BHYKtq-`u7z&^Q@E=JSurkiUzI7*D9TT%!x&7pMI7rDDxpP)-eg`yW zHC@H8Q&>Kc&pD_N(kPoND6E|O1w}1GJHC!3BRMV^OAc=w&V){dVi|BB4A73$1!{ItnQ@z%)>DKlZalfBHuXZZ;8$##WgOE#MqtGRnN+ zZ@uVz;NPRKvrI_fw4GaP)Rr+v>syh{EFS{LGTwRD?0ClNe4V6C5%ra4*mYENSVfm) zl<9@+#FQPfTQZ6q65BG0Y?3=&lxt*RBgO*r_O_$RQ?iN@b00LxD8tf95~m+L$tcsZ zDC)%imQwqpC`aqRXUT3kec|;}$?Q^x?E}aRQd1NS@o;=An#sk}D*4t_CR|C9w5 zZ|n?v`9kz&YyH@O?p+RIedDp%w=bLrlQeahCRER&v}^WPJbJY=XI*wsnXt|Oe$l9x3m69< zw_`ZE!)*h2u@v@Jb>gd2i{IY$3xCx96_bB@ikt>>kXoOQ#X*K{2E!^9%8g$6fN5g{ zTB*k`>oKcKOQFN1wcJCo~^h2OJ4`wPgXuD z08Zg|<*kzzo{59pJC!X3EoF9(b7LXH)%sk*?^RDRsquX}JX*?}E_W6sjA{NQvSdaO zL=*j>2$kU~2qNiRn8aNFlqDkB4-xfb<|qb`NQ$}-v?Y!wW_E6N9}%Qm8<3OEoI?;N zxPP=w%f&}my@0O&Z+n-&UxHs-E$nk{( zE$Q0qn*#Ulfa+QycXZAWCY^Go_Vm2u9^U%Tf!lO_lRSR#Q|q&e6w2Y68G|nGrKvnn zJ3nkDCZB)IVRYO;NetOtNzX85p%Y@}ICHu~2oDATJpWbc)DN+>|>Zo^ucQa$fgW;$IofdrF+dEggbKlGBnRRv~tvK=-L1YR#2}E&CaWg z0gRCVp(@m~0Rx4jM=dZ8q2%S4AiEc}pgR$NX}xcrfInDr;i;Og|NQxUUVpT%(fuJ9 z(@+5!caUM(l|LL97e)n~DvZ~nBDoqkvTMP0Z5_f8TpwboO2Q&l@Sa%>21$FRO0Zoc zw*H(Agj5Rd&Txgb=0LP!H0Yo+L=nF^P}J|9-2laB1vS%h{6bBKy<(6sp?}gHa^I2% z>|RV&WTg_jVsn{NEF**X4royJI=u8R=Fh!`Yh+VEYqXk3lLNU}R227#j3j)GOX$TP$=HKV(S`%!)`d9iYTZYgs)a$o-cA z?#F%-=9G|}l$==dJ~#WoP{Hlla{*q};}afwjxsOtXfY&y7#U5r_WC*l{+j+y{lUPI zh@Vs=Gc4G=j+2PI19&{hv0i!VSmAJ(-l*!kZKwP(T3q+mvjRi5F?CUAAU&|%I=NoP zyID}KRq+oG%-|xXp^GtytE#9bx$*1ezbaK9)ATidERIjXKGG35vq50Y6*xow(kWqe z%Be?>e#8p|SLw2y#TMtk9-~wDeF~4sJTn&YRo`l*dkzc35}RH zWF8l|U6Y|t0uE1i)GXUW(v{U3{07s;&0F30#|Z9x?p;jC4{2F_izqnbvc9=RfH ze1bt?m1<*^HLTDH8k~d_*8CcAUPYuo8+>25LOC9Ic`~_3VS@Kpc5cA%*Yi9(fY;@@3E$;j3ag(6j5R3P5O4GP{ zc#Y_jc2F7vKbGlxezPERcF$18VhXf zDIjv&;fUn$Hl=R)^b)@mf+g!8z_F)TS3bVQTW#n@wwQ}h4(OC7&OzGrgHiL&p!7Pi zuKoBacfx!ve%MX);NVl3q!!=J;V(H@$|G;f+@cN`$x-rv(|SnaIWw?_>-|(YF-Y=O ziG^3aR}}N+S%%Cd7+w%LdMA)DZcT4c8Mg`RUI?{;UD-n(;sPK#>UnYFB#+Fvj|90tUK{keyX;)td1;4Tvn^gSWYM8vg!7yT^#tZmJy8r>HVpcMJ;(?U(&k4tq~8p1e>EvHg~+k{TY z(e&C3qWKCqwv}n=DF$ZCl-?MG2IZl`wDf(wd4xGZHn!`g_doOQ_4-COWGSequqlRE>nQfMzOYc6*MPTgA~qc0_Dxrvd~i4C~&t2NE3oL8rt4wft6Ifxi6 z%?o%w9~mI(gy;%!9ILC66?6-sI-FuN{byJT*?2ysBv{XIyN-Z$>D=IU}G^NvJ#(J^&w_;p2k{uH*#+9)T;ckrDB95 zv&Sh2h74{`b)D#x7@I%FSYhcip{phXSYDci?yj+DPb%eDl*aLxc|g0tFy_`bdnkWo zip_zEsSx=dp%!))WL7w{S|x$1h98+9+0rwNznmi}(T2d9m|#@_2T%n-rE%1OSVh;L z%8zO}g*slDkeqB=Jq>;t9sWm~=E=7!(#Mb1bX~dPlH590swKWtw1H*`G$Ixfza9&ASs00Vm9z3DP`I5r2!Hq_rIjY?{dNsX$vEd6&HRzi)rkpr2too3 z^IN|bq+O8$Vs;2v=Nh05iX__QBh5}q+o4a0(>~2l$E~SCI#}vdhs#aDj#8JaS1rC) zA(jB!FI=hnV6bWlC1e>B2N(kwgSd+D5)9Mk%!`@j)!D}N?Z{QuToN6AVICS> zbaE9%RgO$gpFy>I?iJli9{l(po@JORKhd^4_vnGF!>GWN9x>X@ntaLh0f2J>KJ|vuowD|fnX=eA&M3AQ_8fsk&$`6WdAQW>#fD&9k zB`^l#?n{goDHOFBvyIrhwgw3z*D$ z1{+fuB6WQ(hIa!1vn!Af-uCx=Xh8Rk6BQv}3ogQbxqO6kYqEYHk*T9pJtA&4gKmV= zo0!$7AzEO>g}ujmzwRA&<14YvCqzH|qQ~G4EN>={@D98mH>@<_x!I)*kG{Df4wh|M zu2f$8zv>C-u-6U4q{Kone*b1)NVL2Qm7|-18h05o3Pu$9K^tMNKNz-uBXqWLk|<2@ zNaQaKRUcs_;JryAudF!(B$BCsT>XIYaXN zmZnVQmm3~#19i@6`xHfv|JpTOA%neUY2`#qM_DjhE~tNo1_N_mT--8XFbE2g^E3#2 zT5^0~3I#E&R-Y)2YOMmTYOVSugoF%wk=>|-yZ|nSL}r-w;1ZsU`&t|q-k#cVtw3`% z)IeTE+Vq3eDw~eYhEM#Yv&7LX&@aAR-9R@daUPG#p*meiLez+*x!q?m+T|zqK^SPU^~@v-AorEVgr?6 zBnI>z6x2eoakCKlE{xl)@}3 zjzmGY4%(*CfVG0(gU@Tv*mds2p|&x+ol9xGm4+UT-Vx4x`DZbJ&fChSwb9V^!}?H} z;8m^aPy|zCdW?23WPvYG1sx~kb9&KHW`dt2^lJox0gzOJ0Z+et6abfYgMCBQ!{|=1?1@3~^gV&QIxe&RfGOk5W-VOP|=}r%7 zxCLIe&m}-*Z&8b^_PmOdx>M`0pOE#D@c7;V90wTp2sx@5V;E5V$f?Sxq9+z*`Jl?c z5CF*Aq&tUX_{62kn4N;ut6T*ElmeJS8EkwR!lY215>cih4)fZm>beRB#L@(op;=)P z&e(wO%IXcAhmoi5D_^-qKqlFjfNZxKKx?Q03@EayP^d-Ff1*AEMMwi-VD@fMJ<6G~ zuP}p?W%YOVSIW&@Uj3Zp#q)p7(3h?<5G3ZPWsK${O$2p^C#fCyKd_uB^EQHQl+Ro4 zOO`x6oPEqhP6VtM-bcEZ4coV!6z5#<LCHTDD0DD(T1f#v5p zQ;CYup(@#k;=@}o+N*`%ZvXVT3r#+UwSF@6)j+rmhBmQ4*>5Ds(B&c392$Tc?U!Ux z2ycKV2*!aD6@oYy6`<}az@CkAYOvhRYZfR4Qp%`?%+NkBi0v`=i^b>+LlT2DvX`bi zmLaIRLsdWcG8)9DoLE;J<9b@e1oYwU&r730t=S;n>rv?<8Y`We3#!T|*JU@Bv}z6N z$nn9MRc&w;ez{3qHCU>`4iIAv_$?RV!DKGpJi2azM-ynS_7$SgQc>$mqnnt0dH6Ky zG8g7*LR>WDWBN6+|mkH7Xdu zP;tAUR36HosSjCCuPT+rM2!u{(M2<>w=x-4DlHPR*)4Slx9jaHp8Cb5zr9)mH&S=R zY%e$$XiSJRATjdI;A}Xv?w8C=efch1)Ircw#dL4#T@Rb|%gi_^Qr*lu(pS;EU=n8|Pb`k);vL7HA7rkd){GICX*zAmZNF?89!4zL6s2;PJP+BBQgCx& zppSC|=<_FYEd#AtbXZvNl^84&AGyJt0-Draf8nWM1Z13fSa;+;l!HVk6YByPT(vevG~xs( z_SGmWSD(}7H(1Fz;^Qv7T`g=HJQ@YlFXZ6I7rDod3jETb?c}EzEyX!fJtE^qWi|&~ zlhE;XPQ&Z*mE{CR2MxUQ@Nv5eN@>AWpke9cfmC-e=q({rZ`+ z=$W5jk{q%LjG7vI8@8OY{$hP-NeBSy|0gkCodpH;#|@y$HiUL`pj`ZnM?zS|eG~^- zSB)NSg$+>gI};v`BbZaV0KZta!irD+L|PPlDmRM{F0;kysL{zNIW!?4;BE%TZI#N+Zo9vt7~nM9WcS0DlU9isVHciiS-@UC{}_;dqrPsLFCvmlX}NwI`)g zw=IY$a`ACmf=T#ev^<=qc!(QG%BZD%%x)^sEImX8B@o=%3AzE>z7vMB&^2X;e=zuL zwObQ4&8h>1T0T5G21v!~WeV0}8F;`P%0eD-)f=XZzyt_wgAeUJMx*pBQ!+64EEDP+ z6TH9#N~y6yU-OoxN!?1dG;N~DK;=YEnNR(Ru33f`T}j%O3v-56RA~5|C zkoD{de*tl2U&UPVYk0F%S;3VArd=4Wze!`PV(t!W4Z>s zIXNx-b^UeCPf)Y`{eLF!s@Z|rv@zRpb}ToACnut|sL*T}(!&z?-r$2J2mOgCzx)`< zdB+*JKl|T%F7NQi%JajUp`q^%cQ*kBP!VP8r7(0Od1-&QDMJmQ=tg!OHg!`Cv5Fe$ zD$24Zd-Afz=Yjg9G}18vW=!O9`Wi5KGT(RCvJ{*b#pQT5ua!N1|KhbMdnzb3k1@$% zQi%?J)$_icO~hW}hWx_w;>!JS_GJFimgBNf8`=qN)JhHRt*Nmme%acG&4mBEeA;S4 zhz~gX@UdU_TOIy(n?n7ormwQ3+a+a$Xm;AHvB4+v@uA>X*jJzqJablKNS7h$rN>(b zF)FNQ8S-)5upnyvSi_OcAp+m113X1z-mD~d+3*9XvaY;)3Q~Z zAi?EJf7U7~r8n!XQ8HG90z^vA%pmsWuOmCbK#QNgx`W>rJbdWkLwbmum!MvtM#v#x z(4gez2}Xhf7-p6<=?j5N%lia)T$sf3g%R;AC3_&Lu)1(f_%jrgfSL%z!|HeEQ;0#Q zT;cy&(+p+{P`p-hA!hhFQtN~Ji4TW*$rplG@%CL!<0nT5K;YceufA@H1*9SXV3=Gj z1))3y7`4|@OlXD&C5{d>+^oq8HekR`9~|c=55~|uq4`!r1+&}u?g7HDg3_BlXMqW5 z{0NwpU2Xv)`fhChdN}}?MOj+SD31n>fg)tW83zGARNY^vL*#@Y+tJ&-qCF$9ePOT0 zT-nxq>*QSn3Rme_ZOWmW99vub`Seu9*2dHEY3RV&#+xoX-PmI5>-l)T^bPnI*trr- zFcW760H9$6{TG`0-+>*D|1q%hml_nZwQ+RPw{dd(2Tn~+*s#H3L) z26ZFb9qQBae2e7+5e{v+vJ!{67E`Wlxmv-)@o?f}h`P@>q&6Pd5}gP!uL|){ku1Dl z7ci`RLQsitHNFRq?}GI+L0)S-fQb=Tz@1G`WGqjW!~-s{fsMZiXIyU!&Prx3QO7RK zS{yd4Tv0%Sn1v>rf$+C@2P&Y9o4Ga=aO6regA6CN+w1s3By0}PJ}dW_>S&YtFtpA3 zqdu4QX%`yzM$iVyDUY0E5EyQoY9R}+JT+bh2ZRBi&&qfu;Z7<;gEAQB+l`Z*85#>l zoTeK*BQFOKULuGeOy0q1)QniA9`l(e1Z_DmhjIePtU?7xu%;GbURI$yukUDx7tGG? zk&?Hkzt?2_Tv}rH^JCN(9X9S>7yT#nqS({aG4x_$CC6>Ymal43A7uki8m#*m#UfP2gRdUFshq}D-U>jZQ}>0;UX3O%&C6;yF1?<8->^YjXytgdHv@% zkc=WP#!Sg+)YCnzHBo@JOmM;0Hu1hit-*^4V@^WP->^9pMpm8sL!SNy{>ym*0-*r> zS1SAeMy~%-+5fft2WI`3(f;pM{|!q2WwQUX{P?r^A65TFX#e{Ne}U?MBe8#h>i;bL ze>VUB;nn~4@fWWBH{|vguKmw~_2=*SpZWNIM{WP@>2DkSckBEM&HZPo1phzt^xqJ= r|L*AD_w#RK|IecH$M65_lK!7fUtS6n?C+7l{s`+&NF@Eeiva%@9Clr( diff --git a/dist/css-layout.js b/dist/css-layout.js deleted file mode 100644 index 5dc93990..00000000 --- a/dist/css-layout.js +++ /dev/null @@ -1,1737 +0,0 @@ -// UMD (Universal Module Definition) -// See https://github.com/umdjs/umd for reference -// -// This file uses the following specific UMD implementation: -// https://github.com/umdjs/umd/blob/master/templates/returnExports.js -(function(root, factory) { - if (typeof define === 'function' && define.amd) { - // AMD. Register as an anonymous module. - define([], factory); - } else if (typeof exports === 'object') { - // Node. Does not work with strict CommonJS, but - // only CommonJS-like environments that support module.exports, - // like Node. - module.exports = factory(); - } else { - // Browser globals (root is window) - root.computeLayout = factory(); - } -}(this, function() { - /** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -var computeLayout = (function() { - - var POSITIVE_FLEX_IS_AUTO = false; - - var gCurrentGenerationCount = 0; - - var CSS_UNDEFINED; - - var CSS_LEFT = 'left'; - var CSS_TOP = 'top'; - var CSS_RIGHT = 'right'; - var CSS_BOTTOM = 'bottom'; - - var CSS_DIRECTION_INHERIT = 'inherit'; - var CSS_DIRECTION_LTR = 'ltr'; - var CSS_DIRECTION_RTL = 'rtl'; - - var CSS_FLEX_DIRECTION_ROW = 'row'; - var CSS_FLEX_DIRECTION_ROW_REVERSE = 'row-reverse'; - var CSS_FLEX_DIRECTION_COLUMN = 'column'; - var CSS_FLEX_DIRECTION_COLUMN_REVERSE = 'column-reverse'; - - var CSS_JUSTIFY_FLEX_START = 'flex-start'; - var CSS_JUSTIFY_CENTER = 'center'; - var CSS_JUSTIFY_FLEX_END = 'flex-end'; - var CSS_JUSTIFY_SPACE_BETWEEN = 'space-between'; - var CSS_JUSTIFY_SPACE_AROUND = 'space-around'; - - var CSS_ALIGN_FLEX_START = 'flex-start'; - var CSS_ALIGN_CENTER = 'center'; - var CSS_ALIGN_FLEX_END = 'flex-end'; - var CSS_ALIGN_STRETCH = 'stretch'; - - var CSS_POSITION_RELATIVE = 'relative'; - var CSS_POSITION_ABSOLUTE = 'absolute'; - - var CSS_OVERFLOW_VISIBLE = 'visible'; - var CSS_OVERFLOW_HIDDEN = 'hidden'; - - var CSS_MEASURE_MODE_UNDEFINED = 'undefined'; - var CSS_MEASURE_MODE_EXACTLY = 'exactly'; - var CSS_MEASURE_MODE_AT_MOST = 'at-most'; - - var leading = { - 'row': 'left', - 'row-reverse': 'right', - 'column': 'top', - 'column-reverse': 'bottom' - }; - var trailing = { - 'row': 'right', - 'row-reverse': 'left', - 'column': 'bottom', - 'column-reverse': 'top' - }; - var pos = { - 'row': 'left', - 'row-reverse': 'right', - 'column': 'top', - 'column-reverse': 'bottom' - }; - var dim = { - 'row': 'width', - 'row-reverse': 'width', - 'column': 'height', - 'column-reverse': 'height' - }; - var measuredDim = { - 'row': 'measuredWidth', - 'row-reverse': 'measuredWidth', - 'column': 'measuredHeight', - 'column-reverse': 'measuredHeight' - }; - - // When transpiled to Java / C the node type has layout, children and style - // properties. For the JavaScript version this function adds these properties - // if they don't already exist. - function fillNodes(node) { - if (!node.layout || node.isDirty) { - node.layout = { - width: undefined, - height: undefined, - top: 0, - left: 0, - right: 0, - bottom: 0 - }; - } - - if (!node.style) { - node.style = {}; - } - - if (!node.children) { - node.children = []; - } - - if (node.style.measure && node.children && node.children.length) { - throw new Error('Using custom measure function is supported only for leaf nodes.'); - } - - node.children.forEach(fillNodes); - return node; - } - - function isUndefined(value) { - return value === undefined || Number.isNaN(value); - } - - function isRowDirection(flexDirection) { - return flexDirection === CSS_FLEX_DIRECTION_ROW || - flexDirection === CSS_FLEX_DIRECTION_ROW_REVERSE; - } - - function isColumnDirection(flexDirection) { - return flexDirection === CSS_FLEX_DIRECTION_COLUMN || - flexDirection === CSS_FLEX_DIRECTION_COLUMN_REVERSE; - } - - function getFlex(node) { - if (node.style.flex === undefined) { - return 0; - } - return node.style.flex; - } - - function isFlexBasisAuto(node) { - if (POSITIVE_FLEX_IS_AUTO) { - // All flex values are auto. - return true; - } else { - // A flex value > 0 implies a basis of zero. - return getFlex(node) <= 0; - } - } - - function getFlexGrowFactor(node) { - // Flex grow is implied by positive values for flex. - if (getFlex(node) > 0) { - return getFlex(node); - } - return 0; - } - - function getFlexShrinkFactor(node) { - if (POSITIVE_FLEX_IS_AUTO) { - // A flex shrink factor of 1 is implied by non-zero values for flex. - if (getFlex(node) !== 0) { - return 1; - } - } else { - // A flex shrink factor of 1 is implied by negative values for flex. - if (getFlex(node) < 0) { - return 1; - } - } - return 0; - } - - function getLeadingMargin(node, axis) { - if (node.style.marginStart !== undefined && isRowDirection(axis)) { - return node.style.marginStart; - } - - var value = null; - switch (axis) { - case 'row': value = node.style.marginLeft; break; - case 'row-reverse': value = node.style.marginRight; break; - case 'column': value = node.style.marginTop; break; - case 'column-reverse': value = node.style.marginBottom; break; - } - - if (value !== undefined) { - return value; - } - - if (node.style.margin !== undefined) { - return node.style.margin; - } - - return 0; - } - - function getTrailingMargin(node, axis) { - if (node.style.marginEnd !== undefined && isRowDirection(axis)) { - return node.style.marginEnd; - } - - var value = null; - switch (axis) { - case 'row': value = node.style.marginRight; break; - case 'row-reverse': value = node.style.marginLeft; break; - case 'column': value = node.style.marginBottom; break; - case 'column-reverse': value = node.style.marginTop; break; - } - - if (value != null) { - return value; - } - - if (node.style.margin !== undefined) { - return node.style.margin; - } - - return 0; - } - - function getLeadingPadding(node, axis) { - if (node.style.paddingStart !== undefined && node.style.paddingStart >= 0 - && isRowDirection(axis)) { - return node.style.paddingStart; - } - - var value = null; - switch (axis) { - case 'row': value = node.style.paddingLeft; break; - case 'row-reverse': value = node.style.paddingRight; break; - case 'column': value = node.style.paddingTop; break; - case 'column-reverse': value = node.style.paddingBottom; break; - } - - if (value != null && value >= 0) { - return value; - } - - if (node.style.padding !== undefined && node.style.padding >= 0) { - return node.style.padding; - } - - return 0; - } - - function getTrailingPadding(node, axis) { - if (node.style.paddingEnd !== undefined && node.style.paddingEnd >= 0 - && isRowDirection(axis)) { - return node.style.paddingEnd; - } - - var value = null; - switch (axis) { - case 'row': value = node.style.paddingRight; break; - case 'row-reverse': value = node.style.paddingLeft; break; - case 'column': value = node.style.paddingBottom; break; - case 'column-reverse': value = node.style.paddingTop; break; - } - - if (value != null && value >= 0) { - return value; - } - - if (node.style.padding !== undefined && node.style.padding >= 0) { - return node.style.padding; - } - - return 0; - } - - function getLeadingBorder(node, axis) { - if (node.style.borderStartWidth !== undefined && node.style.borderStartWidth >= 0 - && isRowDirection(axis)) { - return node.style.borderStartWidth; - } - - var value = null; - switch (axis) { - case 'row': value = node.style.borderLeftWidth; break; - case 'row-reverse': value = node.style.borderRightWidth; break; - case 'column': value = node.style.borderTopWidth; break; - case 'column-reverse': value = node.style.borderBottomWidth; break; - } - - if (value != null && value >= 0) { - return value; - } - - if (node.style.borderWidth !== undefined && node.style.borderWidth >= 0) { - return node.style.borderWidth; - } - - return 0; - } - - function getTrailingBorder(node, axis) { - if (node.style.borderEndWidth !== undefined && node.style.borderEndWidth >= 0 - && isRowDirection(axis)) { - return node.style.borderEndWidth; - } - - var value = null; - switch (axis) { - case 'row': value = node.style.borderRightWidth; break; - case 'row-reverse': value = node.style.borderLeftWidth; break; - case 'column': value = node.style.borderBottomWidth; break; - case 'column-reverse': value = node.style.borderTopWidth; break; - } - - if (value != null && value >= 0) { - return value; - } - - if (node.style.borderWidth !== undefined && node.style.borderWidth >= 0) { - return node.style.borderWidth; - } - - return 0; - } - - function getLeadingPaddingAndBorder(node, axis) { - return getLeadingPadding(node, axis) + getLeadingBorder(node, axis); - } - - function getTrailingPaddingAndBorder(node, axis) { - return getTrailingPadding(node, axis) + getTrailingBorder(node, axis); - } - - function getMarginAxis(node, axis) { - return getLeadingMargin(node, axis) + getTrailingMargin(node, axis); - } - - function getPaddingAndBorderAxis(node, axis) { - return getLeadingPaddingAndBorder(node, axis) + - getTrailingPaddingAndBorder(node, axis); - } - - function getJustifyContent(node) { - if (node.style.justifyContent) { - return node.style.justifyContent; - } - return 'flex-start'; - } - - function getAlignContent(node) { - if (node.style.alignContent) { - return node.style.alignContent; - } - return 'flex-start'; - } - - function getAlignItem(node, child) { - if (child.style.alignSelf) { - return child.style.alignSelf; - } - if (node.style.alignItems) { - return node.style.alignItems; - } - return 'stretch'; - } - - function resolveAxis(axis, direction) { - if (direction === CSS_DIRECTION_RTL) { - if (axis === CSS_FLEX_DIRECTION_ROW) { - return CSS_FLEX_DIRECTION_ROW_REVERSE; - } else if (axis === CSS_FLEX_DIRECTION_ROW_REVERSE) { - return CSS_FLEX_DIRECTION_ROW; - } - } - - return axis; - } - - function resolveDirection(node, parentDirection) { - var direction; - if (node.style.direction) { - direction = node.style.direction; - } else { - direction = CSS_DIRECTION_INHERIT; - } - - if (direction === CSS_DIRECTION_INHERIT) { - direction = (parentDirection === undefined ? CSS_DIRECTION_LTR : parentDirection); - } - - return direction; - } - - function getFlexDirection(node) { - if (node.style.flexDirection) { - return node.style.flexDirection; - } - return CSS_FLEX_DIRECTION_COLUMN; - } - - function getCrossFlexDirection(flexDirection, direction) { - if (isColumnDirection(flexDirection)) { - return resolveAxis(CSS_FLEX_DIRECTION_ROW, direction); - } else { - return CSS_FLEX_DIRECTION_COLUMN; - } - } - - function getPositionType(node) { - if (node.style.position) { - return node.style.position; - } - return CSS_POSITION_RELATIVE; - } - - function getOverflow(node) { - if (node.style.overflow) { - return node.style.overflow; - } - return CSS_OVERFLOW_VISIBLE; - } - - function isFlex(node) { - return ( - getPositionType(node) === CSS_POSITION_RELATIVE && - node.style.flex !== undefined && node.style.flex !== 0 - ); - } - - function isFlexWrap(node) { - return node.style.flexWrap === 'wrap'; - } - - function getDimWithMargin(node, axis) { - return node.layout[measuredDim[axis]] + getMarginAxis(node, axis); - } - - function isStyleDimDefined(node, axis) { - return node.style[dim[axis]] !== undefined && node.style[dim[axis]] >= 0; - } - - function isLayoutDimDefined(node, axis) { - return node.layout[measuredDim[axis]] !== undefined && node.layout[measuredDim[axis]] >= 0; - } - - function isPosDefined(node, pos) { - return node.style[pos] !== undefined; - } - - function isMeasureDefined(node) { - return node.style.measure !== undefined; - } - - function getPosition(node, pos) { - if (node.style[pos] !== undefined) { - return node.style[pos]; - } - return 0; - } - - function boundAxisWithinMinAndMax(node, axis, value) { - var min = { - 'row': node.style.minWidth, - 'row-reverse': node.style.minWidth, - 'column': node.style.minHeight, - 'column-reverse': node.style.minHeight - }[axis]; - - var max = { - 'row': node.style.maxWidth, - 'row-reverse': node.style.maxWidth, - 'column': node.style.maxHeight, - 'column-reverse': node.style.maxHeight - }[axis]; - - var boundValue = value; - if (max !== undefined && max >= 0 && boundValue > max) { - boundValue = max; - } - if (min !== undefined && min >= 0 && boundValue < min) { - boundValue = min; - } - return boundValue; - } - - function fminf(a, b) { - if (a < b) { - return a; - } - return b; - } - - function fmaxf(a, b) { - if (a > b) { - return a; - } - return b; - } - - // Like boundAxisWithinMinAndMax but also ensures that the value doesn't go below the - // padding and border amount. - function boundAxis(node, axis, value) { - return fmaxf(boundAxisWithinMinAndMax(node, axis, value), getPaddingAndBorderAxis(node, axis)); - } - - function setTrailingPosition(node, child, axis) { - var size = (getPositionType(child) === CSS_POSITION_ABSOLUTE) ? - 0 : - child.layout[measuredDim[axis]]; - child.layout[trailing[axis]] = node.layout[measuredDim[axis]] - size - child.layout[pos[axis]]; - } - - // If both left and right are defined, then use left. Otherwise return - // +left or -right depending on which is defined. - function getRelativePosition(node, axis) { - if (node.style[leading[axis]] !== undefined) { - return getPosition(node, leading[axis]); - } - return -getPosition(node, trailing[axis]); - } - - function setPosition(node, direction) { - var mainAxis = resolveAxis(getFlexDirection(node), direction); - var crossAxis = getCrossFlexDirection(mainAxis, direction); - - node.layout[leading[mainAxis]] = getLeadingMargin(node, mainAxis) + - getRelativePosition(node, mainAxis); - node.layout[trailing[mainAxis]] = getTrailingMargin(node, mainAxis) + - getRelativePosition(node, mainAxis); - node.layout[leading[crossAxis]] = getLeadingMargin(node, crossAxis) + - getRelativePosition(node, crossAxis); - node.layout[trailing[crossAxis]] = getTrailingMargin(node, crossAxis) + - getRelativePosition(node, crossAxis); - } - - function assert(condition, message) { - if (!condition) { - throw new Error(message); - } - } - - // - // This is the main routine that implements a subset of the flexbox layout algorithm - // described in the W3C CSS documentation: https://www.w3.org/TR/css3-flexbox/. - // - // Limitations of this algorithm, compared to the full standard: - // * Display property is always assumed to be 'flex' except for Text nodes, which - // are assumed to be 'inline-flex'. - // * The 'zIndex' property (or any form of z ordering) is not supported. Nodes are - // stacked in document order. - // * The 'order' property is not supported. The order of flex items is always defined - // by document order. - // * The 'visibility' property is always assumed to be 'visible'. Values of 'collapse' - // and 'hidden' are not supported. - // * The 'wrap' property supports only 'nowrap' (which is the default) or 'wrap'. The - // rarely-used 'wrap-reverse' is not supported. - // * Rather than allowing arbitrary combinations of flexGrow, flexShrink and - // flexBasis, this algorithm supports only the three most common combinations: - // flex: 0 is equiavlent to flex: 0 0 auto - // flex: n (where n is a positive value) is equivalent to flex: n 1 auto - // If POSITIVE_FLEX_IS_AUTO is 0, then it is equivalent to flex: n 0 0 - // This is faster because the content doesn't need to be measured, but it's - // less flexible because the basis is always 0 and can't be overriden with - // the width/height attributes. - // flex: -1 (or any negative value) is equivalent to flex: 0 1 auto - // * Margins cannot be specified as 'auto'. They must be specified in terms of pixel - // values, and the default value is 0. - // * The 'baseline' value is not supported for alignItems and alignSelf properties. - // * Values of width, maxWidth, minWidth, height, maxHeight and minHeight must be - // specified as pixel values, not as percentages. - // * There is no support for calculation of dimensions based on intrinsic aspect ratios - // (e.g. images). - // * There is no support for forced breaks. - // * It does not support vertical inline directions (top-to-bottom or bottom-to-top text). - // - // Deviations from standard: - // * Section 4.5 of the spec indicates that all flex items have a default minimum - // main size. For text blocks, for example, this is the width of the widest word. - // Calculating the minimum width is expensive, so we forego it and assume a default - // minimum main size of 0. - // * Min/Max sizes in the main axis are not honored when resolving flexible lengths. - // * The spec indicates that the default value for 'flexDirection' is 'row', but - // the algorithm below assumes a default of 'column'. - // - // Input parameters: - // - node: current node to be sized and layed out - // - availableWidth & availableHeight: available size to be used for sizing the node - // or CSS_UNDEFINED if the size is not available; interpretation depends on layout - // flags - // - parentDirection: the inline (text) direction within the parent (left-to-right or - // right-to-left) - // - widthMeasureMode: indicates the sizing rules for the width (see below for explanation) - // - heightMeasureMode: indicates the sizing rules for the height (see below for explanation) - // - performLayout: specifies whether the caller is interested in just the dimensions - // of the node or it requires the entire node and its subtree to be layed out - // (with final positions) - // - // Details: - // This routine is called recursively to lay out subtrees of flexbox elements. It uses the - // information in node.style, which is treated as a read-only input. It is responsible for - // setting the layout.direction and layout.measured_dimensions fields for the input node as well - // as the layout.position and layout.line_index fields for its child nodes. The - // layout.measured_dimensions field includes any border or padding for the node but does - // not include margins. - // - // The spec describes four different layout modes: "fill available", "max content", "min content", - // and "fit content". Of these, we don't use "min content" because we don't support default - // minimum main sizes (see above for details). Each of our measure modes maps to a layout mode - // from the spec (https://www.w3.org/TR/css3-sizing/#terms): - // - CSS_MEASURE_MODE_UNDEFINED: max content - // - CSS_MEASURE_MODE_EXACTLY: fill available - // - CSS_MEASURE_MODE_AT_MOST: fit content - // - // When calling layoutNodeImpl and layoutNodeInternal, if the caller passes an available size of - // undefined then it must also pass a measure mode of CSS_MEASURE_MODE_UNDEFINED in that dimension. - // - function layoutNodeImpl(node, availableWidth, availableHeight, /*css_direction_t*/parentDirection, widthMeasureMode, heightMeasureMode, performLayout) { - assert(isUndefined(availableWidth) ? widthMeasureMode === CSS_MEASURE_MODE_UNDEFINED : true, 'availableWidth is indefinite so widthMeasureMode must be CSS_MEASURE_MODE_UNDEFINED'); - assert(isUndefined(availableHeight) ? heightMeasureMode === CSS_MEASURE_MODE_UNDEFINED : true, 'availableHeight is indefinite so heightMeasureMode must be CSS_MEASURE_MODE_UNDEFINED'); - - var/*float*/ paddingAndBorderAxisRow = getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW); - var/*float*/ paddingAndBorderAxisColumn = getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN); - var/*float*/ marginAxisRow = getMarginAxis(node, CSS_FLEX_DIRECTION_ROW); - var/*float*/ marginAxisColumn = getMarginAxis(node, CSS_FLEX_DIRECTION_COLUMN); - - // Set the resolved resolution in the node's layout. - var/*css_direction_t*/ direction = resolveDirection(node, parentDirection); - node.layout.direction = direction; - - // For content (text) nodes, determine the dimensions based on the text contents. - if (isMeasureDefined(node)) { - var/*float*/ innerWidth = availableWidth - marginAxisRow - paddingAndBorderAxisRow; - var/*float*/ innerHeight = availableHeight - marginAxisColumn - paddingAndBorderAxisColumn; - - if (widthMeasureMode === CSS_MEASURE_MODE_EXACTLY && heightMeasureMode === CSS_MEASURE_MODE_EXACTLY) { - - // Don't bother sizing the text if both dimensions are already defined. - node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW, availableWidth - marginAxisRow); - node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, availableHeight - marginAxisColumn); - } else if (innerWidth <= 0 || innerHeight <= 0) { - - // Don't bother sizing the text if there's no horizontal or vertical space. - node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW, 0); - node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, 0); - } else { - - // Measure the text under the current constraints. - var/*css_dim_t*/ measureDim = node.style.measure( - /*(c)!node->context,*/ - /*(java)!layoutContext.measureOutput,*/ - innerWidth, - widthMeasureMode, - innerHeight, - heightMeasureMode - ); - - node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW, - (widthMeasureMode === CSS_MEASURE_MODE_UNDEFINED || widthMeasureMode === CSS_MEASURE_MODE_AT_MOST) ? - measureDim.width + paddingAndBorderAxisRow : - availableWidth - marginAxisRow); - node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, - (heightMeasureMode === CSS_MEASURE_MODE_UNDEFINED || heightMeasureMode === CSS_MEASURE_MODE_AT_MOST) ? - measureDim.height + paddingAndBorderAxisColumn : - availableHeight - marginAxisColumn); - } - - return; - } - - // For nodes with no children, use the available values if they were provided, or - // the minimum size as indicated by the padding and border sizes. - var/*int*/ childCount = node.children.length; - if (childCount === 0) { - node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW, - (widthMeasureMode === CSS_MEASURE_MODE_UNDEFINED || widthMeasureMode === CSS_MEASURE_MODE_AT_MOST) ? - paddingAndBorderAxisRow : - availableWidth - marginAxisRow); - node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, - (heightMeasureMode === CSS_MEASURE_MODE_UNDEFINED || heightMeasureMode === CSS_MEASURE_MODE_AT_MOST) ? - paddingAndBorderAxisColumn : - availableHeight - marginAxisColumn); - return; - } - - // If we're not being asked to perform a full layout, we can handle a number of common - // cases here without incurring the cost of the remaining function. - if (!performLayout) { - // If we're being asked to size the content with an at most constraint but there is no available width, - // the measurement will always be zero. - if (widthMeasureMode === CSS_MEASURE_MODE_AT_MOST && availableWidth <= 0 && - heightMeasureMode === CSS_MEASURE_MODE_AT_MOST && availableHeight <= 0) { - node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW, 0); - node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, 0); - return; - } - - if (widthMeasureMode === CSS_MEASURE_MODE_AT_MOST && availableWidth <= 0) { - node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW, 0); - node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, isUndefined(availableHeight) ? 0 : (availableHeight - marginAxisColumn)); - return; - } - - if (heightMeasureMode === CSS_MEASURE_MODE_AT_MOST && availableHeight <= 0) { - node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW, isUndefined(availableWidth) ? 0 : (availableWidth - marginAxisRow)); - node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, 0); - return; - } - - // If we're being asked to use an exact width/height, there's no need to measure the children. - if (widthMeasureMode === CSS_MEASURE_MODE_EXACTLY && heightMeasureMode === CSS_MEASURE_MODE_EXACTLY) { - node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW, availableWidth - marginAxisRow); - node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, availableHeight - marginAxisColumn); - return; - } - } - - // STEP 1: CALCULATE VALUES FOR REMAINDER OF ALGORITHM - var/*(c)!css_flex_direction_t*//*(java)!int*/ mainAxis = resolveAxis(getFlexDirection(node), direction); - var/*(c)!css_flex_direction_t*//*(java)!int*/ crossAxis = getCrossFlexDirection(mainAxis, direction); - var/*bool*/ isMainAxisRow = isRowDirection(mainAxis); - var/*css_justify_t*/ justifyContent = getJustifyContent(node); - var/*bool*/ isNodeFlexWrap = isFlexWrap(node); - - var/*css_node_t**/ firstAbsoluteChild = undefined; - var/*css_node_t**/ currentAbsoluteChild = undefined; - - var/*float*/ leadingPaddingAndBorderMain = getLeadingPaddingAndBorder(node, mainAxis); - var/*float*/ trailingPaddingAndBorderMain = getTrailingPaddingAndBorder(node, mainAxis); - var/*float*/ leadingPaddingAndBorderCross = getLeadingPaddingAndBorder(node, crossAxis); - var/*float*/ paddingAndBorderAxisMain = getPaddingAndBorderAxis(node, mainAxis); - var/*float*/ paddingAndBorderAxisCross = getPaddingAndBorderAxis(node, crossAxis); - - var/*css_measure_mode_t*/ measureModeMainDim = isMainAxisRow ? widthMeasureMode : heightMeasureMode; - var/*css_measure_mode_t*/ measureModeCrossDim = isMainAxisRow ? heightMeasureMode : widthMeasureMode; - - // STEP 2: DETERMINE AVAILABLE SIZE IN MAIN AND CROSS DIRECTIONS - var/*float*/ availableInnerWidth = availableWidth - marginAxisRow - paddingAndBorderAxisRow; - var/*float*/ availableInnerHeight = availableHeight - marginAxisColumn - paddingAndBorderAxisColumn; - var/*float*/ availableInnerMainDim = isMainAxisRow ? availableInnerWidth : availableInnerHeight; - var/*float*/ availableInnerCrossDim = isMainAxisRow ? availableInnerHeight : availableInnerWidth; - - // STEP 3: DETERMINE FLEX BASIS FOR EACH ITEM - var/*css_node_t**/ child; - var/*int*/ i; - var/*float*/ childWidth; - var/*float*/ childHeight; - var/*css_measure_mode_t*/ childWidthMeasureMode; - var/*css_measure_mode_t*/ childHeightMeasureMode; - for (i = 0; i < childCount; i++) { - child = node.children[i]; - - if (performLayout) { - // Set the initial position (relative to the parent). - var/*css_direction_t*/ childDirection = resolveDirection(child, direction); - setPosition(child, childDirection); - } - - // Absolute-positioned children don't participate in flex layout. Add them - // to a list that we can process later. - if (getPositionType(child) === CSS_POSITION_ABSOLUTE) { - - // Store a private linked list of absolutely positioned children - // so that we can efficiently traverse them later. - if (firstAbsoluteChild === undefined) { - firstAbsoluteChild = child; - } - if (currentAbsoluteChild !== undefined) { - currentAbsoluteChild.nextChild = child; - } - currentAbsoluteChild = child; - child.nextChild = undefined; - } else { - - if (isMainAxisRow && isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW)) { - - // The width is definite, so use that as the flex basis. - child.layout.flexBasis = fmaxf(child.style.width, getPaddingAndBorderAxis(child, CSS_FLEX_DIRECTION_ROW)); - } else if (!isMainAxisRow && isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN)) { - - // The height is definite, so use that as the flex basis. - child.layout.flexBasis = fmaxf(child.style.height, getPaddingAndBorderAxis(child, CSS_FLEX_DIRECTION_COLUMN)); - } else if (!isFlexBasisAuto(child) && !isUndefined(availableInnerMainDim)) { - - // If the basis isn't 'auto', it is assumed to be zero. - child.layout.flexBasis = fmaxf(0, getPaddingAndBorderAxis(child, mainAxis)); - } else { - - // Compute the flex basis and hypothetical main size (i.e. the clamped flex basis). - childWidth = CSS_UNDEFINED; - childHeight = CSS_UNDEFINED; - childWidthMeasureMode = CSS_MEASURE_MODE_UNDEFINED; - childHeightMeasureMode = CSS_MEASURE_MODE_UNDEFINED; - - if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW)) { - childWidth = child.style.width + getMarginAxis(child, CSS_FLEX_DIRECTION_ROW); - childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } - if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN)) { - childHeight = child.style.height + getMarginAxis(child, CSS_FLEX_DIRECTION_COLUMN); - childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } - - // According to the spec, if the main size is not definite and the - // child's inline axis is parallel to the main axis (i.e. it's - // horizontal), the child should be sized using "UNDEFINED" in - // the main size. Otherwise use "AT_MOST" in the cross axis. - if (!isMainAxisRow && isUndefined(childWidth) && !isUndefined(availableInnerWidth)) { - childWidth = availableInnerWidth; - childWidthMeasureMode = CSS_MEASURE_MODE_AT_MOST; - } - - // The W3C spec doesn't say anything about the 'overflow' property, - // but all major browsers appear to implement the following logic. - if (getOverflow(node) === CSS_OVERFLOW_HIDDEN) { - if (isMainAxisRow && isUndefined(childHeight) && !isUndefined(availableInnerHeight)) { - childHeight = availableInnerHeight; - childHeightMeasureMode = CSS_MEASURE_MODE_AT_MOST; - } - } - - // If child has no defined size in the cross axis and is set to stretch, set the cross - // axis to be measured exactly with the available inner width - if (!isMainAxisRow && - !isUndefined(availableInnerWidth) && - !isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW) && - widthMeasureMode == CSS_MEASURE_MODE_EXACTLY && - getAlignItem(node, child) == CSS_ALIGN_STRETCH) { - childWidth = availableInnerWidth; - childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } - if (isMainAxisRow && - !isUndefined(availableInnerHeight) && - !isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN) && - heightMeasureMode == CSS_MEASURE_MODE_EXACTLY && - getAlignItem(node, child) == CSS_ALIGN_STRETCH) { - childHeight = availableInnerHeight; - childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } - - // Measure the child - layoutNodeInternal(child, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, false, 'measure'); - - child.layout.flexBasis = fmaxf(isMainAxisRow ? child.layout.measuredWidth : child.layout.measuredHeight, getPaddingAndBorderAxis(child, mainAxis)); - } - } - } - - // STEP 4: COLLECT FLEX ITEMS INTO FLEX LINES - - // Indexes of children that represent the first and last items in the line. - var/*int*/ startOfLineIndex = 0; - var/*int*/ endOfLineIndex = 0; - - // Number of lines. - var/*int*/ lineCount = 0; - - // Accumulated cross dimensions of all lines so far. - var/*float*/ totalLineCrossDim = 0; - - // Max main dimension of all the lines. - var/*float*/ maxLineMainDim = 0; - - while (endOfLineIndex < childCount) { - - // Number of items on the currently line. May be different than the difference - // between start and end indicates because we skip over absolute-positioned items. - var/*int*/ itemsOnLine = 0; - - // sizeConsumedOnCurrentLine is accumulation of the dimensions and margin - // of all the children on the current line. 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. - var/*float*/ sizeConsumedOnCurrentLine = 0; - - var/*float*/ totalFlexGrowFactors = 0; - var/*float*/ totalFlexShrinkScaledFactors = 0; - - i = startOfLineIndex; - - // Maintain a linked list of the child nodes that can shrink and/or grow. - var/*css_node_t**/ firstRelativeChild = undefined; - var/*css_node_t**/ currentRelativeChild = undefined; - - // Add items to the current line until it's full or we run out of items. - while (i < childCount) { - child = node.children[i]; - child.lineIndex = lineCount; - - if (getPositionType(child) !== CSS_POSITION_ABSOLUTE) { - var/*float*/ outerFlexBasis = child.layout.flexBasis + getMarginAxis(child, mainAxis); - - // If this is a multi-line flow and this item pushes us over the available size, we've - // hit the end of the current line. Break out of the loop and lay out the current line. - if (sizeConsumedOnCurrentLine + outerFlexBasis > availableInnerMainDim && isNodeFlexWrap && itemsOnLine > 0) { - break; - } - - sizeConsumedOnCurrentLine += outerFlexBasis; - itemsOnLine++; - - if (isFlex(child)) { - totalFlexGrowFactors += getFlexGrowFactor(child); - - // Unlike the grow factor, the shrink factor is scaled relative to the child - // dimension. - totalFlexShrinkScaledFactors += getFlexShrinkFactor(child) * child.layout.flexBasis; - } - - // Store a private linked list of children that need to be layed out. - if (firstRelativeChild === undefined) { - firstRelativeChild = child; - } - if (currentRelativeChild !== undefined) { - currentRelativeChild.nextChild = child; - } - currentRelativeChild = child; - child.nextChild = undefined; - } - - i++; - endOfLineIndex++; - } - - // If we don't need to measure the cross axis, we can skip the entire flex step. - var/*bool*/ canSkipFlex = !performLayout && measureModeCrossDim === CSS_MEASURE_MODE_EXACTLY; - - // 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. - var/*float*/ leadingMainDim = 0; - var/*float*/ betweenMainDim = 0; - - // STEP 5: RESOLVING FLEXIBLE LENGTHS ON MAIN AXIS - // Calculate the remaining available space that needs to be allocated. - // If the main dimension size isn't known, it is computed based on - // the line length, so there's no more space left to distribute. - var/*float*/ remainingFreeSpace = 0; - if (!isUndefined(availableInnerMainDim)) { - remainingFreeSpace = availableInnerMainDim - sizeConsumedOnCurrentLine; - } else if (sizeConsumedOnCurrentLine < 0) { - // availableInnerMainDim is indefinite which means the node is being sized based on its content. - // sizeConsumedOnCurrentLine is negative which means the node will allocate 0 pixels for - // its content. Consequently, remainingFreeSpace is 0 - sizeConsumedOnCurrentLine. - remainingFreeSpace = -sizeConsumedOnCurrentLine; - } - - var/*float*/ originalRemainingFreeSpace = remainingFreeSpace; - var/*float*/ deltaFreeSpace = 0; - - if (!canSkipFlex) { - var/*float*/ childFlexBasis; - var/*float*/ flexShrinkScaledFactor; - var/*float*/ flexGrowFactor; - var/*float*/ baseMainSize; - var/*float*/ boundMainSize; - - // Do two passes over the flex items to figure out how to distribute the remaining space. - // The first pass finds the items whose min/max constraints trigger, freezes them at those - // sizes, and excludes those sizes from the remaining space. The second pass sets the size - // of each flexible item. It distributes the remaining space amongst the items whose min/max - // constraints didn't trigger in pass 1. For the other items, it sets their sizes by forcing - // their min/max constraints to trigger again. - // - // This two pass approach for resolving min/max constraints deviates from the spec. The - // spec (https://www.w3.org/TR/css-flexbox-1/#resolve-flexible-lengths) describes a process - // that needs to be repeated a variable number of times. The algorithm implemented here - // won't handle all cases but it was simpler to implement and it mitigates performance - // concerns because we know exactly how many passes it'll do. - - // First pass: detect the flex items whose min/max constraints trigger - var/*float*/ deltaFlexShrinkScaledFactors = 0; - var/*float*/ deltaFlexGrowFactors = 0; - currentRelativeChild = firstRelativeChild; - while (currentRelativeChild !== undefined) { - childFlexBasis = currentRelativeChild.layout.flexBasis; - - if (remainingFreeSpace < 0) { - flexShrinkScaledFactor = getFlexShrinkFactor(currentRelativeChild) * childFlexBasis; - - // Is this child able to shrink? - if (flexShrinkScaledFactor !== 0) { - baseMainSize = childFlexBasis + - remainingFreeSpace / totalFlexShrinkScaledFactors * flexShrinkScaledFactor; - boundMainSize = boundAxis(currentRelativeChild, mainAxis, baseMainSize); - if (baseMainSize !== boundMainSize) { - // By excluding this item's size and flex factor from remaining, this item's - // min/max constraints should also trigger in the second pass resulting in the - // item's size calculation being identical in the first and second passes. - deltaFreeSpace -= boundMainSize - childFlexBasis; - deltaFlexShrinkScaledFactors -= flexShrinkScaledFactor; - } - } - } else if (remainingFreeSpace > 0) { - flexGrowFactor = getFlexGrowFactor(currentRelativeChild); - - // Is this child able to grow? - if (flexGrowFactor !== 0) { - baseMainSize = childFlexBasis + - remainingFreeSpace / totalFlexGrowFactors * flexGrowFactor; - boundMainSize = boundAxis(currentRelativeChild, mainAxis, baseMainSize); - if (baseMainSize !== boundMainSize) { - // By excluding this item's size and flex factor from remaining, this item's - // min/max constraints should also trigger in the second pass resulting in the - // item's size calculation being identical in the first and second passes. - deltaFreeSpace -= boundMainSize - childFlexBasis; - deltaFlexGrowFactors -= flexGrowFactor; - } - } - } - - currentRelativeChild = currentRelativeChild.nextChild; - } - - totalFlexShrinkScaledFactors += deltaFlexShrinkScaledFactors; - totalFlexGrowFactors += deltaFlexGrowFactors; - remainingFreeSpace += deltaFreeSpace; - - // Second pass: resolve the sizes of the flexible items - deltaFreeSpace = 0; - currentRelativeChild = firstRelativeChild; - while (currentRelativeChild !== undefined) { - childFlexBasis = currentRelativeChild.layout.flexBasis; - var/*float*/ updatedMainSize = childFlexBasis; - - if (remainingFreeSpace < 0) { - flexShrinkScaledFactor = getFlexShrinkFactor(currentRelativeChild) * childFlexBasis; - - // Is this child able to shrink? - if (flexShrinkScaledFactor !== 0) { - updatedMainSize = boundAxis(currentRelativeChild, mainAxis, childFlexBasis + - remainingFreeSpace / totalFlexShrinkScaledFactors * flexShrinkScaledFactor); - } - } else if (remainingFreeSpace > 0) { - flexGrowFactor = getFlexGrowFactor(currentRelativeChild); - - // Is this child able to grow? - if (flexGrowFactor !== 0) { - updatedMainSize = boundAxis(currentRelativeChild, mainAxis, childFlexBasis + - remainingFreeSpace / totalFlexGrowFactors * flexGrowFactor); - } - } - - deltaFreeSpace -= updatedMainSize - childFlexBasis; - - if (isMainAxisRow) { - childWidth = updatedMainSize + getMarginAxis(currentRelativeChild, CSS_FLEX_DIRECTION_ROW); - childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; - - if (!isUndefined(availableInnerCrossDim) && - !isStyleDimDefined(currentRelativeChild, CSS_FLEX_DIRECTION_COLUMN) && - heightMeasureMode == CSS_MEASURE_MODE_EXACTLY && - getAlignItem(node, currentRelativeChild) == CSS_ALIGN_STRETCH) { - childHeight = availableInnerCrossDim; - childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } else if (!isStyleDimDefined(currentRelativeChild, CSS_FLEX_DIRECTION_COLUMN)) { - childHeight = availableInnerCrossDim; - childHeightMeasureMode = isUndefined(childHeight) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_AT_MOST; - } else { - childHeight = currentRelativeChild.style.height + getMarginAxis(currentRelativeChild, CSS_FLEX_DIRECTION_COLUMN); - childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } - } else { - childHeight = updatedMainSize + getMarginAxis(currentRelativeChild, CSS_FLEX_DIRECTION_COLUMN); - childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY; - - if (!isUndefined(availableInnerCrossDim) && - !isStyleDimDefined(currentRelativeChild, CSS_FLEX_DIRECTION_ROW) && - widthMeasureMode == CSS_MEASURE_MODE_EXACTLY && - getAlignItem(node, currentRelativeChild) == CSS_ALIGN_STRETCH) { - childWidth = availableInnerCrossDim; - childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } else if (!isStyleDimDefined(currentRelativeChild, CSS_FLEX_DIRECTION_ROW)) { - childWidth = availableInnerCrossDim; - childWidthMeasureMode = isUndefined(childWidth) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_AT_MOST; - } else { - childWidth = currentRelativeChild.style.width + getMarginAxis(currentRelativeChild, CSS_FLEX_DIRECTION_ROW); - childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } - } - - var/*bool*/ requiresStretchLayout = !isStyleDimDefined(currentRelativeChild, crossAxis) && - getAlignItem(node, currentRelativeChild) === CSS_ALIGN_STRETCH; - - // Recursively call the layout algorithm for this child with the updated main size. - layoutNodeInternal(currentRelativeChild, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, performLayout && !requiresStretchLayout, 'flex'); - - currentRelativeChild = currentRelativeChild.nextChild; - } - } - - remainingFreeSpace = originalRemainingFreeSpace + deltaFreeSpace; - - // STEP 6: MAIN-AXIS JUSTIFICATION & CROSS-AXIS SIZE DETERMINATION - - // At this point, all the children have their dimensions set in the main axis. - // Their dimensions are also set in the cross axis with the exception of items - // that are aligned 'stretch'. We need to compute these stretch values and - // set the final positions. - - // If we are using "at most" rules in the main axis, we won't distribute - // any remaining space at this point. - if (measureModeMainDim === CSS_MEASURE_MODE_AT_MOST) { - remainingFreeSpace = 0; - } - - // Use justifyContent to figure out how to allocate the remaining space - // available in the main axis. - if (justifyContent !== CSS_JUSTIFY_FLEX_START) { - if (justifyContent === CSS_JUSTIFY_CENTER) { - leadingMainDim = remainingFreeSpace / 2; - } else if (justifyContent === CSS_JUSTIFY_FLEX_END) { - leadingMainDim = remainingFreeSpace; - } else if (justifyContent === CSS_JUSTIFY_SPACE_BETWEEN) { - remainingFreeSpace = fmaxf(remainingFreeSpace, 0); - if (itemsOnLine > 1) { - betweenMainDim = remainingFreeSpace / (itemsOnLine - 1); - } else { - betweenMainDim = 0; - } - } else if (justifyContent === CSS_JUSTIFY_SPACE_AROUND) { - // Space on the edges is half of the space between elements - betweenMainDim = remainingFreeSpace / itemsOnLine; - leadingMainDim = betweenMainDim / 2; - } - } - - var/*float*/ mainDim = leadingPaddingAndBorderMain + leadingMainDim; - var/*float*/ crossDim = 0; - - for (i = startOfLineIndex; i < endOfLineIndex; ++i) { - child = node.children[i]; - - if (getPositionType(child) === CSS_POSITION_ABSOLUTE && - isPosDefined(child, leading[mainAxis])) { - if (performLayout) { - // 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). - child.layout[pos[mainAxis]] = getPosition(child, leading[mainAxis]) + - getLeadingBorder(node, mainAxis) + - getLeadingMargin(child, mainAxis); - } - } else { - if (performLayout) { - // If the child is position absolute (without top/left) or relative, - // we put it at the current accumulated offset. - child.layout[pos[mainAxis]] += mainDim; - } - - // Now that we placed the element, we need to update the variables. - // We need to do that only for relative elements. Absolute elements - // do not take part in that phase. - if (getPositionType(child) === CSS_POSITION_RELATIVE) { - if (canSkipFlex) { - // If we skipped the flex step, then we can't rely on the measuredDims because - // they weren't computed. This means we can't call getDimWithMargin. - mainDim += betweenMainDim + getMarginAxis(child, mainAxis) + child.layout.flexBasis; - crossDim = availableInnerCrossDim; - } else { - // The main dimension is the sum of all the elements dimension plus - // the spacing. - 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 = fmaxf(crossDim, getDimWithMargin(child, crossAxis)); - } - } - } - } - - mainDim += trailingPaddingAndBorderMain; - - var/*float*/ containerCrossAxis = availableInnerCrossDim; - if (measureModeCrossDim === CSS_MEASURE_MODE_UNDEFINED || measureModeCrossDim === CSS_MEASURE_MODE_AT_MOST) { - // Compute the cross axis from the max cross dimension of the children. - containerCrossAxis = boundAxis(node, crossAxis, crossDim + paddingAndBorderAxisCross) - paddingAndBorderAxisCross; - - if (measureModeCrossDim === CSS_MEASURE_MODE_AT_MOST) { - containerCrossAxis = fminf(containerCrossAxis, availableInnerCrossDim); - } - } - - // If there's no flex wrap, the cross dimension is defined by the container. - if (!isNodeFlexWrap && measureModeCrossDim === CSS_MEASURE_MODE_EXACTLY) { - crossDim = availableInnerCrossDim; - } - - // Clamp to the min/max size specified on the container. - crossDim = boundAxis(node, crossAxis, crossDim + paddingAndBorderAxisCross) - paddingAndBorderAxisCross; - - // STEP 7: CROSS-AXIS ALIGNMENT - // We can skip child alignment if we're just measuring the container. - if (performLayout) { - for (i = startOfLineIndex; i < endOfLineIndex; ++i) { - child = node.children[i]; - - if (getPositionType(child) === CSS_POSITION_ABSOLUTE) { - // If the child is absolutely positioned and has a top/left/bottom/right - // set, override all the previously computed positions to set it correctly. - if (isPosDefined(child, leading[crossAxis])) { - child.layout[pos[crossAxis]] = getPosition(child, leading[crossAxis]) + - getLeadingBorder(node, crossAxis) + - getLeadingMargin(child, crossAxis); - } else { - child.layout[pos[crossAxis]] = leadingPaddingAndBorderCross + - getLeadingMargin(child, crossAxis); - } - } else { - var/*float*/ leadingCrossDim = leadingPaddingAndBorderCross; - - // For a relative children, we're either using alignItems (parent) or - // alignSelf (child) in order to determine the position in the cross axis - var/*css_align_t*/ alignItem = getAlignItem(node, child); - - // If the child uses align stretch, we need to lay it out one more time, this time - // forcing the cross-axis size to be the computed cross size for the current line. - if (alignItem === CSS_ALIGN_STRETCH) { - childWidth = child.layout.measuredWidth + getMarginAxis(child, CSS_FLEX_DIRECTION_ROW); - childHeight = child.layout.measuredHeight + getMarginAxis(child, CSS_FLEX_DIRECTION_COLUMN); - var/*bool*/ isCrossSizeDefinite = false; - - if (isMainAxisRow) { - isCrossSizeDefinite = isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN); - childHeight = crossDim; - } else { - isCrossSizeDefinite = isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW); - childWidth = crossDim; - } - - // If the child defines a definite size for its cross axis, there's no need to stretch. - if (!isCrossSizeDefinite) { - childWidthMeasureMode = isUndefined(childWidth) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_EXACTLY; - childHeightMeasureMode = isUndefined(childHeight) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_EXACTLY; - layoutNodeInternal(child, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, true, 'stretch'); - } - } else if (alignItem !== CSS_ALIGN_FLEX_START) { - var/*float*/ remainingCrossDim = containerCrossAxis - getDimWithMargin(child, crossAxis); - - if (alignItem === CSS_ALIGN_CENTER) { - leadingCrossDim += remainingCrossDim / 2; - } else { // CSS_ALIGN_FLEX_END - leadingCrossDim += remainingCrossDim; - } - } - - // And we apply the position - child.layout[pos[crossAxis]] += totalLineCrossDim + leadingCrossDim; - } - } - } - - totalLineCrossDim += crossDim; - maxLineMainDim = fmaxf(maxLineMainDim, mainDim); - - // Reset variables for new line. - lineCount++; - startOfLineIndex = endOfLineIndex; - endOfLineIndex = startOfLineIndex; - } - - // STEP 8: MULTI-LINE CONTENT ALIGNMENT - if (lineCount > 1 && performLayout && !isUndefined(availableInnerCrossDim)) { - var/*float*/ remainingAlignContentDim = availableInnerCrossDim - totalLineCrossDim; - - var/*float*/ crossDimLead = 0; - var/*float*/ currentLead = leadingPaddingAndBorderCross; - - var/*css_align_t*/ alignContent = getAlignContent(node); - if (alignContent === CSS_ALIGN_FLEX_END) { - currentLead += remainingAlignContentDim; - } else if (alignContent === CSS_ALIGN_CENTER) { - currentLead += remainingAlignContentDim / 2; - } else if (alignContent === CSS_ALIGN_STRETCH) { - if (availableInnerCrossDim > totalLineCrossDim) { - crossDimLead = (remainingAlignContentDim / lineCount); - } - } - - var/*int*/ endIndex = 0; - for (i = 0; i < lineCount; ++i) { - var/*int*/ startIndex = endIndex; - var/*int*/ j; - - // compute the line's height and find the endIndex - var/*float*/ lineHeight = 0; - for (j = startIndex; j < childCount; ++j) { - child = node.children[j]; - if (getPositionType(child) !== CSS_POSITION_RELATIVE) { - continue; - } - if (child.lineIndex !== i) { - break; - } - if (isLayoutDimDefined(child, crossAxis)) { - lineHeight = fmaxf(lineHeight, - child.layout[measuredDim[crossAxis]] + getMarginAxis(child, crossAxis)); - } - } - endIndex = j; - lineHeight += crossDimLead; - - if (performLayout) { - for (j = startIndex; j < endIndex; ++j) { - child = node.children[j]; - if (getPositionType(child) !== CSS_POSITION_RELATIVE) { - continue; - } - - var/*css_align_t*/ alignContentAlignItem = getAlignItem(node, child); - if (alignContentAlignItem === CSS_ALIGN_FLEX_START) { - child.layout[pos[crossAxis]] = currentLead + getLeadingMargin(child, crossAxis); - } else if (alignContentAlignItem === CSS_ALIGN_FLEX_END) { - child.layout[pos[crossAxis]] = currentLead + lineHeight - getTrailingMargin(child, crossAxis) - child.layout[measuredDim[crossAxis]]; - } else if (alignContentAlignItem === CSS_ALIGN_CENTER) { - childHeight = child.layout[measuredDim[crossAxis]]; - child.layout[pos[crossAxis]] = currentLead + (lineHeight - childHeight) / 2; - } else if (alignContentAlignItem === CSS_ALIGN_STRETCH) { - child.layout[pos[crossAxis]] = currentLead + getLeadingMargin(child, crossAxis); - // TODO(prenaux): Correctly set the height of items with indefinite - // (auto) crossAxis dimension. - } - } - } - - currentLead += lineHeight; - } - } - - // STEP 9: COMPUTING FINAL DIMENSIONS - node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW, availableWidth - marginAxisRow); - node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, availableHeight - marginAxisColumn); - - // If the user didn't specify a width or height for the node, set the - // dimensions based on the children. - if (measureModeMainDim === CSS_MEASURE_MODE_UNDEFINED) { - // Clamp the size to the min/max size, if specified, and make sure it - // doesn't go below the padding and border amount. - node.layout[measuredDim[mainAxis]] = boundAxis(node, mainAxis, maxLineMainDim); - } else if (measureModeMainDim === CSS_MEASURE_MODE_AT_MOST) { - node.layout[measuredDim[mainAxis]] = fmaxf( - fminf(availableInnerMainDim + paddingAndBorderAxisMain, - boundAxisWithinMinAndMax(node, mainAxis, maxLineMainDim)), - paddingAndBorderAxisMain); - } - - if (measureModeCrossDim === CSS_MEASURE_MODE_UNDEFINED) { - // Clamp the size to the min/max size, if specified, and make sure it - // doesn't go below the padding and border amount. - node.layout[measuredDim[crossAxis]] = boundAxis(node, crossAxis, totalLineCrossDim + paddingAndBorderAxisCross); - } else if (measureModeCrossDim === CSS_MEASURE_MODE_AT_MOST) { - node.layout[measuredDim[crossAxis]] = fmaxf( - fminf(availableInnerCrossDim + paddingAndBorderAxisCross, - boundAxisWithinMinAndMax(node, crossAxis, totalLineCrossDim + paddingAndBorderAxisCross)), - paddingAndBorderAxisCross); - } - - // STEP 10: SETTING TRAILING POSITIONS FOR CHILDREN - if (performLayout) { - var/*bool*/ needsMainTrailingPos = false; - var/*bool*/ needsCrossTrailingPos = false; - - if (mainAxis === CSS_FLEX_DIRECTION_ROW_REVERSE || - mainAxis === CSS_FLEX_DIRECTION_COLUMN_REVERSE) { - needsMainTrailingPos = true; - } - - if (crossAxis === CSS_FLEX_DIRECTION_ROW_REVERSE || - crossAxis === CSS_FLEX_DIRECTION_COLUMN_REVERSE) { - needsCrossTrailingPos = true; - } - - // Set trailing position if necessary. - if (needsMainTrailingPos || needsCrossTrailingPos) { - for (i = 0; i < childCount; ++i) { - child = node.children[i]; - - if (needsMainTrailingPos) { - setTrailingPosition(node, child, mainAxis); - } - - if (needsCrossTrailingPos) { - setTrailingPosition(node, child, crossAxis); - } - } - } - } - - // STEP 11: SIZING AND POSITIONING ABSOLUTE CHILDREN - currentAbsoluteChild = firstAbsoluteChild; - while (currentAbsoluteChild !== undefined) { - // Now that we know the bounds of the container, perform layout again on the - // absolutely-positioned children. - if (performLayout) { - - childWidth = CSS_UNDEFINED; - childHeight = CSS_UNDEFINED; - - if (isStyleDimDefined(currentAbsoluteChild, CSS_FLEX_DIRECTION_ROW)) { - childWidth = currentAbsoluteChild.style.width + getMarginAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_ROW); - } else { - // If the child doesn't have a specified width, compute the width based on the left/right offsets if they're defined. - if (isPosDefined(currentAbsoluteChild, CSS_LEFT) && isPosDefined(currentAbsoluteChild, CSS_RIGHT)) { - childWidth = node.layout.measuredWidth - - (getLeadingBorder(node, CSS_FLEX_DIRECTION_ROW) + getTrailingBorder(node, CSS_FLEX_DIRECTION_ROW)) - - (currentAbsoluteChild.style[CSS_LEFT] + currentAbsoluteChild.style[CSS_RIGHT]); - childWidth = boundAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_ROW, childWidth); - } - } - - if (isStyleDimDefined(currentAbsoluteChild, CSS_FLEX_DIRECTION_COLUMN)) { - childHeight = currentAbsoluteChild.style.height + getMarginAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_COLUMN); - } else { - // If the child doesn't have a specified height, compute the height based on the top/bottom offsets if they're defined. - if (isPosDefined(currentAbsoluteChild, CSS_TOP) && isPosDefined(currentAbsoluteChild, CSS_BOTTOM)) { - childHeight = node.layout.measuredHeight - - (getLeadingBorder(node, CSS_FLEX_DIRECTION_COLUMN) + getTrailingBorder(node, CSS_FLEX_DIRECTION_COLUMN)) - - (currentAbsoluteChild.style[CSS_TOP] + currentAbsoluteChild.style[CSS_BOTTOM]); - childHeight = boundAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_COLUMN, childHeight); - } - } - - // If we're still missing one or the other dimension, measure the content. - if (isUndefined(childWidth) || isUndefined(childHeight)) { - childWidthMeasureMode = isUndefined(childWidth) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_EXACTLY; - childHeightMeasureMode = isUndefined(childHeight) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_EXACTLY; - - // According to the spec, if the main size is not definite and the - // child's inline axis is parallel to the main axis (i.e. it's - // horizontal), the child should be sized using "UNDEFINED" in - // the main size. Otherwise use "AT_MOST" in the cross axis. - if (!isMainAxisRow && isUndefined(childWidth) && !isUndefined(availableInnerWidth)) { - childWidth = availableInnerWidth; - childWidthMeasureMode = CSS_MEASURE_MODE_AT_MOST; - } - - // The W3C spec doesn't say anything about the 'overflow' property, - // but all major browsers appear to implement the following logic. - if (getOverflow(node) === CSS_OVERFLOW_HIDDEN) { - if (isMainAxisRow && isUndefined(childHeight) && !isUndefined(availableInnerHeight)) { - childHeight = availableInnerHeight; - childHeightMeasureMode = CSS_MEASURE_MODE_AT_MOST; - } - } - - layoutNodeInternal(currentAbsoluteChild, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, false, 'abs-measure'); - childWidth = currentAbsoluteChild.layout.measuredWidth + getMarginAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_ROW); - childHeight = currentAbsoluteChild.layout.measuredHeight + getMarginAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_COLUMN); - } - - layoutNodeInternal(currentAbsoluteChild, childWidth, childHeight, direction, CSS_MEASURE_MODE_EXACTLY, CSS_MEASURE_MODE_EXACTLY, true, 'abs-layout'); - - if (isPosDefined(currentAbsoluteChild, trailing[CSS_FLEX_DIRECTION_ROW]) && - !isPosDefined(currentAbsoluteChild, leading[CSS_FLEX_DIRECTION_ROW])) { - currentAbsoluteChild.layout[leading[CSS_FLEX_DIRECTION_ROW]] = - node.layout[measuredDim[CSS_FLEX_DIRECTION_ROW]] - - currentAbsoluteChild.layout[measuredDim[CSS_FLEX_DIRECTION_ROW]] - - getPosition(currentAbsoluteChild, trailing[CSS_FLEX_DIRECTION_ROW]); - } - - if (isPosDefined(currentAbsoluteChild, trailing[CSS_FLEX_DIRECTION_COLUMN]) && - !isPosDefined(currentAbsoluteChild, leading[CSS_FLEX_DIRECTION_COLUMN])) { - currentAbsoluteChild.layout[leading[CSS_FLEX_DIRECTION_COLUMN]] = - node.layout[measuredDim[CSS_FLEX_DIRECTION_COLUMN]] - - currentAbsoluteChild.layout[measuredDim[CSS_FLEX_DIRECTION_COLUMN]] - - getPosition(currentAbsoluteChild, trailing[CSS_FLEX_DIRECTION_COLUMN]); - } - } - - currentAbsoluteChild = currentAbsoluteChild.nextChild; - } - } - - function canUseCachedMeasurement( - isTextNode, - availableWidth, - availableHeight, - marginRow, - marginColumn, - widthMeasureMode, - heightMeasureMode, - cachedLayout) { - - var isHeightSame = - (cachedLayout.heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED && heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED) || - (cachedLayout.heightMeasureMode == heightMeasureMode && cachedLayout.availableHeight == availableHeight); - - var isWidthSame = - (cachedLayout.widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED && widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED) || - (cachedLayout.widthMeasureMode == widthMeasureMode && cachedLayout.availableWidth == availableWidth); - - if (isHeightSame && isWidthSame) { - return true; - } - - var isHeightValid = - (cachedLayout.heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED && heightMeasureMode == CSS_MEASURE_MODE_AT_MOST && cachedLayout.computedHeight <= (availableHeight - marginColumn)) || - (heightMeasureMode == CSS_MEASURE_MODE_EXACTLY && cachedLayout.computedHeight == (availableHeight - marginColumn)); - - if (isWidthSame && isHeightValid) { - return true; - } - - var isWidthValid = - (cachedLayout.widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED && widthMeasureMode == CSS_MEASURE_MODE_AT_MOST && cachedLayout.computedWidth <= (availableWidth - marginRow)) || - (widthMeasureMode == CSS_MEASURE_MODE_EXACTLY && cachedLayout.computedWidth == (availableWidth - marginRow)); - - if (isHeightSame && isWidthValid) { - return true; - } - - if (isHeightValid && isWidthValid) { - return true; - } - - // We know this to be text so we can apply some more specialized heuristics. - if (isTextNode) { - if (isWidthSame) { - if (heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED) { - // Width is the same and height is not restricted. Re-use cahced value. - return true; - } - - if (heightMeasureMode == CSS_MEASURE_MODE_AT_MOST && - cachedLayout.computedHeight < (availableHeight - marginColumn)) { - // Width is the same and height restriction is greater than the cached height. Re-use cached value. - return true; - } - - // Width is the same but height restriction imposes smaller height than previously measured. - // Update the cached value to respect the new height restriction. - cachedLayout.computedHeight = availableHeight - marginColumn; - return true; - } - - if (cachedLayout.widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED) { - if (widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED || - (widthMeasureMode == CSS_MEASURE_MODE_AT_MOST && - cachedLayout.computedWidth <= (availableWidth - marginRow))) { - // Previsouly this text was measured with no width restriction, if width is now restricted - // but to a larger value than the previsouly measured width we can re-use the measurement - // as we know it will fit. - return true; - } - } - } - - return false; - } - - // - // This is a wrapper around the layoutNodeImpl function. It determines - // whether the layout request is redundant and can be skipped. - // - // Parameters: - // Input parameters are the same as layoutNodeImpl (see above) - // Return parameter is true if layout was performed, false if skipped - // - function layoutNodeInternal(node, availableWidth, availableHeight, parentDirection, - widthMeasureMode, heightMeasureMode, performLayout, reason) { - var layout = node.layout; - - var needToVisitNode = (node.isDirty && layout.generationCount !== gCurrentGenerationCount) || - layout.lastParentDirection !== parentDirection; - - if (needToVisitNode) { - // Invalidate the cached results. - if (layout.cachedMeasurements !== undefined) { - layout.cachedMeasurements = []; - } - if (layout.cachedLayout !== undefined) { - layout.cachedLayout.widthMeasureMode = undefined; - layout.cachedLayout.heightMeasureMode = undefined; - } - } - - var i; - var len; - var cachedResults; - - // Determine whether the results are already cached. We maintain a separate - // cache for layouts and measurements. A layout operation modifies the positions - // and dimensions for nodes in the subtree. The algorithm assumes that each node - // gets layed out a maximum of one time per tree layout, but multiple measurements - // may be required to resolve all of the flex dimensions. - // We handle nodes with measure functions specially here because they are the most - // expensive to measure, so it's worth avoiding redundant measurements if at all possible. - if (isMeasureDefined(node)) { - var marginAxisRow = getMarginAxis(node, CSS_FLEX_DIRECTION_ROW); - var marginAxisColumn = getMarginAxis(node, CSS_FLEX_DIRECTION_COLUMN); - - // First, try to use the layout cache. - if (layout.cachedLayout && - canUseCachedMeasurement(node.isTextNode, availableWidth, availableHeight, marginAxisRow, marginAxisColumn, - widthMeasureMode, heightMeasureMode, layout.cachedLayout)) { - cachedResults = layout.cachedLayout; - } else if (layout.cachedMeasurements) { - // Try to use the measurement cache. - for (i = 0, len = layout.cachedMeasurements.length; i < len; i++) { - if (canUseCachedMeasurement(node.isTextNode, availableWidth, availableHeight, marginAxisRow, marginAxisColumn, - widthMeasureMode, heightMeasureMode, layout.cachedMeasurements[i])) { - cachedResults = layout.cachedMeasurements[i]; - break; - } - } - } - } else if (performLayout) { - if (layout.cachedLayout && - layout.cachedLayout.availableWidth === availableWidth && - layout.cachedLayout.availableHeight === availableHeight && - layout.cachedLayout.widthMeasureMode === widthMeasureMode && - layout.cachedLayout.heightMeasureMode === heightMeasureMode) { - cachedResults = layout.cachedLayout; - } - } else if (layout.cachedMeasurements) { - for (i = 0, len = layout.cachedMeasurements.length; i < len; i++) { - if (layout.cachedMeasurements[i].availableWidth === availableWidth && - layout.cachedMeasurements[i].availableHeight === availableHeight && - layout.cachedMeasurements[i].widthMeasureMode === widthMeasureMode && - layout.cachedMeasurements[i].heightMeasureMode === heightMeasureMode) { - cachedResults = layout.cachedMeasurements[i]; - break; - } - } - } - - if (!needToVisitNode && cachedResults !== undefined) { - layout.measureWidth = cachedResults.computedWidth; - layout.measureHeight = cachedResults.computedHeight; - } else { - layoutNodeImpl(node, availableWidth, availableHeight, parentDirection, widthMeasureMode, heightMeasureMode, performLayout); - layout.lastParentDirection = parentDirection; - - if (cachedResults === undefined) { - var newCacheEntry; - if (performLayout) { - // Use the single layout cache entry. - if (layout.cachedLayout === undefined) { - layout.cachedLayout = {}; - } - newCacheEntry = layout.cachedLayout; - } else { - // Allocate a new measurement cache entry. - if (layout.cachedMeasurements === undefined) { - layout.cachedMeasurements = []; - } - newCacheEntry = {}; - layout.cachedMeasurements.push(newCacheEntry); - } - - newCacheEntry.availableWidth = availableWidth; - newCacheEntry.availableHeight = availableHeight; - newCacheEntry.widthMeasureMode = widthMeasureMode; - newCacheEntry.heightMeasureMode = heightMeasureMode; - newCacheEntry.computedWidth = layout.measuredWidth; - newCacheEntry.computedHeight = layout.measuredHeight; - } - } - - if (performLayout) { - node.layout.width = node.layout.measuredWidth; - node.layout.height = node.layout.measuredHeight; - layout.shouldUpdate = true; - } - - layout.generationCount = gCurrentGenerationCount; - return (needToVisitNode || cachedResults === undefined); - } - - function layoutNode(node, availableWidth, availableHeight, parentDirection) { - // Increment the generation count. This will force the recursive routine to visit - // all dirty nodes at least once. Subsequent visits will be skipped if the input - // parameters don't change. - gCurrentGenerationCount++; - - var widthMeasureMode = CSS_MEASURE_MODE_UNDEFINED; - var heightMeasureMode = CSS_MEASURE_MODE_UNDEFINED; - - if (!isUndefined(availableWidth)) { - widthMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } else if (isStyleDimDefined(node, CSS_FLEX_DIRECTION_ROW)) { - availableWidth = node.style.width + getMarginAxis(node, CSS_FLEX_DIRECTION_ROW); - widthMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } else if (node.style.maxWidth >= 0.0) { - availableWidth = node.style.maxWidth; - widthMeasureMode = CSS_MEASURE_MODE_AT_MOST; - } - - if (!isUndefined(availableHeight)) { - heightMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } else if (isStyleDimDefined(node, CSS_FLEX_DIRECTION_COLUMN)) { - availableHeight = node.style.height + getMarginAxis(node, CSS_FLEX_DIRECTION_COLUMN); - heightMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } else if (node.style.maxHeight >= 0.0) { - availableHeight = node.style.maxHeight; - heightMeasureMode = CSS_MEASURE_MODE_AT_MOST; - } - - if (layoutNodeInternal(node, availableWidth, availableHeight, parentDirection, widthMeasureMode, heightMeasureMode, true, 'initial')) { - setPosition(node, node.layout.direction); - } - } - - return { - layoutNodeImpl: layoutNodeImpl, - computeLayout: layoutNode, - fillNodes: fillNodes, - canUseCachedMeasurement: canUseCachedMeasurement - }; -})(); - -// This module export is only used for the purposes of unit testing this file. When -// the library is packaged this file is included within css-layout.js which forms -// the public API. -if (typeof exports === 'object') { - module.exports = computeLayout; -} - - - return function(node) { - /*eslint-disable */ - // disabling ESLint because this code relies on the above include - computeLayout.fillNodes(node); - computeLayout.computeLayout(node); - /*eslint-enable */ - }; -})); diff --git a/dist/css-layout.min.js b/dist/css-layout.min.js deleted file mode 100644 index e4a5f417..00000000 --- a/dist/css-layout.min.js +++ /dev/null @@ -1,2 +0,0 @@ -!function(a,b){"function"==typeof define&&define.amd?define([],b):"object"==typeof exports?module.exports=b():a.computeLayout=b()}(this,function(){var a=function(){function a(b){if((!b.layout||b.isDirty)&&(b.layout={width:void 0,height:void 0,top:0,left:0,right:0,bottom:0}),b.style||(b.style={}),b.children||(b.children=[]),b.style.measure&&b.children&&b.children.length)throw new Error("Using custom measure function is supported only for leaf nodes.");return b.children.forEach(a),b}function b(a){return void 0===a||Number.isNaN(a)}function c(a){return a===da||a===ea}function d(a){return a===fa||a===ga}function e(a){return void 0===a.style.flex?0:a.style.flex}function f(a){return W?!0:e(a)<=0}function g(a){return e(a)>0?e(a):0}function h(a){if(W){if(0!==e(a))return 1}else if(e(a)<0)return 1;return 0}function i(a,b){if(void 0!==a.style.marginStart&&c(b))return a.style.marginStart;var d=null;switch(b){case"row":d=a.style.marginLeft;break;case"row-reverse":d=a.style.marginRight;break;case"column":d=a.style.marginTop;break;case"column-reverse":d=a.style.marginBottom}return void 0!==d?d:void 0!==a.style.margin?a.style.margin:0}function j(a,b){if(void 0!==a.style.marginEnd&&c(b))return a.style.marginEnd;var d=null;switch(b){case"row":d=a.style.marginRight;break;case"row-reverse":d=a.style.marginLeft;break;case"column":d=a.style.marginBottom;break;case"column-reverse":d=a.style.marginTop}return null!=d?d:void 0!==a.style.margin?a.style.margin:0}function k(a,b){if(void 0!==a.style.paddingStart&&a.style.paddingStart>=0&&c(b))return a.style.paddingStart;var d=null;switch(b){case"row":d=a.style.paddingLeft;break;case"row-reverse":d=a.style.paddingRight;break;case"column":d=a.style.paddingTop;break;case"column-reverse":d=a.style.paddingBottom}return null!=d&&d>=0?d:void 0!==a.style.padding&&a.style.padding>=0?a.style.padding:0}function l(a,b){if(void 0!==a.style.paddingEnd&&a.style.paddingEnd>=0&&c(b))return a.style.paddingEnd;var d=null;switch(b){case"row":d=a.style.paddingRight;break;case"row-reverse":d=a.style.paddingLeft;break;case"column":d=a.style.paddingBottom;break;case"column-reverse":d=a.style.paddingTop}return null!=d&&d>=0?d:void 0!==a.style.padding&&a.style.padding>=0?a.style.padding:0}function m(a,b){if(void 0!==a.style.borderStartWidth&&a.style.borderStartWidth>=0&&c(b))return a.style.borderStartWidth;var d=null;switch(b){case"row":d=a.style.borderLeftWidth;break;case"row-reverse":d=a.style.borderRightWidth;break;case"column":d=a.style.borderTopWidth;break;case"column-reverse":d=a.style.borderBottomWidth}return null!=d&&d>=0?d:void 0!==a.style.borderWidth&&a.style.borderWidth>=0?a.style.borderWidth:0}function n(a,b){if(void 0!==a.style.borderEndWidth&&a.style.borderEndWidth>=0&&c(b))return a.style.borderEndWidth;var d=null;switch(b){case"row":d=a.style.borderRightWidth;break;case"row-reverse":d=a.style.borderLeftWidth;break;case"column":d=a.style.borderBottomWidth;break;case"column-reverse":d=a.style.borderTopWidth}return null!=d&&d>=0?d:void 0!==a.style.borderWidth&&a.style.borderWidth>=0?a.style.borderWidth:0}function o(a,b){return k(a,b)+m(a,b)}function p(a,b){return l(a,b)+n(a,b)}function q(a,b){return i(a,b)+j(a,b)}function r(a,b){return o(a,b)+p(a,b)}function s(a){return a.style.justifyContent?a.style.justifyContent:"flex-start"}function t(a){return a.style.alignContent?a.style.alignContent:"flex-start"}function u(a,b){return b.style.alignSelf?b.style.alignSelf:a.style.alignItems?a.style.alignItems:"stretch"}function v(a,b){if(b===ca){if(a===da)return ea;if(a===ea)return da}return a}function w(a,b){var c;return c=a.style.direction?a.style.direction:aa,c===aa&&(c=void 0===b?ba:b),c}function x(a){return a.style.flexDirection?a.style.flexDirection:fa}function y(a,b){return d(a)?v(da,b):fa}function z(a){return a.style.position?a.style.position:qa}function A(a){return a.style.overflow?a.style.overflow:sa}function B(a){return z(a)===qa&&void 0!==a.style.flex&&0!==a.style.flex}function C(a){return"wrap"===a.style.flexWrap}function D(a,b){return a.layout[Ba[b]]+q(a,b)}function E(a,b){return void 0!==a.style[Aa[b]]&&a.style[Aa[b]]>=0}function F(a,b){return void 0!==a.layout[Ba[b]]&&a.layout[Ba[b]]>=0}function G(a,b){return void 0!==a.style[b]}function H(a){return void 0!==a.style.measure}function I(a,b){return void 0!==a.style[b]?a.style[b]:0}function J(a,b,c){var d={row:a.style.minWidth,"row-reverse":a.style.minWidth,column:a.style.minHeight,"column-reverse":a.style.minHeight}[b],e={row:a.style.maxWidth,"row-reverse":a.style.maxWidth,column:a.style.maxHeight,"column-reverse":a.style.maxHeight}[b],f=c;return void 0!==e&&e>=0&&f>e&&(f=e),void 0!==d&&d>=0&&d>f&&(f=d),f}function K(a,b){return b>a?a:b}function L(a,b){return a>b?a:b}function M(a,b,c){return L(J(a,b,c),r(a,b))}function N(a,b,c){var d=z(b)===ra?0:b.layout[Ba[c]];b.layout[ya[c]]=a.layout[Ba[c]]-d-b.layout[za[c]]}function O(a,b){return void 0!==a.style[xa[b]]?I(a,xa[b]):-I(a,ya[b])}function P(a,b){var c=v(x(a),b),d=y(c,b);a.layout[xa[c]]=i(a,c)+O(a,c),a.layout[ya[c]]=j(a,c)+O(a,c),a.layout[xa[d]]=i(a,d)+O(a,d),a.layout[ya[d]]=j(a,d)+O(a,d)}function Q(a,b){if(!a)throw new Error(b)}function R(a,d,e,k,l,O,R){Q(b(d)?l===ua:!0,"availableWidth is indefinite so widthMeasureMode must be CSS_MEASURE_MODE_UNDEFINED"),Q(b(e)?O===ua:!0,"availableHeight is indefinite so heightMeasureMode must be CSS_MEASURE_MODE_UNDEFINED");var S=r(a,da),U=r(a,fa),W=q(a,da),X=q(a,fa),aa=w(a,k);if(a.layout.direction=aa,H(a)){var ba=d-W-S,ca=e-X-U;if(l===va&&O===va)a.layout.measuredWidth=M(a,da,d-W),a.layout.measuredHeight=M(a,fa,e-X);else if(0>=ba||0>=ca)a.layout.measuredWidth=M(a,da,0),a.layout.measuredHeight=M(a,fa,0);else{var sa=a.style.measure(ba,l,ca,O);a.layout.measuredWidth=M(a,da,l===ua||l===wa?sa.width+S:d-W),a.layout.measuredHeight=M(a,fa,O===ua||O===wa?sa.height+U:e-X)}}else{var Aa=a.children.length;if(0===Aa)return a.layout.measuredWidth=M(a,da,l===ua||l===wa?S:d-W),void(a.layout.measuredHeight=M(a,fa,O===ua||O===wa?U:e-X));if(!R){if(l===wa&&0>=d&&O===wa&&0>=e)return a.layout.measuredWidth=M(a,da,0),void(a.layout.measuredHeight=M(a,fa,0));if(l===wa&&0>=d)return a.layout.measuredWidth=M(a,da,0),void(a.layout.measuredHeight=M(a,fa,b(e)?0:e-X));if(O===wa&&0>=e)return a.layout.measuredWidth=M(a,da,b(d)?0:d-W),void(a.layout.measuredHeight=M(a,fa,0));if(l===va&&O===va)return a.layout.measuredWidth=M(a,da,d-W),void(a.layout.measuredHeight=M(a,fa,e-X))}var Ca,Da,Ea,Fa,Ga,Ha,Ia=v(x(a),aa),Ja=y(Ia,aa),Ka=c(Ia),La=s(a),Ma=C(a),Na=void 0,Oa=void 0,Pa=o(a,Ia),Qa=p(a,Ia),Ra=o(a,Ja),Sa=r(a,Ia),Ta=r(a,Ja),Ua=Ka?l:O,Va=Ka?O:l,Wa=d-W-S,Xa=e-X-U,Ya=Ka?Wa:Xa,Za=Ka?Xa:Wa;for(Da=0;Aa>Da;Da++){if(Ca=a.children[Da],R){var $a=w(Ca,aa);P(Ca,$a)}z(Ca)===ra?(void 0===Na&&(Na=Ca),void 0!==Oa&&(Oa.nextChild=Ca),Oa=Ca,Ca.nextChild=void 0):Ka&&E(Ca,da)?Ca.layout.flexBasis=L(Ca.style.width,r(Ca,da)):!Ka&&E(Ca,fa)?Ca.layout.flexBasis=L(Ca.style.height,r(Ca,fa)):f(Ca)||b(Ya)?(Ea=V,Fa=V,Ga=ua,Ha=ua,E(Ca,da)&&(Ea=Ca.style.width+q(Ca,da),Ga=va),E(Ca,fa)&&(Fa=Ca.style.height+q(Ca,fa),Ha=va),Ka||!b(Ea)||b(Wa)||(Ea=Wa,Ga=wa),A(a)===ta&&Ka&&b(Fa)&&!b(Xa)&&(Fa=Xa,Ha=wa),Ka||b(Wa)||E(Ca,da)||l!=va||u(a,Ca)!=pa||(Ea=Wa,Ga=va),!Ka||b(Xa)||E(Ca,fa)||O!=va||u(a,Ca)!=pa||(Fa=Xa,Ha=va),T(Ca,Ea,Fa,aa,Ga,Ha,!1,"measure"),Ca.layout.flexBasis=L(Ka?Ca.layout.measuredWidth:Ca.layout.measuredHeight,r(Ca,Ia))):Ca.layout.flexBasis=L(0,r(Ca,Ia))}for(var _a=0,ab=0,bb=0,cb=0,db=0;Aa>ab;){var eb=0,fb=0,gb=0,hb=0;Da=_a;for(var ib=void 0,jb=void 0;Aa>Da;){if(Ca=a.children[Da],Ca.lineIndex=bb,z(Ca)!==ra){var kb=Ca.layout.flexBasis+q(Ca,Ia);if(fb+kb>Ya&&Ma&&eb>0)break;fb+=kb,eb++,B(Ca)&&(gb+=g(Ca),hb+=h(Ca)*Ca.layout.flexBasis),void 0===ib&&(ib=Ca),void 0!==jb&&(jb.nextChild=Ca),jb=Ca,Ca.nextChild=void 0}Da++,ab++}var lb=!R&&Va===va,mb=0,nb=0,ob=0;b(Ya)?0>fb&&(ob=-fb):ob=Ya-fb;var pb=ob,qb=0;if(!lb){var rb,sb,tb,ub,vb,wb=0,xb=0;for(jb=ib;void 0!==jb;)rb=jb.layout.flexBasis,0>ob?(sb=h(jb)*rb,0!==sb&&(ub=rb+ob/hb*sb,vb=M(jb,Ia,ub),ub!==vb&&(qb-=vb-rb,wb-=sb))):ob>0&&(tb=g(jb),0!==tb&&(ub=rb+ob/gb*tb,vb=M(jb,Ia,ub),ub!==vb&&(qb-=vb-rb,xb-=tb))),jb=jb.nextChild;for(hb+=wb,gb+=xb,ob+=qb,qb=0,jb=ib;void 0!==jb;){rb=jb.layout.flexBasis;var yb=rb;0>ob?(sb=h(jb)*rb,0!==sb&&(yb=M(jb,Ia,rb+ob/hb*sb))):ob>0&&(tb=g(jb),0!==tb&&(yb=M(jb,Ia,rb+ob/gb*tb))),qb-=yb-rb,Ka?(Ea=yb+q(jb,da),Ga=va,b(Za)||E(jb,fa)||O!=va||u(a,jb)!=pa?E(jb,fa)?(Fa=jb.style.height+q(jb,fa),Ha=va):(Fa=Za,Ha=b(Fa)?ua:wa):(Fa=Za,Ha=va)):(Fa=yb+q(jb,fa),Ha=va,b(Za)||E(jb,da)||l!=va||u(a,jb)!=pa?E(jb,da)?(Ea=jb.style.width+q(jb,da),Ga=va):(Ea=Za,Ga=b(Ea)?ua:wa):(Ea=Za,Ga=va));var zb=!E(jb,Ja)&&u(a,jb)===pa;T(jb,Ea,Fa,aa,Ga,Ha,R&&!zb,"flex"),jb=jb.nextChild}}ob=pb+qb,Ua===wa&&(ob=0),La!==ha&&(La===ia?mb=ob/2:La===ja?mb=ob:La===ka?(ob=L(ob,0),nb=eb>1?ob/(eb-1):0):La===la&&(nb=ob/eb,mb=nb/2));var Ab=Pa+mb,Bb=0;for(Da=_a;ab>Da;++Da)Ca=a.children[Da],z(Ca)===ra&&G(Ca,xa[Ia])?R&&(Ca.layout[za[Ia]]=I(Ca,xa[Ia])+m(a,Ia)+i(Ca,Ia)):(R&&(Ca.layout[za[Ia]]+=Ab),z(Ca)===qa&&(lb?(Ab+=nb+q(Ca,Ia)+Ca.layout.flexBasis,Bb=Za):(Ab+=nb+D(Ca,Ia),Bb=L(Bb,D(Ca,Ja)))));Ab+=Qa;var Cb=Za;if((Va===ua||Va===wa)&&(Cb=M(a,Ja,Bb+Ta)-Ta,Va===wa&&(Cb=K(Cb,Za))),Ma||Va!==va||(Bb=Za),Bb=M(a,Ja,Bb+Ta)-Ta,R)for(Da=_a;ab>Da;++Da)if(Ca=a.children[Da],z(Ca)===ra)G(Ca,xa[Ja])?Ca.layout[za[Ja]]=I(Ca,xa[Ja])+m(a,Ja)+i(Ca,Ja):Ca.layout[za[Ja]]=Ra+i(Ca,Ja);else{var Db=Ra,Eb=u(a,Ca);if(Eb===pa){Ea=Ca.layout.measuredWidth+q(Ca,da),Fa=Ca.layout.measuredHeight+q(Ca,fa);var Fb=!1;Ka?(Fb=E(Ca,fa),Fa=Bb):(Fb=E(Ca,da),Ea=Bb),Fb||(Ga=b(Ea)?ua:va,Ha=b(Fa)?ua:va,T(Ca,Ea,Fa,aa,Ga,Ha,!0,"stretch"))}else if(Eb!==ma){var Gb=Cb-D(Ca,Ja);Db+=Eb===na?Gb/2:Gb}Ca.layout[za[Ja]]+=cb+Db}cb+=Bb,db=L(db,Ab),bb++,_a=ab,ab=_a}if(bb>1&&R&&!b(Za)){var Hb=Za-cb,Ib=0,Jb=Ra,Kb=t(a);Kb===oa?Jb+=Hb:Kb===na?Jb+=Hb/2:Kb===pa&&Za>cb&&(Ib=Hb/bb);var Lb=0;for(Da=0;bb>Da;++Da){var Mb,Nb=Lb,Ob=0;for(Mb=Nb;Aa>Mb;++Mb)if(Ca=a.children[Mb],z(Ca)===qa){if(Ca.lineIndex!==Da)break;F(Ca,Ja)&&(Ob=L(Ob,Ca.layout[Ba[Ja]]+q(Ca,Ja)))}if(Lb=Mb,Ob+=Ib,R)for(Mb=Nb;Lb>Mb;++Mb)if(Ca=a.children[Mb],z(Ca)===qa){var Pb=u(a,Ca);Pb===ma?Ca.layout[za[Ja]]=Jb+i(Ca,Ja):Pb===oa?Ca.layout[za[Ja]]=Jb+Ob-j(Ca,Ja)-Ca.layout[Ba[Ja]]:Pb===na?(Fa=Ca.layout[Ba[Ja]],Ca.layout[za[Ja]]=Jb+(Ob-Fa)/2):Pb===pa&&(Ca.layout[za[Ja]]=Jb+i(Ca,Ja))}Jb+=Ob}}if(a.layout.measuredWidth=M(a,da,d-W),a.layout.measuredHeight=M(a,fa,e-X),Ua===ua?a.layout[Ba[Ia]]=M(a,Ia,db):Ua===wa&&(a.layout[Ba[Ia]]=L(K(Ya+Sa,J(a,Ia,db)),Sa)),Va===ua?a.layout[Ba[Ja]]=M(a,Ja,cb+Ta):Va===wa&&(a.layout[Ba[Ja]]=L(K(Za+Ta,J(a,Ja,cb+Ta)),Ta)),R){var Qb=!1,Rb=!1;if((Ia===ea||Ia===ga)&&(Qb=!0),(Ja===ea||Ja===ga)&&(Rb=!0),Qb||Rb)for(Da=0;Aa>Da;++Da)Ca=a.children[Da],Qb&&N(a,Ca,Ia),Rb&&N(a,Ca,Ja)}for(Oa=Na;void 0!==Oa;)R&&(Ea=V,Fa=V,E(Oa,da)?Ea=Oa.style.width+q(Oa,da):G(Oa,Y)&&G(Oa,$)&&(Ea=a.layout.measuredWidth-(m(a,da)+n(a,da))-(Oa.style[Y]+Oa.style[$]),Ea=M(Oa,da,Ea)),E(Oa,fa)?Fa=Oa.style.height+q(Oa,fa):G(Oa,Z)&&G(Oa,_)&&(Fa=a.layout.measuredHeight-(m(a,fa)+n(a,fa))-(Oa.style[Z]+Oa.style[_]),Fa=M(Oa,fa,Fa)),(b(Ea)||b(Fa))&&(Ga=b(Ea)?ua:va,Ha=b(Fa)?ua:va,Ka||!b(Ea)||b(Wa)||(Ea=Wa,Ga=wa),A(a)===ta&&Ka&&b(Fa)&&!b(Xa)&&(Fa=Xa,Ha=wa),T(Oa,Ea,Fa,aa,Ga,Ha,!1,"abs-measure"),Ea=Oa.layout.measuredWidth+q(Oa,da),Fa=Oa.layout.measuredHeight+q(Oa,fa)),T(Oa,Ea,Fa,aa,va,va,!0,"abs-layout"),G(Oa,ya[da])&&!G(Oa,xa[da])&&(Oa.layout[xa[da]]=a.layout[Ba[da]]-Oa.layout[Ba[da]]-I(Oa,ya[da])),G(Oa,ya[fa])&&!G(Oa,xa[fa])&&(Oa.layout[xa[fa]]=a.layout[Ba[fa]]-Oa.layout[Ba[fa]]-I(Oa,ya[fa]))),Oa=Oa.nextChild}}function S(a,b,c,d,e,f,g,h){var i=h.heightMeasureMode==ua&&g==ua||h.heightMeasureMode==g&&h.availableHeight==c,j=h.widthMeasureMode==ua&&f==ua||h.widthMeasureMode==f&&h.availableWidth==b;if(i&&j)return!0;var k=h.heightMeasureMode==ua&&g==wa&&h.computedHeight<=c-e||g==va&&h.computedHeight==c-e;if(j&&k)return!0;var l=h.widthMeasureMode==ua&&f==wa&&h.computedWidth<=b-d||f==va&&h.computedWidth==b-d;if(i&&l)return!0;if(k&&l)return!0;if(a){if(j)return g==ua?!0:g==wa&&h.computedHeightk;k++)if(S(a.isTextNode,b,c,n,o,e,f,i.cachedMeasurements[k])){m=i.cachedMeasurements[k];break}}else if(g)i.cachedLayout&&i.cachedLayout.availableWidth===b&&i.cachedLayout.availableHeight===c&&i.cachedLayout.widthMeasureMode===e&&i.cachedLayout.heightMeasureMode===f&&(m=i.cachedLayout);else if(i.cachedMeasurements)for(k=0,l=i.cachedMeasurements.length;l>k;k++)if(i.cachedMeasurements[k].availableWidth===b&&i.cachedMeasurements[k].availableHeight===c&&i.cachedMeasurements[k].widthMeasureMode===e&&i.cachedMeasurements[k].heightMeasureMode===f){m=i.cachedMeasurements[k];break}if(j||void 0===m){if(R(a,b,c,d,e,f,g),i.lastParentDirection=d,void 0===m){var p;g?(void 0===i.cachedLayout&&(i.cachedLayout={}),p=i.cachedLayout):(void 0===i.cachedMeasurements&&(i.cachedMeasurements=[]),p={},i.cachedMeasurements.push(p)),p.availableWidth=b,p.availableHeight=c,p.widthMeasureMode=e,p.heightMeasureMode=f,p.computedWidth=i.measuredWidth,p.computedHeight=i.measuredHeight}}else i.measureWidth=m.computedWidth,i.measureHeight=m.computedHeight;return g&&(a.layout.width=a.layout.measuredWidth,a.layout.height=a.layout.measuredHeight,i.shouldUpdate=!0),i.generationCount=X,j||void 0===m}function U(a,c,d,e){X++;var f=ua,g=ua;b(c)?E(a,da)?(c=a.style.width+q(a,da),f=va):a.style.maxWidth>=0&&(c=a.style.maxWidth,f=wa):f=va,b(d)?E(a,fa)?(d=a.style.height+q(a,fa),g=va):a.style.maxHeight>=0&&(d=a.style.maxHeight,g=wa):g=va,T(a,c,d,e,f,g,!0,"initial")&&P(a,a.layout.direction)}var V,W=!1,X=0,Y="left",Z="top",$="right",_="bottom",aa="inherit",ba="ltr",ca="rtl",da="row",ea="row-reverse",fa="column",ga="column-reverse",ha="flex-start",ia="center",ja="flex-end",ka="space-between",la="space-around",ma="flex-start",na="center",oa="flex-end",pa="stretch",qa="relative",ra="absolute",sa="visible",ta="hidden",ua="undefined",va="exactly",wa="at-most",xa={row:"left","row-reverse":"right",column:"top","column-reverse":"bottom"},ya={row:"right","row-reverse":"left",column:"bottom","column-reverse":"top"},za={row:"left","row-reverse":"right",column:"top","column-reverse":"bottom"},Aa={row:"width","row-reverse":"width",column:"height","column-reverse":"height"},Ba={row:"measuredWidth","row-reverse":"measuredWidth",column:"measuredHeight","column-reverse":"measuredHeight"};return{layoutNodeImpl:R,computeLayout:U,fillNodes:a,canUseCachedMeasurement:S}}();return"object"==typeof exports&&(module.exports=a),function(b){a.fillNodes(b),a.computeLayout(b)}}); -//# sourceMappingURL=css-layout.min.js.map \ No newline at end of file diff --git a/dist/css-layout.min.js.map b/dist/css-layout.min.js.map deleted file mode 100644 index d7beff52..00000000 --- a/dist/css-layout.min.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["css-layout.js"],"names":["root","factory","define","amd","exports","module","computeLayout","this","fillNodes","node","layout","isDirty","width","undefined","height","top","left","right","bottom","style","children","measure","length","Error","forEach","isUndefined","value","Number","isNaN","isRowDirection","flexDirection","CSS_FLEX_DIRECTION_ROW","CSS_FLEX_DIRECTION_ROW_REVERSE","isColumnDirection","CSS_FLEX_DIRECTION_COLUMN","CSS_FLEX_DIRECTION_COLUMN_REVERSE","getFlex","flex","isFlexBasisAuto","POSITIVE_FLEX_IS_AUTO","getFlexGrowFactor","getFlexShrinkFactor","getLeadingMargin","axis","marginStart","marginLeft","marginRight","marginTop","marginBottom","margin","getTrailingMargin","marginEnd","getLeadingPadding","paddingStart","paddingLeft","paddingRight","paddingTop","paddingBottom","padding","getTrailingPadding","paddingEnd","getLeadingBorder","borderStartWidth","borderLeftWidth","borderRightWidth","borderTopWidth","borderBottomWidth","borderWidth","getTrailingBorder","borderEndWidth","getLeadingPaddingAndBorder","getTrailingPaddingAndBorder","getMarginAxis","getPaddingAndBorderAxis","getJustifyContent","justifyContent","getAlignContent","alignContent","getAlignItem","child","alignSelf","alignItems","resolveAxis","direction","CSS_DIRECTION_RTL","resolveDirection","parentDirection","CSS_DIRECTION_INHERIT","CSS_DIRECTION_LTR","getFlexDirection","getCrossFlexDirection","getPositionType","position","CSS_POSITION_RELATIVE","getOverflow","overflow","CSS_OVERFLOW_VISIBLE","isFlex","isFlexWrap","flexWrap","getDimWithMargin","measuredDim","isStyleDimDefined","dim","isLayoutDimDefined","isPosDefined","pos","isMeasureDefined","getPosition","boundAxisWithinMinAndMax","min","row","minWidth","row-reverse","column","minHeight","column-reverse","max","maxWidth","maxHeight","boundValue","fminf","a","b","fmaxf","boundAxis","setTrailingPosition","size","CSS_POSITION_ABSOLUTE","trailing","getRelativePosition","leading","setPosition","mainAxis","crossAxis","assert","condition","message","layoutNodeImpl","availableWidth","availableHeight","widthMeasureMode","heightMeasureMode","performLayout","CSS_MEASURE_MODE_UNDEFINED","paddingAndBorderAxisRow","paddingAndBorderAxisColumn","marginAxisRow","marginAxisColumn","innerWidth","innerHeight","CSS_MEASURE_MODE_EXACTLY","measuredWidth","measuredHeight","measureDim","CSS_MEASURE_MODE_AT_MOST","childCount","i","childWidth","childHeight","childWidthMeasureMode","childHeightMeasureMode","isMainAxisRow","isNodeFlexWrap","firstAbsoluteChild","currentAbsoluteChild","leadingPaddingAndBorderMain","trailingPaddingAndBorderMain","leadingPaddingAndBorderCross","paddingAndBorderAxisMain","paddingAndBorderAxisCross","measureModeMainDim","measureModeCrossDim","availableInnerWidth","availableInnerHeight","availableInnerMainDim","availableInnerCrossDim","childDirection","nextChild","flexBasis","CSS_UNDEFINED","CSS_OVERFLOW_HIDDEN","CSS_ALIGN_STRETCH","layoutNodeInternal","startOfLineIndex","endOfLineIndex","lineCount","totalLineCrossDim","maxLineMainDim","itemsOnLine","sizeConsumedOnCurrentLine","totalFlexGrowFactors","totalFlexShrinkScaledFactors","firstRelativeChild","currentRelativeChild","lineIndex","outerFlexBasis","canSkipFlex","leadingMainDim","betweenMainDim","remainingFreeSpace","originalRemainingFreeSpace","deltaFreeSpace","childFlexBasis","flexShrinkScaledFactor","flexGrowFactor","baseMainSize","boundMainSize","deltaFlexShrinkScaledFactors","deltaFlexGrowFactors","updatedMainSize","requiresStretchLayout","CSS_JUSTIFY_FLEX_START","CSS_JUSTIFY_CENTER","CSS_JUSTIFY_FLEX_END","CSS_JUSTIFY_SPACE_BETWEEN","CSS_JUSTIFY_SPACE_AROUND","mainDim","crossDim","containerCrossAxis","leadingCrossDim","alignItem","isCrossSizeDefinite","CSS_ALIGN_FLEX_START","remainingCrossDim","CSS_ALIGN_CENTER","remainingAlignContentDim","crossDimLead","currentLead","CSS_ALIGN_FLEX_END","endIndex","j","startIndex","lineHeight","alignContentAlignItem","needsMainTrailingPos","needsCrossTrailingPos","CSS_LEFT","CSS_RIGHT","CSS_TOP","CSS_BOTTOM","canUseCachedMeasurement","isTextNode","marginRow","marginColumn","cachedLayout","isHeightSame","isWidthSame","isHeightValid","computedHeight","isWidthValid","computedWidth","reason","needToVisitNode","generationCount","gCurrentGenerationCount","lastParentDirection","cachedMeasurements","len","cachedResults","newCacheEntry","push","measureWidth","measureHeight","shouldUpdate","layoutNode"],"mappings":"CAKC,SAASA,EAAMC,GACQ,kBAAXC,SAAyBA,OAAOC,IAEzCD,UAAWD,GACiB,gBAAZG,SAIhBC,OAAOD,QAAUH,IAGjBD,EAAKM,cAAgBL,KAEvBM,KAAM,WAUR,GAAID,GAAgB,WA6ElB,QAASE,GAAUC,GAoBjB,KAnBKA,EAAKC,QAAUD,EAAKE,WACvBF,EAAKC,QACHE,MAAOC,OACPC,OAAQD,OACRE,IAAK,EACLC,KAAM,EACNC,MAAO,EACPC,OAAQ,IAIPT,EAAKU,QACRV,EAAKU,UAGFV,EAAKW,WACRX,EAAKW,aAGHX,EAAKU,MAAME,SAAWZ,EAAKW,UAAYX,EAAKW,SAASE,OACvD,KAAM,IAAIC,OAAM,kEAIlB,OADAd,GAAKW,SAASI,QAAQhB,GACfC,EAGT,QAASgB,GAAYC,GACnB,MAAiBb,UAAVa,GAAuBC,OAAOC,MAAMF,GAG7C,QAASG,GAAeC,GACtB,MAAOA,KAAkBC,IAClBD,IAAkBE,GAG3B,QAASC,GAAkBH,GACzB,MAAOA,KAAkBI,IAClBJ,IAAkBK,GAG3B,QAASC,GAAQ3B,GACf,MAAwBI,UAApBJ,EAAKU,MAAMkB,KACN,EAEF5B,EAAKU,MAAMkB,KAGpB,QAASC,GAAgB7B,GACvB,MAAI8B,IAEK,EAGAH,EAAQ3B,IAAS,EAI5B,QAAS+B,GAAkB/B,GAEzB,MAAI2B,GAAQ3B,GAAQ,EACX2B,EAAQ3B,GAEV,EAGT,QAASgC,GAAoBhC,GAC3B,GAAI8B,GAEF,GAAsB,IAAlBH,EAAQ3B,GACV,MAAO,OAIT,IAAI2B,EAAQ3B,GAAQ,EAClB,MAAO,EAGX,OAAO,GAGT,QAASiC,GAAiBjC,EAAMkC,GAC9B,GAA+B9B,SAA3BJ,EAAKU,MAAMyB,aAA6Bf,EAAec,GACzD,MAAOlC,GAAKU,MAAMyB,WAGpB,IAAIlB,GAAQ,IACZ,QAAQiB,GACN,IAAK,MAAkBjB,EAAQjB,EAAKU,MAAM0B,UAAc,MACxD,KAAK,cAAkBnB,EAAQjB,EAAKU,MAAM2B,WAAc,MACxD,KAAK,SAAkBpB,EAAQjB,EAAKU,MAAM4B,SAAc,MACxD,KAAK,iBAAkBrB,EAAQjB,EAAKU,MAAM6B,aAG5C,MAAcnC,UAAVa,EACKA,EAGiBb,SAAtBJ,EAAKU,MAAM8B,OACNxC,EAAKU,MAAM8B,OAGb,EAGT,QAASC,GAAkBzC,EAAMkC,GAC/B,GAA6B9B,SAAzBJ,EAAKU,MAAMgC,WAA2BtB,EAAec,GACvD,MAAOlC,GAAKU,MAAMgC,SAGpB,IAAIzB,GAAQ,IACZ,QAAQiB,GACN,IAAK,MAAkBjB,EAAQjB,EAAKU,MAAM2B,WAAc,MACxD,KAAK,cAAkBpB,EAAQjB,EAAKU,MAAM0B,UAAc,MACxD,KAAK,SAAkBnB,EAAQjB,EAAKU,MAAM6B,YAAc,MACxD,KAAK,iBAAkBtB,EAAQjB,EAAKU,MAAM4B,UAG5C,MAAa,OAATrB,EACKA,EAGiBb,SAAtBJ,EAAKU,MAAM8B,OACNxC,EAAKU,MAAM8B,OAGb,EAGT,QAASG,GAAkB3C,EAAMkC,GAC/B,GAAgC9B,SAA5BJ,EAAKU,MAAMkC,cAA8B5C,EAAKU,MAAMkC,cAAgB,GACjExB,EAAec,GACpB,MAAOlC,GAAKU,MAAMkC,YAGpB,IAAI3B,GAAQ,IACZ,QAAQiB,GACN,IAAK,MAAkBjB,EAAQjB,EAAKU,MAAMmC,WAAe,MACzD,KAAK,cAAkB5B,EAAQjB,EAAKU,MAAMoC,YAAe,MACzD,KAAK,SAAkB7B,EAAQjB,EAAKU,MAAMqC,UAAe,MACzD,KAAK,iBAAkB9B,EAAQjB,EAAKU,MAAMsC,cAG5C,MAAa,OAAT/B,GAAiBA,GAAS,EACrBA,EAGkBb,SAAvBJ,EAAKU,MAAMuC,SAAyBjD,EAAKU,MAAMuC,SAAW,EACrDjD,EAAKU,MAAMuC,QAGb,EAGT,QAASC,GAAmBlD,EAAMkC,GAChC,GAA8B9B,SAA1BJ,EAAKU,MAAMyC,YAA4BnD,EAAKU,MAAMyC,YAAc,GAC7D/B,EAAec,GACpB,MAAOlC,GAAKU,MAAMyC,UAGpB,IAAIlC,GAAQ,IACZ,QAAQiB,GACN,IAAK,MAAkBjB,EAAQjB,EAAKU,MAAMoC,YAAe,MACzD,KAAK,cAAkB7B,EAAQjB,EAAKU,MAAMmC,WAAe,MACzD,KAAK,SAAkB5B,EAAQjB,EAAKU,MAAMsC,aAAe,MACzD,KAAK,iBAAkB/B,EAAQjB,EAAKU,MAAMqC,WAG5C,MAAa,OAAT9B,GAAiBA,GAAS,EACrBA,EAGkBb,SAAvBJ,EAAKU,MAAMuC,SAAyBjD,EAAKU,MAAMuC,SAAW,EACrDjD,EAAKU,MAAMuC,QAGb,EAGT,QAASG,GAAiBpD,EAAMkC,GAC9B,GAAoC9B,SAAhCJ,EAAKU,MAAM2C,kBAAkCrD,EAAKU,MAAM2C,kBAAoB,GACzEjC,EAAec,GACpB,MAAOlC,GAAKU,MAAM2C,gBAGpB,IAAIpC,GAAQ,IACZ,QAAQiB,GACN,IAAK,MAAkBjB,EAAQjB,EAAKU,MAAM4C,eAAmB,MAC7D,KAAK,cAAkBrC,EAAQjB,EAAKU,MAAM6C,gBAAmB,MAC7D,KAAK,SAAkBtC,EAAQjB,EAAKU,MAAM8C,cAAmB,MAC7D,KAAK,iBAAkBvC,EAAQjB,EAAKU,MAAM+C,kBAG5C,MAAa,OAATxC,GAAiBA,GAAS,EACrBA,EAGsBb,SAA3BJ,EAAKU,MAAMgD,aAA6B1D,EAAKU,MAAMgD,aAAe,EAC7D1D,EAAKU,MAAMgD,YAGb,EAGT,QAASC,GAAkB3D,EAAMkC,GAC/B,GAAkC9B,SAA9BJ,EAAKU,MAAMkD,gBAAgC5D,EAAKU,MAAMkD,gBAAkB,GACrExC,EAAec,GACpB,MAAOlC,GAAKU,MAAMkD,cAGpB,IAAI3C,GAAQ,IACZ,QAAQiB,GACN,IAAK,MAAkBjB,EAAQjB,EAAKU,MAAM6C,gBAAmB,MAC7D,KAAK,cAAkBtC,EAAQjB,EAAKU,MAAM4C,eAAmB,MAC7D,KAAK,SAAkBrC,EAAQjB,EAAKU,MAAM+C,iBAAmB,MAC7D,KAAK,iBAAkBxC,EAAQjB,EAAKU,MAAM8C,eAG5C,MAAa,OAATvC,GAAiBA,GAAS,EACrBA,EAGsBb,SAA3BJ,EAAKU,MAAMgD,aAA6B1D,EAAKU,MAAMgD,aAAe,EAC7D1D,EAAKU,MAAMgD,YAGb,EAGT,QAASG,GAA2B7D,EAAMkC,GACxC,MAAOS,GAAkB3C,EAAMkC,GAAQkB,EAAiBpD,EAAMkC,GAGhE,QAAS4B,GAA4B9D,EAAMkC,GACzC,MAAOgB,GAAmBlD,EAAMkC,GAAQyB,EAAkB3D,EAAMkC,GAGlE,QAAS6B,GAAc/D,EAAMkC,GAC3B,MAAOD,GAAiBjC,EAAMkC,GAAQO,EAAkBzC,EAAMkC,GAGhE,QAAS8B,GAAwBhE,EAAMkC,GACrC,MAAO2B,GAA2B7D,EAAMkC,GACpC4B,EAA4B9D,EAAMkC,GAGxC,QAAS+B,GAAkBjE,GACzB,MAAIA,GAAKU,MAAMwD,eACNlE,EAAKU,MAAMwD,eAEb,aAGT,QAASC,GAAgBnE,GACvB,MAAIA,GAAKU,MAAM0D,aACNpE,EAAKU,MAAM0D,aAEb,aAGT,QAASC,GAAarE,EAAMsE,GAC1B,MAAIA,GAAM5D,MAAM6D,UACPD,EAAM5D,MAAM6D,UAEjBvE,EAAKU,MAAM8D,WACNxE,EAAKU,MAAM8D,WAEb,UAGT,QAASC,GAAYvC,EAAMwC,GACzB,GAAIA,IAAcC,GAAmB,CACnC,GAAIzC,IAASZ,GACX,MAAOC,GACF,IAAIW,IAASX,GAClB,MAAOD,IAIX,MAAOY,GAGT,QAAS0C,GAAiB5E,EAAM6E,GAC9B,GAAIH,EAWJ,OATEA,GADE1E,EAAKU,MAAMgE,UACD1E,EAAKU,MAAMgE,UAEXI,GAGVJ,IAAcI,KAChBJ,EAAiCtE,SAApByE,EAAgCE,GAAoBF,GAG5DH,EAGT,QAASM,GAAiBhF,GACxB,MAAIA,GAAKU,MAAMW,cACNrB,EAAKU,MAAMW,cAEbI,GAGT,QAASwD,GAAsB5D,EAAeqD,GAC5C,MAAIlD,GAAkBH,GACboD,EAAYnD,GAAwBoD,GAEpCjD,GAIX,QAASyD,GAAgBlF,GACvB,MAAIA,GAAKU,MAAMyE,SACNnF,EAAKU,MAAMyE,SAEbC,GAGT,QAASC,GAAYrF,GACnB,MAAIA,GAAKU,MAAM4E,SACNtF,EAAKU,MAAM4E,SAEbC,GAGT,QAASC,GAAOxF,GACd,MACEkF,GAAgBlF,KAAUoF,IACNhF,SAApBJ,EAAKU,MAAMkB,MAA0C,IAApB5B,EAAKU,MAAMkB,KAIhD,QAAS6D,GAAWzF,GAClB,MAA+B,SAAxBA,EAAKU,MAAMgF,SAGpB,QAASC,GAAiB3F,EAAMkC,GAC9B,MAAOlC,GAAKC,OAAO2F,GAAY1D,IAAS6B,EAAc/D,EAAMkC,GAG9D,QAAS2D,GAAkB7F,EAAMkC,GAC/B,MAAiC9B,UAA1BJ,EAAKU,MAAMoF,GAAI5D,KAAwBlC,EAAKU,MAAMoF,GAAI5D,KAAU,EAGzE,QAAS6D,GAAmB/F,EAAMkC,GAChC,MAA0C9B,UAAnCJ,EAAKC,OAAO2F,GAAY1D,KAAwBlC,EAAKC,OAAO2F,GAAY1D,KAAU,EAG3F,QAAS8D,GAAahG,EAAMiG,GAC1B,MAA2B7F,UAApBJ,EAAKU,MAAMuF,GAGpB,QAASC,GAAiBlG,GACxB,MAA8BI,UAAvBJ,EAAKU,MAAME,QAGpB,QAASuF,GAAYnG,EAAMiG,GACzB,MAAwB7F,UAApBJ,EAAKU,MAAMuF,GACNjG,EAAKU,MAAMuF,GAEb,EAGT,QAASG,GAAyBpG,EAAMkC,EAAMjB,GAC5C,GAAIoF,IACFC,IAAOtG,EAAKU,MAAM6F,SAClBC,cAAexG,EAAKU,MAAM6F,SAC1BE,OAAUzG,EAAKU,MAAMgG,UACrBC,iBAAkB3G,EAAKU,MAAMgG,WAC7BxE,GAEE0E,GACFN,IAAOtG,EAAKU,MAAMmG,SAClBL,cAAexG,EAAKU,MAAMmG,SAC1BJ,OAAUzG,EAAKU,MAAMoG,UACrBH,iBAAkB3G,EAAKU,MAAMoG,WAC7B5E,GAEE6E,EAAa9F,CAOjB,OANYb,UAARwG,GAAqBA,GAAO,GAAKG,EAAaH,IAChDG,EAAaH,GAEHxG,SAARiG,GAAqBA,GAAO,GAAkBA,EAAbU,IACnCA,EAAaV,GAERU,EAGT,QAASC,GAAMC,EAAGC,GAChB,MAAQA,GAAJD,EACKA,EAEFC,EAGT,QAASC,GAAMF,EAAGC,GAChB,MAAID,GAAIC,EACCD,EAEFC,EAKT,QAASE,GAAUpH,EAAMkC,EAAMjB,GAC7B,MAAOkG,GAAMf,EAAyBpG,EAAMkC,EAAMjB,GAAQ+C,EAAwBhE,EAAMkC,IAG1F,QAASmF,GAAoBrH,EAAMsE,EAAOpC,GACxC,GAAIoF,GAAQpC,EAAgBZ,KAAWiD,GACrC,EACAjD,EAAMrE,OAAO2F,GAAY1D,GAC3BoC,GAAMrE,OAAOuH,GAAStF,IAASlC,EAAKC,OAAO2F,GAAY1D,IAASoF,EAAOhD,EAAMrE,OAAOgG,GAAI/D,IAK1F,QAASuF,GAAoBzH,EAAMkC,GACjC,MAAkC9B,UAA9BJ,EAAKU,MAAMgH,GAAQxF,IACdiE,EAAYnG,EAAM0H,GAAQxF,KAE3BiE,EAAYnG,EAAMwH,GAAStF,IAGrC,QAASyF,GAAY3H,EAAM0E,GACzB,GAAIkD,GAAWnD,EAAYO,EAAiBhF,GAAO0E,GAC/CmD,EAAY5C,EAAsB2C,EAAUlD,EAEhD1E,GAAKC,OAAOyH,GAAQE,IAAa3F,EAAiBjC,EAAM4H,GACtDH,EAAoBzH,EAAM4H,GAC5B5H,EAAKC,OAAOuH,GAASI,IAAanF,EAAkBzC,EAAM4H,GACxDH,EAAoBzH,EAAM4H,GAC5B5H,EAAKC,OAAOyH,GAAQG,IAAc5F,EAAiBjC,EAAM6H,GACvDJ,EAAoBzH,EAAM6H,GAC5B7H,EAAKC,OAAOuH,GAASK,IAAcpF,EAAkBzC,EAAM6H,GACzDJ,EAAoBzH,EAAM6H,GAG9B,QAASC,GAAOC,EAAWC,GACzB,IAAKD,EACH,KAAM,IAAIjH,OAAMkH,GA+EpB,QAASC,GAAejI,EAAMkI,EAAgBC,EAAoCtD,EAAiBuD,EAAkBC,EAAmBC,GACtIR,EAAO9G,EAAYkH,GAAkBE,IAAqBG,IAA6B,EAAM,uFAC7FT,EAAO9G,EAAYmH,GAAmBE,IAAsBE,IAA6B,EAAM,wFAE/F,IAAaC,GAA0BxE,EAAwBhE,EAAMsB,IACxDmH,EAA6BzE,EAAwBhE,EAAMyB,IAC3DiH,EAAgB3E,EAAc/D,EAAMsB,IACpCqH,EAAmB5E,EAAc/D,EAAMyB,IAG7BiD,GAAYE,EAAiB5E,EAAM6E,EAI1D,IAHA7E,EAAKC,OAAOyE,UAAYA,GAGpBwB,EAAiBlG,GAArB,CACE,GAAa4I,IAAaV,EAAiBQ,EAAgBF,EAC9CK,GAAcV,EAAkBQ,EAAmBF,CAEhE,IAAIL,IAAqBU,IAA4BT,IAAsBS,GAGzE9I,EAAKC,OAAO8I,cAAgB3B,EAAUpH,EAAMsB,GAAwB4G,EAAiBQ,GACrF1I,EAAKC,OAAO+I,eAAiB5B,EAAUpH,EAAMyB,GAA2B0G,EAAkBQ,OACrF,IAAkB,GAAdC,IAAkC,GAAfC,GAG5B7I,EAAKC,OAAO8I,cAAgB3B,EAAUpH,EAAMsB,GAAwB,GACpEtB,EAAKC,OAAO+I,eAAiB5B,EAAUpH,EAAMyB,GAA2B,OACnE,CAGL,GAAiBwH,IAAajJ,EAAKU,MAAME,QAGvCgI,GACAR,EACAS,GACAR,EAGFrI,GAAKC,OAAO8I,cAAgB3B,EAAUpH,EAAMsB,GACzC8G,IAAqBG,IAA8BH,IAAqBc,GACvED,GAAW9I,MAAQqI,EACnBN,EAAiBQ,GACrB1I,EAAKC,OAAO+I,eAAiB5B,EAAUpH,EAAMyB,GAC1C4G,IAAsBE,IAA8BF,IAAsBa,GACzED,GAAW5I,OAASoI,EACpBN,EAAkBQ,QAjC1B,CAyCA,GAAWQ,IAAanJ,EAAKW,SAASE,MACtC,IAAmB,IAAfsI,GASF,MARAnJ,GAAKC,OAAO8I,cAAgB3B,EAAUpH,EAAMsB,GACzC8G,IAAqBG,IAA8BH,IAAqBc,GACvEV,EACAN,EAAiBQ,QACrB1I,EAAKC,OAAO+I,eAAiB5B,EAAUpH,EAAMyB,GAC1C4G,IAAsBE,IAA8BF,IAAsBa,GACzET,EACAN,EAAkBQ,GAMxB,KAAKL,EAAe,CAGlB,GAAIF,IAAqBc,IAA8C,GAAlBhB,GACjDG,IAAsBa,IAA+C,GAAnBf,EAGpD,MAFAnI,GAAKC,OAAO8I,cAAgB3B,EAAUpH,EAAMsB,GAAwB,QACpEtB,EAAKC,OAAO+I,eAAiB5B,EAAUpH,EAAMyB,GAA2B,GAI1E,IAAI2G,IAAqBc,IAA8C,GAAlBhB,EAGnD,MAFAlI,GAAKC,OAAO8I,cAAgB3B,EAAUpH,EAAMsB,GAAwB,QACpEtB,EAAKC,OAAO+I,eAAiB5B,EAAUpH,EAAMyB,GAA2BT,EAAYmH,GAAmB,EAAKA,EAAkBQ,GAIhI,IAAIN,IAAsBa,IAA+C,GAAnBf,EAGpD,MAFAnI,GAAKC,OAAO8I,cAAgB3B,EAAUpH,EAAMsB,GAAwBN,EAAYkH,GAAkB,EAAKA,EAAiBQ,QACxH1I,EAAKC,OAAO+I,eAAiB5B,EAAUpH,EAAMyB,GAA2B,GAK1E,IAAI2G,IAAqBU,IAA4BT,IAAsBS,GAGzE,MAFA9I,GAAKC,OAAO8I,cAAgB3B,EAAUpH,EAAMsB,GAAwB4G,EAAiBQ,QACrF1I,EAAKC,OAAO+I,eAAiB5B,EAAUpH,EAAMyB,GAA2B0G,EAAkBQ,IAM9F,GAyBmBrE,IACR8E,GACEC,GACAC,GACaC,GACAC,GA9BoB5B,GAAWnD,EAAYO,EAAiBhF,GAAO0E,IAC/CmD,GAAY5C,EAAsB2C,GAAUlD,IAC9E+E,GAAgBrI,EAAewG,IACtB1D,GAAiBD,EAAkBjE,GAC5C0J,GAAiBjE,EAAWzF,GAErB2J,GAAqBvJ,OACrBwJ,GAAuBxJ,OAE7ByJ,GAA8BhG,EAA2B7D,EAAM4H,IAC/DkC,GAA+BhG,EAA4B9D,EAAM4H,IACjEmC,GAA+BlG,EAA2B7D,EAAM6H,IAChEmC,GAA2BhG,EAAwBhE,EAAM4H,IACzDqC,GAA4BjG,EAAwBhE,EAAM6H,IAE7CqC,GAAqBT,GAAgBrB,EAAmBC,EACxD8B,GAAsBV,GAAgBpB,EAAoBD,EAGvEgC,GAAsBlC,EAAiBQ,EAAgBF,EACvD6B,GAAuBlC,EAAkBQ,EAAmBF,EAC5D6B,GAAwBb,GAAgBW,GAAsBC,GAC9DE,GAAyBd,GAAgBY,GAAuBD,EAS7E,KAAKhB,GAAI,EAAOD,GAAJC,GAAgBA,KAAK,CAG/B,GAFA9E,GAAQtE,EAAKW,SAASyI,IAElBd,EAAe,CAEjB,GAAuBkC,IAAiB5F,EAAiBN,GAAOI,GAChEiD,GAAYrD,GAAOkG,IAKjBtF,EAAgBZ,MAAWiD,IAIFnH,SAAvBuJ,KACFA,GAAqBrF,IAEMlE,SAAzBwJ,KACFA,GAAqBa,UAAYnG,IAEnCsF,GAAuBtF,GACvBA,GAAMmG,UAAYrK,QAGdqJ,IAAiB5D,EAAkBvB,GAAOhD,IAG5CgD,GAAMrE,OAAOyK,UAAYvD,EAAM7C,GAAM5D,MAAMP,MAAO6D,EAAwBM,GAAOhD,MACvEmI,IAAiB5D,EAAkBvB,GAAO7C,IAGpD6C,GAAMrE,OAAOyK,UAAYvD,EAAM7C,GAAM5D,MAAML,OAAQ2D,EAAwBM,GAAO7C,KACxEI,EAAgByC,KAAWtD,EAAYsJ,KAOjDjB,GAAasB,EACbrB,GAAcqB,EACdpB,GAAwBhB,GACxBiB,GAAyBjB,GAErB1C,EAAkBvB,GAAOhD,MAC3B+H,GAAa/E,GAAM5D,MAAMP,MAAQ4D,EAAcO,GAAOhD,IACtDiI,GAAwBT,IAEtBjD,EAAkBvB,GAAO7C,MAC3B6H,GAAchF,GAAM5D,MAAML,OAAS0D,EAAcO,GAAO7C,IACxD+H,GAAyBV,IAOtBW,KAAiBzI,EAAYqI,KAAgBrI,EAAYoJ,MAC5Df,GAAae,GACbb,GAAwBL,IAKtB7D,EAAYrF,KAAU4K,IACpBnB,IAAiBzI,EAAYsI,MAAiBtI,EAAYqJ,MAC5Df,GAAce,GACdb,GAAyBN,IAMxBO,IACAzI,EAAYoJ,KACZvE,EAAkBvB,GAAOhD,KAC1B8G,GAAoBU,IACpBzE,EAAarE,EAAMsE,KAAUuG,KAC/BxB,GAAae,GACbb,GAAwBT,KAEtBW,IACCzI,EAAYqJ,KACZxE,EAAkBvB,GAAO7C,KAC1B4G,GAAqBS,IACrBzE,EAAarE,EAAMsE,KAAUuG,KAC/BvB,GAAce,GACdb,GAAyBV,IAI3BgC,EAAmBxG,GAAO+E,GAAYC,GAAa5E,GAAW6E,GAAuBC,IAAwB,EAAO,WAEpHlF,GAAMrE,OAAOyK,UAAYvD,EAAMsC,GAAgBnF,GAAMrE,OAAO8I,cAAgBzE,GAAMrE,OAAO+I,eAAgBhF,EAAwBM,GAAOsD,MA1DxItD,GAAMrE,OAAOyK,UAAYvD,EAAM,EAAGnD,EAAwBM,GAAOsD,KA8EvE,IAZA,GAAWmD,IAAmB,EACnBC,GAAiB,EAGjBC,GAAY,EAGVC,GAAoB,EAGpBC,GAAiB,EAENhC,GAAjB6B,IAA6B,CAIlC,GAAWI,IAAc,EAMZC,GAA4B,EAE5BC,GAAuB,EACvBC,GAA+B,CAE5CnC,IAAI2B,EAOJ,KAJA,GAAmBS,IAAqBpL,OACrBqL,GAAuBrL,OAG/B+I,GAAJC,IAAgB,CAIrB,GAHA9E,GAAQtE,EAAKW,SAASyI,IACtB9E,GAAMoH,UAAYT,GAEd/F,EAAgBZ,MAAWiD,GAAuB,CACpD,GAAaoE,IAAiBrH,GAAMrE,OAAOyK,UAAY3G,EAAcO,GAAOsD,GAI5E,IAAIyD,GAA4BM,GAAiBrB,IAAyBZ,IAAkB0B,GAAc,EACxG,KAGFC,KAA6BM,GAC7BP,KAEI5F,EAAOlB,MACTgH,IAAwBvJ,EAAkBuC,IAI1CiH,IAAgCvJ,EAAoBsC,IAASA,GAAMrE,OAAOyK,WAIjDtK,SAAvBoL,KACFA,GAAqBlH,IAEMlE,SAAzBqL,KACFA,GAAqBhB,UAAYnG,IAEnCmH,GAAuBnH,GACvBA,GAAMmG,UAAYrK,OAGpBgJ,KACA4B,KAIF,GAAYY,KAAetD,GAAiB6B,KAAwBrB,GAKvD+C,GAAiB,EACjBC,GAAiB,EAMjBC,GAAqB,CAC7B/K,GAAYsJ,IAEsB,EAA5Be,KAITU,IAAsBV,IALtBU,GAAqBzB,GAAwBe,EAQ/C,IAAaW,IAA6BD,GAC7BE,GAAiB,CAE9B,KAAKL,GAAa,CAChB,GAAaM,IACAC,GACAC,GACAC,GACAC,GAgBAC,GAA+B,EAC/BC,GAAuB,CAEpC,KADAf,GAAuBD,GACSpL,SAAzBqL,IACLS,GAAiBT,GAAqBxL,OAAOyK,UAEpB,EAArBqB,IACFI,GAAyBnK,EAAoByJ,IAAwBS,GAGtC,IAA3BC,KACFE,GAAeH,GACbH,GAAqBR,GAA+BY,GACtDG,GAAgBlF,EAAUqE,GAAsB7D,GAAUyE,IACtDA,KAAiBC,KAInBL,IAAkBK,GAAgBJ,GAClCK,IAAgCJ,MAG3BJ,GAAqB,IAC9BK,GAAiBrK,EAAkB0J,IAGZ,IAAnBW,KACFC,GAAeH,GACbH,GAAqBT,GAAuBc,GAC9CE,GAAgBlF,EAAUqE,GAAsB7D,GAAUyE,IACtDA,KAAiBC,KAInBL,IAAkBK,GAAgBJ,GAClCM,IAAwBJ,MAK9BX,GAAuBA,GAAqBhB,SAU9C,KAPAc,IAAgCgB,GAChCjB,IAAwBkB,GACxBT,IAAsBE,GAGtBA,GAAiB,EACjBR,GAAuBD,GACSpL,SAAzBqL,IAAoC,CACzCS,GAAiBT,GAAqBxL,OAAOyK,SAC7C,IAAa+B,IAAkBP,EAEN,GAArBH,IACFI,GAAyBnK,EAAoByJ,IAAwBS,GAGtC,IAA3BC,KACFM,GAAkBrF,EAAUqE,GAAsB7D,GAAUsE,GAC1DH,GAAqBR,GAA+BY,MAE/CJ,GAAqB,IAC9BK,GAAiBrK,EAAkB0J,IAGZ,IAAnBW,KACFK,GAAkBrF,EAAUqE,GAAsB7D,GAAUsE,GAC1DH,GAAqBT,GAAuBc,MAIlDH,IAAkBQ,GAAkBP,GAEhCzC,IACFJ,GAAaoD,GAAkB1I,EAAc0H,GAAsBnK,IACnEiI,GAAwBT,GAEnB9H,EAAYuJ,KACZ1E,EAAkB4F,GAAsBhK,KACzC4G,GAAqBS,IACrBzE,EAAarE,EAAMyL,KAAyBZ,GAGpChF,EAAkB4F,GAAsBhK,KAIlD6H,GAAcmC,GAAqB/K,MAAML,OAAS0D,EAAc0H,GAAsBhK,IACtF+H,GAAyBV,KAJzBQ,GAAciB,GACdf,GAAyBxI,EAAYsI,IAAef,GAA6BW,KAJjFI,GAAciB,GACdf,GAAyBV,MAS3BQ,GAAcmD,GAAkB1I,EAAc0H,GAAsBhK,IACpE+H,GAAyBV,GAEpB9H,EAAYuJ,KACZ1E,EAAkB4F,GAAsBnK,KACzC8G,GAAoBU,IACpBzE,EAAarE,EAAMyL,KAAyBZ,GAGpChF,EAAkB4F,GAAsBnK,KAIlD+H,GAAaoC,GAAqB/K,MAAMP,MAAQ4D,EAAc0H,GAAsBnK,IACpFiI,GAAwBT,KAJxBO,GAAakB,GACbhB,GAAwBvI,EAAYqI,IAAcd,GAA6BW,KAJ/EG,GAAakB,GACbhB,GAAwBT,IAU5B,IAAY4D,KAAyB7G,EAAkB4F,GAAsB5D,KAC3ExD,EAAarE,EAAMyL,MAA0BZ,EAG/CC,GAAmBW,GAAsBpC,GAAYC,GAAa5E,GAAW6E,GAAuBC,GAAwBlB,IAAkBoE,GAAuB,QAErKjB,GAAuBA,GAAqBhB,WAIhDsB,GAAqBC,GAA6BC,GAW9C/B,KAAuBhB,KACzB6C,GAAqB,GAKnB7H,KAAmByI,KACjBzI,KAAmB0I,GACrBf,GAAiBE,GAAqB,EAC7B7H,KAAmB2I,GAC5BhB,GAAiBE,GACR7H,KAAmB4I,IAC5Bf,GAAqB5E,EAAM4E,GAAoB,GAE7CD,GADEV,GAAc,EACCW,IAAsBX,GAAc,GAEpC,GAEVlH,KAAmB6I,KAE5BjB,GAAiBC,GAAqBX,GACtCS,GAAiBC,GAAiB,GAItC,IAAakB,IAAUnD,GAA8BgC,GACxCoB,GAAW,CAExB,KAAK7D,GAAI2B,GAAsBC,GAAJ5B,KAAsBA,GAC/C9E,GAAQtE,EAAKW,SAASyI,IAElBlE,EAAgBZ,MAAWiD,IAC3BvB,EAAa1B,GAAOoD,GAAQE,KAC1BU,IAIFhE,GAAMrE,OAAOgG,GAAI2B,KAAazB,EAAY7B,GAAOoD,GAAQE,KACvDxE,EAAiBpD,EAAM4H,IACvB3F,EAAiBqC,GAAOsD,MAGxBU,IAGFhE,GAAMrE,OAAOgG,GAAI2B,MAAcoF,IAM7B9H,EAAgBZ,MAAWc,KACzBwG,IAGFoB,IAAWlB,GAAiB/H,EAAcO,GAAOsD,IAAYtD,GAAMrE,OAAOyK,UAC1EuC,GAAW1C,KAIXyC,IAAWlB,GAAiBnG,EAAiBrB,GAAOsD,IAIpDqF,GAAW9F,EAAM8F,GAAUtH,EAAiBrB,GAAOuD,OAM3DmF,KAAWlD,EAEX,IAAaoD,IAAqB3C,EAoBlC,KAnBIJ,KAAwB5B,IAA8B4B,KAAwBjB,MAEhFgE,GAAqB9F,EAAUpH,EAAM6H,GAAWoF,GAAWhD,IAA6BA,GAEpFE,KAAwBjB,KAC1BgE,GAAqBlG,EAAMkG,GAAoB3C,MAK9Cb,IAAkBS,KAAwBrB,KAC7CmE,GAAW1C,IAIb0C,GAAW7F,EAAUpH,EAAM6H,GAAWoF,GAAWhD,IAA6BA,GAI1E3B,EACF,IAAKc,GAAI2B,GAAsBC,GAAJ5B,KAAsBA,GAG/C,GAFA9E,GAAQtE,EAAKW,SAASyI,IAElBlE,EAAgBZ,MAAWiD,GAGzBvB,EAAa1B,GAAOoD,GAAQG,KAC9BvD,GAAMrE,OAAOgG,GAAI4B,KAAc1B,EAAY7B,GAAOoD,GAAQG,KACxDzE,EAAiBpD,EAAM6H,IACvB5F,EAAiBqC,GAAOuD,IAE1BvD,GAAMrE,OAAOgG,GAAI4B,KAAckC,GAC7B9H,EAAiBqC,GAAOuD,QAEvB,CACL,GAAasF,IAAkBpD,GAIZqD,GAAY/I,EAAarE,EAAMsE,GAIlD,IAAI8I,KAAcvC,GAAmB,CACnCxB,GAAa/E,GAAMrE,OAAO8I,cAAgBhF,EAAcO,GAAOhD,IAC/DgI,GAAchF,GAAMrE,OAAO+I,eAAiBjF,EAAcO,GAAO7C,GACjE,IAAY4L,KAAsB,CAE9B5D,KACF4D,GAAsBxH,EAAkBvB,GAAO7C,IAC/C6H,GAAc2D,KAEdI,GAAsBxH,EAAkBvB,GAAOhD,IAC/C+H,GAAa4D,IAIVI,KACH9D,GAAwBvI,EAAYqI,IAAcd,GAA6BO,GAC/EU,GAAyBxI,EAAYsI,IAAef,GAA6BO,GACjFgC,EAAmBxG,GAAO+E,GAAYC,GAAa5E,GAAW6E,GAAuBC,IAAwB,EAAM,gBAEhH,IAAI4D,KAAcE,GAAsB,CAC7C,GAAaC,IAAoBL,GAAqBvH,EAAiBrB,GAAOuD,GAG5EsF,KADEC,KAAcI,GACGD,GAAoB,EAEpBA,GAKvBjJ,GAAMrE,OAAOgG,GAAI4B,MAAeqD,GAAoBiC,GAK1DjC,IAAqB+B,GACrB9B,GAAiBhE,EAAMgE,GAAgB6B,IAGvC/B,KACAF,GAAmBC,GACnBA,GAAiBD,GAInB,GAAIE,GAAY,GAAK3C,IAAkBtH,EAAYuJ,IAAyB,CAC1E,GAAakD,IAA2BlD,GAAyBW,GAEpDwC,GAAe,EACfC,GAAc5D,GAER3F,GAAeD,EAAgBnE,EAC9CoE,MAAiBwJ,GACnBD,IAAeF,GACNrJ,KAAiBoJ,GAC1BG,IAAeF,GAA2B,EACjCrJ,KAAiByG,IACtBN,GAAyBW,KAC3BwC,GAAgBD,GAA2BxC,GAI/C,IAAW4C,IAAW,CACtB,KAAKzE,GAAI,EAAO6B,GAAJ7B,KAAiBA,GAAG,CAC9B,GACW0E,IADAC,GAAaF,GAIXG,GAAa,CAC1B,KAAKF,GAAIC,GAAgB5E,GAAJ2E,KAAkBA,GAErC,GADAxJ,GAAQtE,EAAKW,SAASmN,IAClB5I,EAAgBZ,MAAWc,GAA/B,CAGA,GAAId,GAAMoH,YAActC,GACtB,KAEErD,GAAmBzB,GAAOuD,MAC5BmG,GAAa7G,EAAM6G,GACjB1J,GAAMrE,OAAO2F,GAAYiC,KAAc9D,EAAcO,GAAOuD,MAMlE,GAHAgG,GAAWC,GACXE,IAAcN,GAEVpF,EACF,IAAKwF,GAAIC,GAAgBF,GAAJC,KAAgBA,GAEnC,GADAxJ,GAAQtE,EAAKW,SAASmN,IAClB5I,EAAgBZ,MAAWc,GAA/B,CAIA,GAAmB6I,IAAwB5J,EAAarE,EAAMsE,GAC1D2J,MAA0BX,GAC5BhJ,GAAMrE,OAAOgG,GAAI4B,KAAc8F,GAAc1L,EAAiBqC,GAAOuD,IAC5DoG,KAA0BL,GACnCtJ,GAAMrE,OAAOgG,GAAI4B,KAAc8F,GAAcK,GAAavL,EAAkB6B,GAAOuD,IAAavD,GAAMrE,OAAO2F,GAAYiC,KAChHoG,KAA0BT,IACnClE,GAAchF,GAAMrE,OAAO2F,GAAYiC,KACvCvD,GAAMrE,OAAOgG,GAAI4B,KAAc8F,IAAeK,GAAa1E,IAAe,GACjE2E,KAA0BpD,KACnCvG,GAAMrE,OAAOgG,GAAI4B,KAAc8F,GAAc1L,EAAiBqC,GAAOuD,KAO3E8F,IAAeK,IAiCnB,GA5BAhO,EAAKC,OAAO8I,cAAgB3B,EAAUpH,EAAMsB,GAAwB4G,EAAiBQ,GACrF1I,EAAKC,OAAO+I,eAAiB5B,EAAUpH,EAAMyB,GAA2B0G,EAAkBQ,GAItFuB,KAAuB3B,GAGzBvI,EAAKC,OAAO2F,GAAYgC,KAAaR,EAAUpH,EAAM4H,GAAUuD,IACtDjB,KAAuBhB,KAChClJ,EAAKC,OAAO2F,GAAYgC,KAAaT,EACnCH,EAAMsD,GAAwBN,GAC5B5D,EAAyBpG,EAAM4H,GAAUuD,KAC3CnB,KAGAG,KAAwB5B,GAG1BvI,EAAKC,OAAO2F,GAAYiC,KAAcT,EAAUpH,EAAM6H,GAAWqD,GAAoBjB,IAC5EE,KAAwBjB,KACjClJ,EAAKC,OAAO2F,GAAYiC,KAAcV,EACpCH,EAAMuD,GAAyBN,GAC7B7D,EAAyBpG,EAAM6H,GAAWqD,GAAoBjB,KAChEA,KAIA3B,EAAe,CACjB,GAAY4F,KAAuB,EACvBC,IAAwB,CAapC,KAXIvG,KAAarG,IACbqG,KAAalG,MACfwM,IAAuB,IAGrBrG,KAActG,IACdsG,KAAcnG,MAChByM,IAAwB,GAItBD,IAAwBC,GAC1B,IAAK/E,GAAI,EAAOD,GAAJC,KAAkBA,GAC5B9E,GAAQtE,EAAKW,SAASyI,IAElB8E,IACF7G,EAAoBrH,EAAMsE,GAAOsD,IAG/BuG,IACF9G,EAAoBrH,EAAMsE,GAAOuD,IAQzC,IADA+B,GAAuBD,GACSvJ,SAAzBwJ,IAGDtB,IAEFe,GAAasB,EACbrB,GAAcqB,EAEV9E,EAAkB+D,GAAsBtI,IAC1C+H,GAAaO,GAAqBlJ,MAAMP,MAAQ4D,EAAc6F,GAAsBtI,IAGhF0E,EAAa4D,GAAsBwE,IAAapI,EAAa4D,GAAsByE,KACrFhF,GAAarJ,EAAKC,OAAO8I,eACtB3F,EAAiBpD,EAAMsB,IAA0BqC,EAAkB3D,EAAMsB,MACzEsI,GAAqBlJ,MAAM0N,GAAYxE,GAAqBlJ,MAAM2N,IACrEhF,GAAajC,EAAUwC,GAAsBtI,GAAwB+H,KAIrExD,EAAkB+D,GAAsBnI,IAC1C6H,GAAcM,GAAqBlJ,MAAML,OAAS0D,EAAc6F,GAAsBnI,IAGlFuE,EAAa4D,GAAsB0E,IAAYtI,EAAa4D,GAAsB2E,KACpFjF,GAActJ,EAAKC,OAAO+I,gBACvB5F,EAAiBpD,EAAMyB,IAA6BkC,EAAkB3D,EAAMyB,MAC5EmI,GAAqBlJ,MAAM4N,GAAW1E,GAAqBlJ,MAAM6N,IACpEjF,GAAclC,EAAUwC,GAAsBnI,GAA2B6H,MAKzEtI,EAAYqI,KAAerI,EAAYsI,OACzCC,GAAwBvI,EAAYqI,IAAcd,GAA6BO,GAC/EU,GAAyBxI,EAAYsI,IAAef,GAA6BO,GAM5EW,KAAiBzI,EAAYqI,KAAgBrI,EAAYoJ,MAC5Df,GAAae,GACbb,GAAwBL,IAKtB7D,EAAYrF,KAAU4K,IACpBnB,IAAiBzI,EAAYsI,MAAiBtI,EAAYqJ,MAC5Df,GAAce,GACdb,GAAyBN,IAI7B4B,EAAmBlB,GAAsBP,GAAYC,GAAa5E,GAAW6E,GAAuBC,IAAwB,EAAO,eACnIH,GAAaO,GAAqB3J,OAAO8I,cAAgBhF,EAAc6F,GAAsBtI,IAC7FgI,GAAcM,GAAqB3J,OAAO+I,eAAiBjF,EAAc6F,GAAsBnI,KAGjGqJ,EAAmBlB,GAAsBP,GAAYC,GAAa5E,GAAWoE,GAA0BA,IAA0B,EAAM,cAEnI9C,EAAa4D,GAAsBpC,GAASlG,OAC3C0E,EAAa4D,GAAsBlC,GAAQpG,OAC9CsI,GAAqB3J,OAAOyH,GAAQpG,KAClCtB,EAAKC,OAAO2F,GAAYtE,KACxBsI,GAAqB3J,OAAO2F,GAAYtE,KACxC6E,EAAYyD,GAAsBpC,GAASlG,MAG3C0E,EAAa4D,GAAsBpC,GAAS/F,OAC3CuE,EAAa4D,GAAsBlC,GAAQjG,OAC9CmI,GAAqB3J,OAAOyH,GAAQjG,KAClCzB,EAAKC,OAAO2F,GAAYnE,KACxBmI,GAAqB3J,OAAO2F,GAAYnE,KACxC0E,EAAYyD,GAAsBpC,GAAS/F,OAIjDmI,GAAuBA,GAAqBa,WAIhD,QAAS+D,GACLC,EACAvG,EACAC,EACAuG,EACAC,EACAvG,EACAC,EACAuG,GAEF,GAAIC,GACDD,EAAavG,mBAAqBE,IAA8BF,GAAqBE,IACnFqG,EAAavG,mBAAqBA,GAAqBuG,EAAazG,iBAAmBA,EAExF2G,EACDF,EAAaxG,kBAAoBG,IAA8BH,GAAoBG,IACjFqG,EAAaxG,kBAAoBA,GAAoBwG,EAAa1G,gBAAkBA,CAEzF,IAAI2G,GAAgBC,EAClB,OAAO,CAGT,IAAIC,GACDH,EAAavG,mBAAqBE,IAA8BF,GAAqBa,IAA4B0F,EAAaI,gBAAmB7G,EAAkBwG,GACjKtG,GAAqBS,IAA4B8F,EAAaI,gBAAmB7G,EAAkBwG,CAExG,IAAIG,GAAeC,EACjB,OAAO,CAGT,IAAIE,GACDL,EAAaxG,kBAAoBG,IAA8BH,GAAoBc,IAA4B0F,EAAaM,eAAkBhH,EAAiBwG,GAC7JtG,GAAoBU,IAA4B8F,EAAaM,eAAkBhH,EAAiBwG,CAErG,IAAIG,GAAgBI,EAClB,OAAO,CAGT,IAAIF,GAAiBE,EACnB,OAAO,CAIT,IAAIR,EAAY,CACd,GAAIK,EACF,MAAIzG,IAAqBE,IAEhB,EAGLF,GAAqBa,IACrB0F,EAAaI,eAAkB7G,EAAkBwG,GAE5C,GAKTC,EAAaI,eAAiB7G,EAAkBwG,GACzC,EAGT,IAAIC,EAAaxG,kBAAoBG,KAC/BH,GAAoBG,IAClBH,GAAoBc,IACpB0F,EAAaM,eAAkBhH,EAAiBwG,GAIpD,OAAO,EAKb,OAAO,EAWT,QAAS5D,GAAmB9K,EAAMkI,EAAgBC,EAAiBtD,EAC/DuD,EAAkBC,EAAmBC,EAAe6G,GACtD,GAAIlP,GAASD,EAAKC,OAEdmP,EAAmBpP,EAAKE,SAAWD,EAAOoP,kBAAoBC,GAChErP,EAAOsP,sBAAwB1K,CAE7BuK,KAEgChP,SAA9BH,EAAOuP,qBACTvP,EAAOuP,uBAEmBpP,SAAxBH,EAAO2O,eACT3O,EAAO2O,aAAaxG,iBAAmBhI,OACvCH,EAAO2O,aAAavG,kBAAoBjI,QAI5C,IAAIgJ,GACAqG,EACAC,CASJ,IAAIxJ,EAAiBlG,GAAO,CAC1B,GAAI0I,GAAgB3E,EAAc/D,EAAMsB,IACpCqH,EAAmB5E,EAAc/D,EAAMyB,GAG3C,IAAIxB,EAAO2O,cACPJ,EAAwBxO,EAAKyO,WAAYvG,EAAgBC,EAAiBO,EAAeC,EACvFP,EAAkBC,EAAmBpI,EAAO2O,cAChDc,EAAgBzP,EAAO2O,iBAClB,IAAI3O,EAAOuP,mBAEhB,IAAKpG,EAAI,EAAGqG,EAAMxP,EAAOuP,mBAAmB3O,OAAY4O,EAAJrG,EAASA,IAC3D,GAAIoF,EAAwBxO,EAAKyO,WAAYvG,EAAgBC,EAAiBO,EAAeC,EACzFP,EAAkBC,EAAmBpI,EAAOuP,mBAAmBpG,IAAK,CACtEsG,EAAgBzP,EAAOuP,mBAAmBpG,EAC1C,YAID,IAAId,EACLrI,EAAO2O,cACP3O,EAAO2O,aAAa1G,iBAAmBA,GACvCjI,EAAO2O,aAAazG,kBAAoBA,GACxClI,EAAO2O,aAAaxG,mBAAqBA,GACzCnI,EAAO2O,aAAavG,oBAAsBA,IAC5CqH,EAAgBzP,EAAO2O,kBAEpB,IAAI3O,EAAOuP,mBAChB,IAAKpG,EAAI,EAAGqG,EAAMxP,EAAOuP,mBAAmB3O,OAAY4O,EAAJrG,EAASA,IAC3D,GAAInJ,EAAOuP,mBAAmBpG,GAAGlB,iBAAmBA,GAChDjI,EAAOuP,mBAAmBpG,GAAGjB,kBAAoBA,GACjDlI,EAAOuP,mBAAmBpG,GAAGhB,mBAAqBA,GAClDnI,EAAOuP,mBAAmBpG,GAAGf,oBAAsBA,EAAmB,CACxEqH,EAAgBzP,EAAOuP,mBAAmBpG,EAC1C,OAKN,GAAKgG,GAAqChP,SAAlBsP,GAOtB,GAHAzH,EAAejI,EAAMkI,EAAgBC,EAAiBtD,EAAiBuD,EAAkBC,EAAmBC,GAC5GrI,EAAOsP,oBAAsB1K,EAEPzE,SAAlBsP,EAA6B,CAC/B,GAAIC,EACArH,IAE0BlI,SAAxBH,EAAO2O,eACT3O,EAAO2O,iBAETe,EAAgB1P,EAAO2O,eAGWxO,SAA9BH,EAAOuP,qBACTvP,EAAOuP,uBAETG,KACA1P,EAAOuP,mBAAmBI,KAAKD,IAGjCA,EAAczH,eAAiBA,EAC/ByH,EAAcxH,gBAAkBA,EAChCwH,EAAcvH,iBAAmBA,EACjCuH,EAActH,kBAAoBA,EAClCsH,EAAcT,cAAgBjP,EAAO8I,cACrC4G,EAAcX,eAAiB/O,EAAO+I,oBA5BxC/I,GAAO4P,aAAeH,EAAcR,cACpCjP,EAAO6P,cAAgBJ,EAAcV,cAsCvC,OAPI1G,KACFtI,EAAKC,OAAOE,MAAQH,EAAKC,OAAO8I,cAChC/I,EAAKC,OAAOI,OAASL,EAAKC,OAAO+I,eACjC/I,EAAO8P,cAAe,GAGxB9P,EAAOoP,gBAAkBC,EACjBF,GAAqChP,SAAlBsP,EAG7B,QAASM,GAAWhQ,EAAMkI,EAAgBC,EAAiBtD,GAIzDyK,GAEA,IAAIlH,GAAmBG,GACnBF,EAAoBE,EAEnBvH,GAAYkH,GAENrC,EAAkB7F,EAAMsB,KACjC4G,EAAiBlI,EAAKU,MAAMP,MAAQ4D,EAAc/D,EAAMsB,IACxD8G,EAAmBU,IACV9I,EAAKU,MAAMmG,UAAY,IAChCqB,EAAiBlI,EAAKU,MAAMmG,SAC5BuB,EAAmBc,IANnBd,EAAmBU,GAShB9H,EAAYmH,GAENtC,EAAkB7F,EAAMyB,KACjC0G,EAAkBnI,EAAKU,MAAML,OAAS0D,EAAc/D,EAAMyB,IAC1D4G,EAAoBS,IACX9I,EAAKU,MAAMoG,WAAa,IACjCqB,EAAkBnI,EAAKU,MAAMoG,UAC7BuB,EAAoBa,IANpBb,EAAoBS,GASlBgC,EAAmB9K,EAAMkI,EAAgBC,EAAiBtD,EAAiBuD,EAAkBC,GAAmB,EAAM,YACxHV,EAAY3H,EAAMA,EAAKC,OAAOyE,WA/oDlC,GAIIiG,GAJA7I,GAAwB,EAExBwN,EAA0B,EAI1BlB,EAAW,OACXE,EAAU,MACVD,EAAY,QACZE,EAAa,SAEbzJ,GAAwB,UACxBC,GAAoB,MACpBJ,GAAoB,MAEpBrD,GAAyB,MACzBC,GAAiC,cACjCE,GAA4B,SAC5BC,GAAoC,iBAEpCiL,GAAyB,aACzBC,GAAqB,SACrBC,GAAuB,WACvBC,GAA4B,gBAC5BC,GAA2B,eAE3BO,GAAuB,aACvBE,GAAmB,SACnBI,GAAqB,WACrB/C,GAAoB,UAEpBzF,GAAwB,WACxBmC,GAAwB,WAExBhC,GAAuB,UACvBqF,GAAsB,SAEtBrC,GAA6B,YAC7BO,GAA2B,UAC3BI,GAA2B,UAE3BxB,IACFpB,IAAO,OACPE,cAAe,QACfC,OAAU,MACVE,iBAAkB,UAEhBa,IACFlB,IAAO,QACPE,cAAe,OACfC,OAAU,SACVE,iBAAkB,OAEhBV,IACFK,IAAO,OACPE,cAAe,QACfC,OAAU,MACVE,iBAAkB,UAEhBb,IACFQ,IAAO,QACPE,cAAe,QACfC,OAAU,SACVE,iBAAkB,UAEhBf,IACFU,IAAO,gBACPE,cAAe,gBACfC,OAAU,iBACVE,iBAAkB,iBA8kDpB,QACEsB,eAAgBA,EAChBpI,cAAemQ,EACfjQ,UAAWA,EACXyO,wBAAyBA,KAY3B,OALqB,gBAAZ7O,WACTC,OAAOD,QAAUE,GAIV,SAASG,GAGdH,EAAcE,UAAUC,GACxBH,EAAcA,cAAcG","file":"css-layout.min.js","sourcesContent":["// UMD (Universal Module Definition)\n// See https://github.com/umdjs/umd for reference\n//\n// This file uses the following specific UMD implementation:\n// https://github.com/umdjs/umd/blob/master/templates/returnExports.js\n(function(root, factory) {\n if (typeof define === 'function' && define.amd) {\n // AMD. Register as an anonymous module.\n define([], factory);\n } else if (typeof exports === 'object') {\n // Node. Does not work with strict CommonJS, but\n // only CommonJS-like environments that support module.exports,\n // like Node.\n module.exports = factory();\n } else {\n // Browser globals (root is window)\n root.computeLayout = factory();\n }\n}(this, function() {\n /**\n * Copyright (c) 2014, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under the BSD-style license found in the\n * LICENSE file in the root directory of this source tree. An additional grant\n * of patent rights can be found in the PATENTS file in the same directory.\n */\n\nvar computeLayout = (function() {\n\n var POSITIVE_FLEX_IS_AUTO = false;\n\n var gCurrentGenerationCount = 0;\n\n var CSS_UNDEFINED;\n\n var CSS_LEFT = 'left';\n var CSS_TOP = 'top';\n var CSS_RIGHT = 'right';\n var CSS_BOTTOM = 'bottom';\n\n var CSS_DIRECTION_INHERIT = 'inherit';\n var CSS_DIRECTION_LTR = 'ltr';\n var CSS_DIRECTION_RTL = 'rtl';\n\n var CSS_FLEX_DIRECTION_ROW = 'row';\n var CSS_FLEX_DIRECTION_ROW_REVERSE = 'row-reverse';\n var CSS_FLEX_DIRECTION_COLUMN = 'column';\n var CSS_FLEX_DIRECTION_COLUMN_REVERSE = 'column-reverse';\n\n var CSS_JUSTIFY_FLEX_START = 'flex-start';\n var CSS_JUSTIFY_CENTER = 'center';\n var CSS_JUSTIFY_FLEX_END = 'flex-end';\n var CSS_JUSTIFY_SPACE_BETWEEN = 'space-between';\n var CSS_JUSTIFY_SPACE_AROUND = 'space-around';\n\n var CSS_ALIGN_FLEX_START = 'flex-start';\n var CSS_ALIGN_CENTER = 'center';\n var CSS_ALIGN_FLEX_END = 'flex-end';\n var CSS_ALIGN_STRETCH = 'stretch';\n\n var CSS_POSITION_RELATIVE = 'relative';\n var CSS_POSITION_ABSOLUTE = 'absolute';\n\n var CSS_OVERFLOW_VISIBLE = 'visible';\n var CSS_OVERFLOW_HIDDEN = 'hidden';\n\n var CSS_MEASURE_MODE_UNDEFINED = 'undefined';\n var CSS_MEASURE_MODE_EXACTLY = 'exactly';\n var CSS_MEASURE_MODE_AT_MOST = 'at-most';\n\n var leading = {\n 'row': 'left',\n 'row-reverse': 'right',\n 'column': 'top',\n 'column-reverse': 'bottom'\n };\n var trailing = {\n 'row': 'right',\n 'row-reverse': 'left',\n 'column': 'bottom',\n 'column-reverse': 'top'\n };\n var pos = {\n 'row': 'left',\n 'row-reverse': 'right',\n 'column': 'top',\n 'column-reverse': 'bottom'\n };\n var dim = {\n 'row': 'width',\n 'row-reverse': 'width',\n 'column': 'height',\n 'column-reverse': 'height'\n };\n var measuredDim = {\n 'row': 'measuredWidth',\n 'row-reverse': 'measuredWidth',\n 'column': 'measuredHeight',\n 'column-reverse': 'measuredHeight'\n };\n\n // When transpiled to Java / C the node type has layout, children and style\n // properties. For the JavaScript version this function adds these properties\n // if they don't already exist.\n function fillNodes(node) {\n if (!node.layout || node.isDirty) {\n node.layout = {\n width: undefined,\n height: undefined,\n top: 0,\n left: 0,\n right: 0,\n bottom: 0\n };\n }\n\n if (!node.style) {\n node.style = {};\n }\n\n if (!node.children) {\n node.children = [];\n }\n\n if (node.style.measure && node.children && node.children.length) {\n throw new Error('Using custom measure function is supported only for leaf nodes.');\n }\n\n node.children.forEach(fillNodes);\n return node;\n }\n\n function isUndefined(value) {\n return value === undefined || Number.isNaN(value);\n }\n\n function isRowDirection(flexDirection) {\n return flexDirection === CSS_FLEX_DIRECTION_ROW ||\n flexDirection === CSS_FLEX_DIRECTION_ROW_REVERSE;\n }\n\n function isColumnDirection(flexDirection) {\n return flexDirection === CSS_FLEX_DIRECTION_COLUMN ||\n flexDirection === CSS_FLEX_DIRECTION_COLUMN_REVERSE;\n }\n\n function getFlex(node) {\n if (node.style.flex === undefined) {\n return 0;\n }\n return node.style.flex;\n }\n\n function isFlexBasisAuto(node) {\n if (POSITIVE_FLEX_IS_AUTO) {\n // All flex values are auto.\n return true;\n } else {\n // A flex value > 0 implies a basis of zero.\n return getFlex(node) <= 0;\n }\n }\n\n function getFlexGrowFactor(node) {\n // Flex grow is implied by positive values for flex.\n if (getFlex(node) > 0) {\n return getFlex(node);\n }\n return 0;\n }\n\n function getFlexShrinkFactor(node) {\n if (POSITIVE_FLEX_IS_AUTO) {\n // A flex shrink factor of 1 is implied by non-zero values for flex.\n if (getFlex(node) !== 0) {\n return 1;\n }\n } else {\n // A flex shrink factor of 1 is implied by negative values for flex.\n if (getFlex(node) < 0) {\n return 1;\n }\n }\n return 0;\n }\n\n function getLeadingMargin(node, axis) {\n if (node.style.marginStart !== undefined && isRowDirection(axis)) {\n return node.style.marginStart;\n }\n\n var value = null;\n switch (axis) {\n case 'row': value = node.style.marginLeft; break;\n case 'row-reverse': value = node.style.marginRight; break;\n case 'column': value = node.style.marginTop; break;\n case 'column-reverse': value = node.style.marginBottom; break;\n }\n\n if (value !== undefined) {\n return value;\n }\n\n if (node.style.margin !== undefined) {\n return node.style.margin;\n }\n\n return 0;\n }\n\n function getTrailingMargin(node, axis) {\n if (node.style.marginEnd !== undefined && isRowDirection(axis)) {\n return node.style.marginEnd;\n }\n\n var value = null;\n switch (axis) {\n case 'row': value = node.style.marginRight; break;\n case 'row-reverse': value = node.style.marginLeft; break;\n case 'column': value = node.style.marginBottom; break;\n case 'column-reverse': value = node.style.marginTop; break;\n }\n\n if (value != null) {\n return value;\n }\n\n if (node.style.margin !== undefined) {\n return node.style.margin;\n }\n\n return 0;\n }\n\n function getLeadingPadding(node, axis) {\n if (node.style.paddingStart !== undefined && node.style.paddingStart >= 0\n && isRowDirection(axis)) {\n return node.style.paddingStart;\n }\n\n var value = null;\n switch (axis) {\n case 'row': value = node.style.paddingLeft; break;\n case 'row-reverse': value = node.style.paddingRight; break;\n case 'column': value = node.style.paddingTop; break;\n case 'column-reverse': value = node.style.paddingBottom; break;\n }\n\n if (value != null && value >= 0) {\n return value;\n }\n\n if (node.style.padding !== undefined && node.style.padding >= 0) {\n return node.style.padding;\n }\n\n return 0;\n }\n\n function getTrailingPadding(node, axis) {\n if (node.style.paddingEnd !== undefined && node.style.paddingEnd >= 0\n && isRowDirection(axis)) {\n return node.style.paddingEnd;\n }\n\n var value = null;\n switch (axis) {\n case 'row': value = node.style.paddingRight; break;\n case 'row-reverse': value = node.style.paddingLeft; break;\n case 'column': value = node.style.paddingBottom; break;\n case 'column-reverse': value = node.style.paddingTop; break;\n }\n\n if (value != null && value >= 0) {\n return value;\n }\n\n if (node.style.padding !== undefined && node.style.padding >= 0) {\n return node.style.padding;\n }\n\n return 0;\n }\n\n function getLeadingBorder(node, axis) {\n if (node.style.borderStartWidth !== undefined && node.style.borderStartWidth >= 0\n && isRowDirection(axis)) {\n return node.style.borderStartWidth;\n }\n\n var value = null;\n switch (axis) {\n case 'row': value = node.style.borderLeftWidth; break;\n case 'row-reverse': value = node.style.borderRightWidth; break;\n case 'column': value = node.style.borderTopWidth; break;\n case 'column-reverse': value = node.style.borderBottomWidth; break;\n }\n\n if (value != null && value >= 0) {\n return value;\n }\n\n if (node.style.borderWidth !== undefined && node.style.borderWidth >= 0) {\n return node.style.borderWidth;\n }\n\n return 0;\n }\n\n function getTrailingBorder(node, axis) {\n if (node.style.borderEndWidth !== undefined && node.style.borderEndWidth >= 0\n && isRowDirection(axis)) {\n return node.style.borderEndWidth;\n }\n\n var value = null;\n switch (axis) {\n case 'row': value = node.style.borderRightWidth; break;\n case 'row-reverse': value = node.style.borderLeftWidth; break;\n case 'column': value = node.style.borderBottomWidth; break;\n case 'column-reverse': value = node.style.borderTopWidth; break;\n }\n\n if (value != null && value >= 0) {\n return value;\n }\n\n if (node.style.borderWidth !== undefined && node.style.borderWidth >= 0) {\n return node.style.borderWidth;\n }\n\n return 0;\n }\n\n function getLeadingPaddingAndBorder(node, axis) {\n return getLeadingPadding(node, axis) + getLeadingBorder(node, axis);\n }\n\n function getTrailingPaddingAndBorder(node, axis) {\n return getTrailingPadding(node, axis) + getTrailingBorder(node, axis);\n }\n\n function getMarginAxis(node, axis) {\n return getLeadingMargin(node, axis) + getTrailingMargin(node, axis);\n }\n\n function getPaddingAndBorderAxis(node, axis) {\n return getLeadingPaddingAndBorder(node, axis) +\n getTrailingPaddingAndBorder(node, axis);\n }\n\n function getJustifyContent(node) {\n if (node.style.justifyContent) {\n return node.style.justifyContent;\n }\n return 'flex-start';\n }\n\n function getAlignContent(node) {\n if (node.style.alignContent) {\n return node.style.alignContent;\n }\n return 'flex-start';\n }\n\n function getAlignItem(node, child) {\n if (child.style.alignSelf) {\n return child.style.alignSelf;\n }\n if (node.style.alignItems) {\n return node.style.alignItems;\n }\n return 'stretch';\n }\n\n function resolveAxis(axis, direction) {\n if (direction === CSS_DIRECTION_RTL) {\n if (axis === CSS_FLEX_DIRECTION_ROW) {\n return CSS_FLEX_DIRECTION_ROW_REVERSE;\n } else if (axis === CSS_FLEX_DIRECTION_ROW_REVERSE) {\n return CSS_FLEX_DIRECTION_ROW;\n }\n }\n\n return axis;\n }\n\n function resolveDirection(node, parentDirection) {\n var direction;\n if (node.style.direction) {\n direction = node.style.direction;\n } else {\n direction = CSS_DIRECTION_INHERIT;\n }\n\n if (direction === CSS_DIRECTION_INHERIT) {\n direction = (parentDirection === undefined ? CSS_DIRECTION_LTR : parentDirection);\n }\n\n return direction;\n }\n\n function getFlexDirection(node) {\n if (node.style.flexDirection) {\n return node.style.flexDirection;\n }\n return CSS_FLEX_DIRECTION_COLUMN;\n }\n\n function getCrossFlexDirection(flexDirection, direction) {\n if (isColumnDirection(flexDirection)) {\n return resolveAxis(CSS_FLEX_DIRECTION_ROW, direction);\n } else {\n return CSS_FLEX_DIRECTION_COLUMN;\n }\n }\n\n function getPositionType(node) {\n if (node.style.position) {\n return node.style.position;\n }\n return CSS_POSITION_RELATIVE;\n }\n\n function getOverflow(node) {\n if (node.style.overflow) {\n return node.style.overflow;\n }\n return CSS_OVERFLOW_VISIBLE;\n }\n\n function isFlex(node) {\n return (\n getPositionType(node) === CSS_POSITION_RELATIVE &&\n node.style.flex !== undefined && node.style.flex !== 0\n );\n }\n\n function isFlexWrap(node) {\n return node.style.flexWrap === 'wrap';\n }\n\n function getDimWithMargin(node, axis) {\n return node.layout[measuredDim[axis]] + getMarginAxis(node, axis);\n }\n\n function isStyleDimDefined(node, axis) {\n return node.style[dim[axis]] !== undefined && node.style[dim[axis]] >= 0;\n }\n\n function isLayoutDimDefined(node, axis) {\n return node.layout[measuredDim[axis]] !== undefined && node.layout[measuredDim[axis]] >= 0;\n }\n\n function isPosDefined(node, pos) {\n return node.style[pos] !== undefined;\n }\n\n function isMeasureDefined(node) {\n return node.style.measure !== undefined;\n }\n\n function getPosition(node, pos) {\n if (node.style[pos] !== undefined) {\n return node.style[pos];\n }\n return 0;\n }\n\n function boundAxisWithinMinAndMax(node, axis, value) {\n var min = {\n 'row': node.style.minWidth,\n 'row-reverse': node.style.minWidth,\n 'column': node.style.minHeight,\n 'column-reverse': node.style.minHeight\n }[axis];\n\n var max = {\n 'row': node.style.maxWidth,\n 'row-reverse': node.style.maxWidth,\n 'column': node.style.maxHeight,\n 'column-reverse': node.style.maxHeight\n }[axis];\n\n var boundValue = value;\n if (max !== undefined && max >= 0 && boundValue > max) {\n boundValue = max;\n }\n if (min !== undefined && min >= 0 && boundValue < min) {\n boundValue = min;\n }\n return boundValue;\n }\n\n function fminf(a, b) {\n if (a < b) {\n return a;\n }\n return b;\n }\n\n function fmaxf(a, b) {\n if (a > b) {\n return a;\n }\n return b;\n }\n\n // Like boundAxisWithinMinAndMax but also ensures that the value doesn't go below the\n // padding and border amount.\n function boundAxis(node, axis, value) {\n return fmaxf(boundAxisWithinMinAndMax(node, axis, value), getPaddingAndBorderAxis(node, axis));\n }\n\n function setTrailingPosition(node, child, axis) {\n var size = (getPositionType(child) === CSS_POSITION_ABSOLUTE) ?\n 0 :\n child.layout[measuredDim[axis]];\n child.layout[trailing[axis]] = node.layout[measuredDim[axis]] - size - child.layout[pos[axis]];\n }\n\n // If both left and right are defined, then use left. Otherwise return\n // +left or -right depending on which is defined.\n function getRelativePosition(node, axis) {\n if (node.style[leading[axis]] !== undefined) {\n return getPosition(node, leading[axis]);\n }\n return -getPosition(node, trailing[axis]);\n }\n\n function setPosition(node, direction) {\n var mainAxis = resolveAxis(getFlexDirection(node), direction);\n var crossAxis = getCrossFlexDirection(mainAxis, direction);\n\n node.layout[leading[mainAxis]] = getLeadingMargin(node, mainAxis) +\n getRelativePosition(node, mainAxis);\n node.layout[trailing[mainAxis]] = getTrailingMargin(node, mainAxis) +\n getRelativePosition(node, mainAxis);\n node.layout[leading[crossAxis]] = getLeadingMargin(node, crossAxis) +\n getRelativePosition(node, crossAxis);\n node.layout[trailing[crossAxis]] = getTrailingMargin(node, crossAxis) +\n getRelativePosition(node, crossAxis);\n }\n\n function assert(condition, message) {\n if (!condition) {\n throw new Error(message);\n }\n }\n\n //\n // This is the main routine that implements a subset of the flexbox layout algorithm\n // described in the W3C CSS documentation: https://www.w3.org/TR/css3-flexbox/.\n //\n // Limitations of this algorithm, compared to the full standard:\n // * Display property is always assumed to be 'flex' except for Text nodes, which\n // are assumed to be 'inline-flex'.\n // * The 'zIndex' property (or any form of z ordering) is not supported. Nodes are\n // stacked in document order.\n // * The 'order' property is not supported. The order of flex items is always defined\n // by document order.\n // * The 'visibility' property is always assumed to be 'visible'. Values of 'collapse'\n // and 'hidden' are not supported.\n // * The 'wrap' property supports only 'nowrap' (which is the default) or 'wrap'. The\n // rarely-used 'wrap-reverse' is not supported.\n // * Rather than allowing arbitrary combinations of flexGrow, flexShrink and\n // flexBasis, this algorithm supports only the three most common combinations:\n // flex: 0 is equiavlent to flex: 0 0 auto\n // flex: n (where n is a positive value) is equivalent to flex: n 1 auto\n // If POSITIVE_FLEX_IS_AUTO is 0, then it is equivalent to flex: n 0 0\n // This is faster because the content doesn't need to be measured, but it's\n // less flexible because the basis is always 0 and can't be overriden with\n // the width/height attributes.\n // flex: -1 (or any negative value) is equivalent to flex: 0 1 auto\n // * Margins cannot be specified as 'auto'. They must be specified in terms of pixel\n // values, and the default value is 0.\n // * The 'baseline' value is not supported for alignItems and alignSelf properties.\n // * Values of width, maxWidth, minWidth, height, maxHeight and minHeight must be\n // specified as pixel values, not as percentages.\n // * There is no support for calculation of dimensions based on intrinsic aspect ratios\n // (e.g. images).\n // * There is no support for forced breaks.\n // * It does not support vertical inline directions (top-to-bottom or bottom-to-top text).\n //\n // Deviations from standard:\n // * Section 4.5 of the spec indicates that all flex items have a default minimum\n // main size. For text blocks, for example, this is the width of the widest word.\n // Calculating the minimum width is expensive, so we forego it and assume a default\n // minimum main size of 0.\n // * Min/Max sizes in the main axis are not honored when resolving flexible lengths.\n // * The spec indicates that the default value for 'flexDirection' is 'row', but\n // the algorithm below assumes a default of 'column'.\n //\n // Input parameters:\n // - node: current node to be sized and layed out\n // - availableWidth & availableHeight: available size to be used for sizing the node\n // or CSS_UNDEFINED if the size is not available; interpretation depends on layout\n // flags\n // - parentDirection: the inline (text) direction within the parent (left-to-right or\n // right-to-left)\n // - widthMeasureMode: indicates the sizing rules for the width (see below for explanation)\n // - heightMeasureMode: indicates the sizing rules for the height (see below for explanation)\n // - performLayout: specifies whether the caller is interested in just the dimensions\n // of the node or it requires the entire node and its subtree to be layed out\n // (with final positions)\n //\n // Details:\n // This routine is called recursively to lay out subtrees of flexbox elements. It uses the\n // information in node.style, which is treated as a read-only input. It is responsible for\n // setting the layout.direction and layout.measured_dimensions fields for the input node as well\n // as the layout.position and layout.line_index fields for its child nodes. The\n // layout.measured_dimensions field includes any border or padding for the node but does\n // not include margins.\n //\n // The spec describes four different layout modes: \"fill available\", \"max content\", \"min content\",\n // and \"fit content\". Of these, we don't use \"min content\" because we don't support default\n // minimum main sizes (see above for details). Each of our measure modes maps to a layout mode\n // from the spec (https://www.w3.org/TR/css3-sizing/#terms):\n // - CSS_MEASURE_MODE_UNDEFINED: max content\n // - CSS_MEASURE_MODE_EXACTLY: fill available\n // - CSS_MEASURE_MODE_AT_MOST: fit content\n //\n // When calling layoutNodeImpl and layoutNodeInternal, if the caller passes an available size of\n // undefined then it must also pass a measure mode of CSS_MEASURE_MODE_UNDEFINED in that dimension.\n //\n function layoutNodeImpl(node, availableWidth, availableHeight, /*css_direction_t*/parentDirection, widthMeasureMode, heightMeasureMode, performLayout) {\n assert(isUndefined(availableWidth) ? widthMeasureMode === CSS_MEASURE_MODE_UNDEFINED : true, 'availableWidth is indefinite so widthMeasureMode must be CSS_MEASURE_MODE_UNDEFINED');\n assert(isUndefined(availableHeight) ? heightMeasureMode === CSS_MEASURE_MODE_UNDEFINED : true, 'availableHeight is indefinite so heightMeasureMode must be CSS_MEASURE_MODE_UNDEFINED');\n\n var/*float*/ paddingAndBorderAxisRow = getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW);\n var/*float*/ paddingAndBorderAxisColumn = getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN);\n var/*float*/ marginAxisRow = getMarginAxis(node, CSS_FLEX_DIRECTION_ROW);\n var/*float*/ marginAxisColumn = getMarginAxis(node, CSS_FLEX_DIRECTION_COLUMN);\n\n // Set the resolved resolution in the node's layout.\n var/*css_direction_t*/ direction = resolveDirection(node, parentDirection);\n node.layout.direction = direction;\n\n // For content (text) nodes, determine the dimensions based on the text contents.\n if (isMeasureDefined(node)) {\n var/*float*/ innerWidth = availableWidth - marginAxisRow - paddingAndBorderAxisRow;\n var/*float*/ innerHeight = availableHeight - marginAxisColumn - paddingAndBorderAxisColumn;\n\n if (widthMeasureMode === CSS_MEASURE_MODE_EXACTLY && heightMeasureMode === CSS_MEASURE_MODE_EXACTLY) {\n\n // Don't bother sizing the text if both dimensions are already defined.\n node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW, availableWidth - marginAxisRow);\n node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, availableHeight - marginAxisColumn);\n } else if (innerWidth <= 0 || innerHeight <= 0) {\n\n // Don't bother sizing the text if there's no horizontal or vertical space.\n node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW, 0);\n node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, 0);\n } else {\n\n // Measure the text under the current constraints.\n var/*css_dim_t*/ measureDim = node.style.measure(\n /*(c)!node->context,*/\n /*(java)!layoutContext.measureOutput,*/\n innerWidth,\n widthMeasureMode,\n innerHeight,\n heightMeasureMode\n );\n\n node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW,\n (widthMeasureMode === CSS_MEASURE_MODE_UNDEFINED || widthMeasureMode === CSS_MEASURE_MODE_AT_MOST) ?\n measureDim.width + paddingAndBorderAxisRow :\n availableWidth - marginAxisRow);\n node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN,\n (heightMeasureMode === CSS_MEASURE_MODE_UNDEFINED || heightMeasureMode === CSS_MEASURE_MODE_AT_MOST) ?\n measureDim.height + paddingAndBorderAxisColumn :\n availableHeight - marginAxisColumn);\n }\n\n return;\n }\n\n // For nodes with no children, use the available values if they were provided, or\n // the minimum size as indicated by the padding and border sizes.\n var/*int*/ childCount = node.children.length;\n if (childCount === 0) {\n node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW,\n (widthMeasureMode === CSS_MEASURE_MODE_UNDEFINED || widthMeasureMode === CSS_MEASURE_MODE_AT_MOST) ?\n paddingAndBorderAxisRow :\n availableWidth - marginAxisRow);\n node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN,\n (heightMeasureMode === CSS_MEASURE_MODE_UNDEFINED || heightMeasureMode === CSS_MEASURE_MODE_AT_MOST) ?\n paddingAndBorderAxisColumn :\n availableHeight - marginAxisColumn);\n return;\n }\n\n // If we're not being asked to perform a full layout, we can handle a number of common\n // cases here without incurring the cost of the remaining function.\n if (!performLayout) {\n // If we're being asked to size the content with an at most constraint but there is no available width,\n // the measurement will always be zero.\n if (widthMeasureMode === CSS_MEASURE_MODE_AT_MOST && availableWidth <= 0 &&\n heightMeasureMode === CSS_MEASURE_MODE_AT_MOST && availableHeight <= 0) {\n node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW, 0);\n node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, 0);\n return;\n }\n\n if (widthMeasureMode === CSS_MEASURE_MODE_AT_MOST && availableWidth <= 0) {\n node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW, 0);\n node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, isUndefined(availableHeight) ? 0 : (availableHeight - marginAxisColumn));\n return;\n }\n\n if (heightMeasureMode === CSS_MEASURE_MODE_AT_MOST && availableHeight <= 0) {\n node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW, isUndefined(availableWidth) ? 0 : (availableWidth - marginAxisRow));\n node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, 0);\n return;\n }\n\n // If we're being asked to use an exact width/height, there's no need to measure the children.\n if (widthMeasureMode === CSS_MEASURE_MODE_EXACTLY && heightMeasureMode === CSS_MEASURE_MODE_EXACTLY) {\n node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW, availableWidth - marginAxisRow);\n node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, availableHeight - marginAxisColumn);\n return;\n }\n }\n\n // STEP 1: CALCULATE VALUES FOR REMAINDER OF ALGORITHM\n var/*(c)!css_flex_direction_t*//*(java)!int*/ mainAxis = resolveAxis(getFlexDirection(node), direction);\n var/*(c)!css_flex_direction_t*//*(java)!int*/ crossAxis = getCrossFlexDirection(mainAxis, direction);\n var/*bool*/ isMainAxisRow = isRowDirection(mainAxis);\n var/*css_justify_t*/ justifyContent = getJustifyContent(node);\n var/*bool*/ isNodeFlexWrap = isFlexWrap(node);\n\n var/*css_node_t**/ firstAbsoluteChild = undefined;\n var/*css_node_t**/ currentAbsoluteChild = undefined;\n\n var/*float*/ leadingPaddingAndBorderMain = getLeadingPaddingAndBorder(node, mainAxis);\n var/*float*/ trailingPaddingAndBorderMain = getTrailingPaddingAndBorder(node, mainAxis);\n var/*float*/ leadingPaddingAndBorderCross = getLeadingPaddingAndBorder(node, crossAxis);\n var/*float*/ paddingAndBorderAxisMain = getPaddingAndBorderAxis(node, mainAxis);\n var/*float*/ paddingAndBorderAxisCross = getPaddingAndBorderAxis(node, crossAxis);\n\n var/*css_measure_mode_t*/ measureModeMainDim = isMainAxisRow ? widthMeasureMode : heightMeasureMode;\n var/*css_measure_mode_t*/ measureModeCrossDim = isMainAxisRow ? heightMeasureMode : widthMeasureMode;\n\n // STEP 2: DETERMINE AVAILABLE SIZE IN MAIN AND CROSS DIRECTIONS\n var/*float*/ availableInnerWidth = availableWidth - marginAxisRow - paddingAndBorderAxisRow;\n var/*float*/ availableInnerHeight = availableHeight - marginAxisColumn - paddingAndBorderAxisColumn;\n var/*float*/ availableInnerMainDim = isMainAxisRow ? availableInnerWidth : availableInnerHeight;\n var/*float*/ availableInnerCrossDim = isMainAxisRow ? availableInnerHeight : availableInnerWidth;\n\n // STEP 3: DETERMINE FLEX BASIS FOR EACH ITEM\n var/*css_node_t**/ child;\n var/*int*/ i;\n var/*float*/ childWidth;\n var/*float*/ childHeight;\n var/*css_measure_mode_t*/ childWidthMeasureMode;\n var/*css_measure_mode_t*/ childHeightMeasureMode;\n for (i = 0; i < childCount; i++) {\n child = node.children[i];\n\n if (performLayout) {\n // Set the initial position (relative to the parent).\n var/*css_direction_t*/ childDirection = resolveDirection(child, direction);\n setPosition(child, childDirection);\n }\n\n // Absolute-positioned children don't participate in flex layout. Add them\n // to a list that we can process later.\n if (getPositionType(child) === CSS_POSITION_ABSOLUTE) {\n\n // Store a private linked list of absolutely positioned children\n // so that we can efficiently traverse them later.\n if (firstAbsoluteChild === undefined) {\n firstAbsoluteChild = child;\n }\n if (currentAbsoluteChild !== undefined) {\n currentAbsoluteChild.nextChild = child;\n }\n currentAbsoluteChild = child;\n child.nextChild = undefined;\n } else {\n\n if (isMainAxisRow && isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW)) {\n\n // The width is definite, so use that as the flex basis.\n child.layout.flexBasis = fmaxf(child.style.width, getPaddingAndBorderAxis(child, CSS_FLEX_DIRECTION_ROW));\n } else if (!isMainAxisRow && isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN)) {\n\n // The height is definite, so use that as the flex basis.\n child.layout.flexBasis = fmaxf(child.style.height, getPaddingAndBorderAxis(child, CSS_FLEX_DIRECTION_COLUMN));\n } else if (!isFlexBasisAuto(child) && !isUndefined(availableInnerMainDim)) {\n\n // If the basis isn't 'auto', it is assumed to be zero.\n child.layout.flexBasis = fmaxf(0, getPaddingAndBorderAxis(child, mainAxis));\n } else {\n\n // Compute the flex basis and hypothetical main size (i.e. the clamped flex basis).\n childWidth = CSS_UNDEFINED;\n childHeight = CSS_UNDEFINED;\n childWidthMeasureMode = CSS_MEASURE_MODE_UNDEFINED;\n childHeightMeasureMode = CSS_MEASURE_MODE_UNDEFINED;\n\n if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW)) {\n childWidth = child.style.width + getMarginAxis(child, CSS_FLEX_DIRECTION_ROW);\n childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n }\n if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN)) {\n childHeight = child.style.height + getMarginAxis(child, CSS_FLEX_DIRECTION_COLUMN);\n childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n }\n\n // According to the spec, if the main size is not definite and the\n // child's inline axis is parallel to the main axis (i.e. it's\n // horizontal), the child should be sized using \"UNDEFINED\" in\n // the main size. Otherwise use \"AT_MOST\" in the cross axis.\n if (!isMainAxisRow && isUndefined(childWidth) && !isUndefined(availableInnerWidth)) {\n childWidth = availableInnerWidth;\n childWidthMeasureMode = CSS_MEASURE_MODE_AT_MOST;\n }\n\n // The W3C spec doesn't say anything about the 'overflow' property,\n // but all major browsers appear to implement the following logic.\n if (getOverflow(node) === CSS_OVERFLOW_HIDDEN) {\n if (isMainAxisRow && isUndefined(childHeight) && !isUndefined(availableInnerHeight)) {\n childHeight = availableInnerHeight;\n childHeightMeasureMode = CSS_MEASURE_MODE_AT_MOST;\n }\n }\n\n // If child has no defined size in the cross axis and is set to stretch, set the cross\n // axis to be measured exactly with the available inner width\n if (!isMainAxisRow &&\n !isUndefined(availableInnerWidth) &&\n !isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW) &&\n widthMeasureMode == CSS_MEASURE_MODE_EXACTLY &&\n getAlignItem(node, child) == CSS_ALIGN_STRETCH) {\n childWidth = availableInnerWidth;\n childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n }\n if (isMainAxisRow &&\n !isUndefined(availableInnerHeight) &&\n !isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN) &&\n heightMeasureMode == CSS_MEASURE_MODE_EXACTLY &&\n getAlignItem(node, child) == CSS_ALIGN_STRETCH) {\n childHeight = availableInnerHeight;\n childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n }\n\n // Measure the child\n layoutNodeInternal(child, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, false, 'measure');\n\n child.layout.flexBasis = fmaxf(isMainAxisRow ? child.layout.measuredWidth : child.layout.measuredHeight, getPaddingAndBorderAxis(child, mainAxis));\n }\n }\n }\n\n // STEP 4: COLLECT FLEX ITEMS INTO FLEX LINES\n\n // Indexes of children that represent the first and last items in the line.\n var/*int*/ startOfLineIndex = 0;\n var/*int*/ endOfLineIndex = 0;\n\n // Number of lines.\n var/*int*/ lineCount = 0;\n\n // Accumulated cross dimensions of all lines so far.\n var/*float*/ totalLineCrossDim = 0;\n\n // Max main dimension of all the lines.\n var/*float*/ maxLineMainDim = 0;\n\n while (endOfLineIndex < childCount) {\n\n // Number of items on the currently line. May be different than the difference\n // between start and end indicates because we skip over absolute-positioned items.\n var/*int*/ itemsOnLine = 0;\n\n // sizeConsumedOnCurrentLine is accumulation of the dimensions and margin\n // of all the children on the current line. This will be used in order to\n // either set the dimensions of the node if none already exist or to compute\n // the remaining space left for the flexible children.\n var/*float*/ sizeConsumedOnCurrentLine = 0;\n\n var/*float*/ totalFlexGrowFactors = 0;\n var/*float*/ totalFlexShrinkScaledFactors = 0;\n\n i = startOfLineIndex;\n\n // Maintain a linked list of the child nodes that can shrink and/or grow.\n var/*css_node_t**/ firstRelativeChild = undefined;\n var/*css_node_t**/ currentRelativeChild = undefined;\n\n // Add items to the current line until it's full or we run out of items.\n while (i < childCount) {\n child = node.children[i];\n child.lineIndex = lineCount;\n\n if (getPositionType(child) !== CSS_POSITION_ABSOLUTE) {\n var/*float*/ outerFlexBasis = child.layout.flexBasis + getMarginAxis(child, mainAxis);\n\n // If this is a multi-line flow and this item pushes us over the available size, we've\n // hit the end of the current line. Break out of the loop and lay out the current line.\n if (sizeConsumedOnCurrentLine + outerFlexBasis > availableInnerMainDim && isNodeFlexWrap && itemsOnLine > 0) {\n break;\n }\n\n sizeConsumedOnCurrentLine += outerFlexBasis;\n itemsOnLine++;\n\n if (isFlex(child)) {\n totalFlexGrowFactors += getFlexGrowFactor(child);\n\n // Unlike the grow factor, the shrink factor is scaled relative to the child\n // dimension.\n totalFlexShrinkScaledFactors += getFlexShrinkFactor(child) * child.layout.flexBasis;\n }\n\n // Store a private linked list of children that need to be layed out.\n if (firstRelativeChild === undefined) {\n firstRelativeChild = child;\n }\n if (currentRelativeChild !== undefined) {\n currentRelativeChild.nextChild = child;\n }\n currentRelativeChild = child;\n child.nextChild = undefined;\n }\n\n i++;\n endOfLineIndex++;\n }\n\n // If we don't need to measure the cross axis, we can skip the entire flex step.\n var/*bool*/ canSkipFlex = !performLayout && measureModeCrossDim === CSS_MEASURE_MODE_EXACTLY;\n\n // In order to position the elements in the main axis, we have two\n // controls. The space between the beginning and the first element\n // and the space between each two elements.\n var/*float*/ leadingMainDim = 0;\n var/*float*/ betweenMainDim = 0;\n\n // STEP 5: RESOLVING FLEXIBLE LENGTHS ON MAIN AXIS\n // Calculate the remaining available space that needs to be allocated.\n // If the main dimension size isn't known, it is computed based on\n // the line length, so there's no more space left to distribute.\n var/*float*/ remainingFreeSpace = 0;\n if (!isUndefined(availableInnerMainDim)) {\n remainingFreeSpace = availableInnerMainDim - sizeConsumedOnCurrentLine;\n } else if (sizeConsumedOnCurrentLine < 0) {\n // availableInnerMainDim is indefinite which means the node is being sized based on its content.\n // sizeConsumedOnCurrentLine is negative which means the node will allocate 0 pixels for\n // its content. Consequently, remainingFreeSpace is 0 - sizeConsumedOnCurrentLine.\n remainingFreeSpace = -sizeConsumedOnCurrentLine;\n }\n\n var/*float*/ originalRemainingFreeSpace = remainingFreeSpace;\n var/*float*/ deltaFreeSpace = 0;\n\n if (!canSkipFlex) {\n var/*float*/ childFlexBasis;\n var/*float*/ flexShrinkScaledFactor;\n var/*float*/ flexGrowFactor;\n var/*float*/ baseMainSize;\n var/*float*/ boundMainSize;\n\n // Do two passes over the flex items to figure out how to distribute the remaining space.\n // The first pass finds the items whose min/max constraints trigger, freezes them at those\n // sizes, and excludes those sizes from the remaining space. The second pass sets the size\n // of each flexible item. It distributes the remaining space amongst the items whose min/max\n // constraints didn't trigger in pass 1. For the other items, it sets their sizes by forcing\n // their min/max constraints to trigger again.\n //\n // This two pass approach for resolving min/max constraints deviates from the spec. The\n // spec (https://www.w3.org/TR/css-flexbox-1/#resolve-flexible-lengths) describes a process\n // that needs to be repeated a variable number of times. The algorithm implemented here\n // won't handle all cases but it was simpler to implement and it mitigates performance\n // concerns because we know exactly how many passes it'll do.\n\n // First pass: detect the flex items whose min/max constraints trigger\n var/*float*/ deltaFlexShrinkScaledFactors = 0;\n var/*float*/ deltaFlexGrowFactors = 0;\n currentRelativeChild = firstRelativeChild;\n while (currentRelativeChild !== undefined) {\n childFlexBasis = currentRelativeChild.layout.flexBasis;\n\n if (remainingFreeSpace < 0) {\n flexShrinkScaledFactor = getFlexShrinkFactor(currentRelativeChild) * childFlexBasis;\n\n // Is this child able to shrink?\n if (flexShrinkScaledFactor !== 0) {\n baseMainSize = childFlexBasis +\n remainingFreeSpace / totalFlexShrinkScaledFactors * flexShrinkScaledFactor;\n boundMainSize = boundAxis(currentRelativeChild, mainAxis, baseMainSize);\n if (baseMainSize !== boundMainSize) {\n // By excluding this item's size and flex factor from remaining, this item's\n // min/max constraints should also trigger in the second pass resulting in the\n // item's size calculation being identical in the first and second passes.\n deltaFreeSpace -= boundMainSize - childFlexBasis;\n deltaFlexShrinkScaledFactors -= flexShrinkScaledFactor;\n }\n }\n } else if (remainingFreeSpace > 0) {\n flexGrowFactor = getFlexGrowFactor(currentRelativeChild);\n\n // Is this child able to grow?\n if (flexGrowFactor !== 0) {\n baseMainSize = childFlexBasis +\n remainingFreeSpace / totalFlexGrowFactors * flexGrowFactor;\n boundMainSize = boundAxis(currentRelativeChild, mainAxis, baseMainSize);\n if (baseMainSize !== boundMainSize) {\n // By excluding this item's size and flex factor from remaining, this item's\n // min/max constraints should also trigger in the second pass resulting in the\n // item's size calculation being identical in the first and second passes.\n deltaFreeSpace -= boundMainSize - childFlexBasis;\n deltaFlexGrowFactors -= flexGrowFactor;\n }\n }\n }\n\n currentRelativeChild = currentRelativeChild.nextChild;\n }\n\n totalFlexShrinkScaledFactors += deltaFlexShrinkScaledFactors;\n totalFlexGrowFactors += deltaFlexGrowFactors;\n remainingFreeSpace += deltaFreeSpace;\n\n // Second pass: resolve the sizes of the flexible items\n deltaFreeSpace = 0;\n currentRelativeChild = firstRelativeChild;\n while (currentRelativeChild !== undefined) {\n childFlexBasis = currentRelativeChild.layout.flexBasis;\n var/*float*/ updatedMainSize = childFlexBasis;\n\n if (remainingFreeSpace < 0) {\n flexShrinkScaledFactor = getFlexShrinkFactor(currentRelativeChild) * childFlexBasis;\n\n // Is this child able to shrink?\n if (flexShrinkScaledFactor !== 0) {\n updatedMainSize = boundAxis(currentRelativeChild, mainAxis, childFlexBasis +\n remainingFreeSpace / totalFlexShrinkScaledFactors * flexShrinkScaledFactor);\n }\n } else if (remainingFreeSpace > 0) {\n flexGrowFactor = getFlexGrowFactor(currentRelativeChild);\n\n // Is this child able to grow?\n if (flexGrowFactor !== 0) {\n updatedMainSize = boundAxis(currentRelativeChild, mainAxis, childFlexBasis +\n remainingFreeSpace / totalFlexGrowFactors * flexGrowFactor);\n }\n }\n\n deltaFreeSpace -= updatedMainSize - childFlexBasis;\n\n if (isMainAxisRow) {\n childWidth = updatedMainSize + getMarginAxis(currentRelativeChild, CSS_FLEX_DIRECTION_ROW);\n childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n\n if (!isUndefined(availableInnerCrossDim) &&\n !isStyleDimDefined(currentRelativeChild, CSS_FLEX_DIRECTION_COLUMN) &&\n heightMeasureMode == CSS_MEASURE_MODE_EXACTLY &&\n getAlignItem(node, currentRelativeChild) == CSS_ALIGN_STRETCH) {\n childHeight = availableInnerCrossDim;\n childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n } else if (!isStyleDimDefined(currentRelativeChild, CSS_FLEX_DIRECTION_COLUMN)) {\n childHeight = availableInnerCrossDim;\n childHeightMeasureMode = isUndefined(childHeight) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_AT_MOST;\n } else {\n childHeight = currentRelativeChild.style.height + getMarginAxis(currentRelativeChild, CSS_FLEX_DIRECTION_COLUMN);\n childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n }\n } else {\n childHeight = updatedMainSize + getMarginAxis(currentRelativeChild, CSS_FLEX_DIRECTION_COLUMN);\n childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n\n if (!isUndefined(availableInnerCrossDim) &&\n !isStyleDimDefined(currentRelativeChild, CSS_FLEX_DIRECTION_ROW) &&\n widthMeasureMode == CSS_MEASURE_MODE_EXACTLY &&\n getAlignItem(node, currentRelativeChild) == CSS_ALIGN_STRETCH) {\n childWidth = availableInnerCrossDim;\n childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n } else if (!isStyleDimDefined(currentRelativeChild, CSS_FLEX_DIRECTION_ROW)) {\n childWidth = availableInnerCrossDim;\n childWidthMeasureMode = isUndefined(childWidth) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_AT_MOST;\n } else {\n childWidth = currentRelativeChild.style.width + getMarginAxis(currentRelativeChild, CSS_FLEX_DIRECTION_ROW);\n childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n }\n }\n\n var/*bool*/ requiresStretchLayout = !isStyleDimDefined(currentRelativeChild, crossAxis) &&\n getAlignItem(node, currentRelativeChild) === CSS_ALIGN_STRETCH;\n\n // Recursively call the layout algorithm for this child with the updated main size.\n layoutNodeInternal(currentRelativeChild, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, performLayout && !requiresStretchLayout, 'flex');\n\n currentRelativeChild = currentRelativeChild.nextChild;\n }\n }\n\n remainingFreeSpace = originalRemainingFreeSpace + deltaFreeSpace;\n\n // STEP 6: MAIN-AXIS JUSTIFICATION & CROSS-AXIS SIZE DETERMINATION\n\n // At this point, all the children have their dimensions set in the main axis.\n // Their dimensions are also set in the cross axis with the exception of items\n // that are aligned 'stretch'. We need to compute these stretch values and\n // set the final positions.\n\n // If we are using \"at most\" rules in the main axis, we won't distribute\n // any remaining space at this point.\n if (measureModeMainDim === CSS_MEASURE_MODE_AT_MOST) {\n remainingFreeSpace = 0;\n }\n\n // Use justifyContent to figure out how to allocate the remaining space\n // available in the main axis.\n if (justifyContent !== CSS_JUSTIFY_FLEX_START) {\n if (justifyContent === CSS_JUSTIFY_CENTER) {\n leadingMainDim = remainingFreeSpace / 2;\n } else if (justifyContent === CSS_JUSTIFY_FLEX_END) {\n leadingMainDim = remainingFreeSpace;\n } else if (justifyContent === CSS_JUSTIFY_SPACE_BETWEEN) {\n remainingFreeSpace = fmaxf(remainingFreeSpace, 0);\n if (itemsOnLine > 1) {\n betweenMainDim = remainingFreeSpace / (itemsOnLine - 1);\n } else {\n betweenMainDim = 0;\n }\n } else if (justifyContent === CSS_JUSTIFY_SPACE_AROUND) {\n // Space on the edges is half of the space between elements\n betweenMainDim = remainingFreeSpace / itemsOnLine;\n leadingMainDim = betweenMainDim / 2;\n }\n }\n\n var/*float*/ mainDim = leadingPaddingAndBorderMain + leadingMainDim;\n var/*float*/ crossDim = 0;\n\n for (i = startOfLineIndex; i < endOfLineIndex; ++i) {\n child = node.children[i];\n\n if (getPositionType(child) === CSS_POSITION_ABSOLUTE &&\n isPosDefined(child, leading[mainAxis])) {\n if (performLayout) {\n // In case the child is position absolute and has left/top being\n // defined, we override the position to whatever the user said\n // (and margin/border).\n child.layout[pos[mainAxis]] = getPosition(child, leading[mainAxis]) +\n getLeadingBorder(node, mainAxis) +\n getLeadingMargin(child, mainAxis);\n }\n } else {\n if (performLayout) {\n // If the child is position absolute (without top/left) or relative,\n // we put it at the current accumulated offset.\n child.layout[pos[mainAxis]] += mainDim;\n }\n\n // Now that we placed the element, we need to update the variables.\n // We need to do that only for relative elements. Absolute elements\n // do not take part in that phase.\n if (getPositionType(child) === CSS_POSITION_RELATIVE) {\n if (canSkipFlex) {\n // If we skipped the flex step, then we can't rely on the measuredDims because\n // they weren't computed. This means we can't call getDimWithMargin.\n mainDim += betweenMainDim + getMarginAxis(child, mainAxis) + child.layout.flexBasis;\n crossDim = availableInnerCrossDim;\n } else {\n // The main dimension is the sum of all the elements dimension plus\n // the spacing.\n mainDim += betweenMainDim + getDimWithMargin(child, mainAxis);\n\n // The cross dimension is the max of the elements dimension since there\n // can only be one element in that cross dimension.\n crossDim = fmaxf(crossDim, getDimWithMargin(child, crossAxis));\n }\n }\n }\n }\n\n mainDim += trailingPaddingAndBorderMain;\n\n var/*float*/ containerCrossAxis = availableInnerCrossDim;\n if (measureModeCrossDim === CSS_MEASURE_MODE_UNDEFINED || measureModeCrossDim === CSS_MEASURE_MODE_AT_MOST) {\n // Compute the cross axis from the max cross dimension of the children.\n containerCrossAxis = boundAxis(node, crossAxis, crossDim + paddingAndBorderAxisCross) - paddingAndBorderAxisCross;\n\n if (measureModeCrossDim === CSS_MEASURE_MODE_AT_MOST) {\n containerCrossAxis = fminf(containerCrossAxis, availableInnerCrossDim);\n }\n }\n\n // If there's no flex wrap, the cross dimension is defined by the container.\n if (!isNodeFlexWrap && measureModeCrossDim === CSS_MEASURE_MODE_EXACTLY) {\n crossDim = availableInnerCrossDim;\n }\n\n // Clamp to the min/max size specified on the container.\n crossDim = boundAxis(node, crossAxis, crossDim + paddingAndBorderAxisCross) - paddingAndBorderAxisCross;\n\n // STEP 7: CROSS-AXIS ALIGNMENT\n // We can skip child alignment if we're just measuring the container.\n if (performLayout) {\n for (i = startOfLineIndex; i < endOfLineIndex; ++i) {\n child = node.children[i];\n\n if (getPositionType(child) === CSS_POSITION_ABSOLUTE) {\n // If the child is absolutely positioned and has a top/left/bottom/right\n // set, override all the previously computed positions to set it correctly.\n if (isPosDefined(child, leading[crossAxis])) {\n child.layout[pos[crossAxis]] = getPosition(child, leading[crossAxis]) +\n getLeadingBorder(node, crossAxis) +\n getLeadingMargin(child, crossAxis);\n } else {\n child.layout[pos[crossAxis]] = leadingPaddingAndBorderCross +\n getLeadingMargin(child, crossAxis);\n }\n } else {\n var/*float*/ leadingCrossDim = leadingPaddingAndBorderCross;\n\n // For a relative children, we're either using alignItems (parent) or\n // alignSelf (child) in order to determine the position in the cross axis\n var/*css_align_t*/ alignItem = getAlignItem(node, child);\n\n // If the child uses align stretch, we need to lay it out one more time, this time\n // forcing the cross-axis size to be the computed cross size for the current line.\n if (alignItem === CSS_ALIGN_STRETCH) {\n childWidth = child.layout.measuredWidth + getMarginAxis(child, CSS_FLEX_DIRECTION_ROW);\n childHeight = child.layout.measuredHeight + getMarginAxis(child, CSS_FLEX_DIRECTION_COLUMN);\n var/*bool*/ isCrossSizeDefinite = false;\n\n if (isMainAxisRow) {\n isCrossSizeDefinite = isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN);\n childHeight = crossDim;\n } else {\n isCrossSizeDefinite = isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW);\n childWidth = crossDim;\n }\n\n // If the child defines a definite size for its cross axis, there's no need to stretch.\n if (!isCrossSizeDefinite) {\n childWidthMeasureMode = isUndefined(childWidth) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_EXACTLY;\n childHeightMeasureMode = isUndefined(childHeight) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_EXACTLY;\n layoutNodeInternal(child, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, true, 'stretch');\n }\n } else if (alignItem !== CSS_ALIGN_FLEX_START) {\n var/*float*/ remainingCrossDim = containerCrossAxis - getDimWithMargin(child, crossAxis);\n\n if (alignItem === CSS_ALIGN_CENTER) {\n leadingCrossDim += remainingCrossDim / 2;\n } else { // CSS_ALIGN_FLEX_END\n leadingCrossDim += remainingCrossDim;\n }\n }\n\n // And we apply the position\n child.layout[pos[crossAxis]] += totalLineCrossDim + leadingCrossDim;\n }\n }\n }\n\n totalLineCrossDim += crossDim;\n maxLineMainDim = fmaxf(maxLineMainDim, mainDim);\n\n // Reset variables for new line.\n lineCount++;\n startOfLineIndex = endOfLineIndex;\n endOfLineIndex = startOfLineIndex;\n }\n\n // STEP 8: MULTI-LINE CONTENT ALIGNMENT\n if (lineCount > 1 && performLayout && !isUndefined(availableInnerCrossDim)) {\n var/*float*/ remainingAlignContentDim = availableInnerCrossDim - totalLineCrossDim;\n\n var/*float*/ crossDimLead = 0;\n var/*float*/ currentLead = leadingPaddingAndBorderCross;\n\n var/*css_align_t*/ alignContent = getAlignContent(node);\n if (alignContent === CSS_ALIGN_FLEX_END) {\n currentLead += remainingAlignContentDim;\n } else if (alignContent === CSS_ALIGN_CENTER) {\n currentLead += remainingAlignContentDim / 2;\n } else if (alignContent === CSS_ALIGN_STRETCH) {\n if (availableInnerCrossDim > totalLineCrossDim) {\n crossDimLead = (remainingAlignContentDim / lineCount);\n }\n }\n\n var/*int*/ endIndex = 0;\n for (i = 0; i < lineCount; ++i) {\n var/*int*/ startIndex = endIndex;\n var/*int*/ j;\n\n // compute the line's height and find the endIndex\n var/*float*/ lineHeight = 0;\n for (j = startIndex; j < childCount; ++j) {\n child = node.children[j];\n if (getPositionType(child) !== CSS_POSITION_RELATIVE) {\n continue;\n }\n if (child.lineIndex !== i) {\n break;\n }\n if (isLayoutDimDefined(child, crossAxis)) {\n lineHeight = fmaxf(lineHeight,\n child.layout[measuredDim[crossAxis]] + getMarginAxis(child, crossAxis));\n }\n }\n endIndex = j;\n lineHeight += crossDimLead;\n\n if (performLayout) {\n for (j = startIndex; j < endIndex; ++j) {\n child = node.children[j];\n if (getPositionType(child) !== CSS_POSITION_RELATIVE) {\n continue;\n }\n\n var/*css_align_t*/ alignContentAlignItem = getAlignItem(node, child);\n if (alignContentAlignItem === CSS_ALIGN_FLEX_START) {\n child.layout[pos[crossAxis]] = currentLead + getLeadingMargin(child, crossAxis);\n } else if (alignContentAlignItem === CSS_ALIGN_FLEX_END) {\n child.layout[pos[crossAxis]] = currentLead + lineHeight - getTrailingMargin(child, crossAxis) - child.layout[measuredDim[crossAxis]];\n } else if (alignContentAlignItem === CSS_ALIGN_CENTER) {\n childHeight = child.layout[measuredDim[crossAxis]];\n child.layout[pos[crossAxis]] = currentLead + (lineHeight - childHeight) / 2;\n } else if (alignContentAlignItem === CSS_ALIGN_STRETCH) {\n child.layout[pos[crossAxis]] = currentLead + getLeadingMargin(child, crossAxis);\n // TODO(prenaux): Correctly set the height of items with indefinite\n // (auto) crossAxis dimension.\n }\n }\n }\n\n currentLead += lineHeight;\n }\n }\n\n // STEP 9: COMPUTING FINAL DIMENSIONS\n node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW, availableWidth - marginAxisRow);\n node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, availableHeight - marginAxisColumn);\n\n // If the user didn't specify a width or height for the node, set the\n // dimensions based on the children.\n if (measureModeMainDim === CSS_MEASURE_MODE_UNDEFINED) {\n // Clamp the size to the min/max size, if specified, and make sure it\n // doesn't go below the padding and border amount.\n node.layout[measuredDim[mainAxis]] = boundAxis(node, mainAxis, maxLineMainDim);\n } else if (measureModeMainDim === CSS_MEASURE_MODE_AT_MOST) {\n node.layout[measuredDim[mainAxis]] = fmaxf(\n fminf(availableInnerMainDim + paddingAndBorderAxisMain,\n boundAxisWithinMinAndMax(node, mainAxis, maxLineMainDim)),\n paddingAndBorderAxisMain);\n }\n\n if (measureModeCrossDim === CSS_MEASURE_MODE_UNDEFINED) {\n // Clamp the size to the min/max size, if specified, and make sure it\n // doesn't go below the padding and border amount.\n node.layout[measuredDim[crossAxis]] = boundAxis(node, crossAxis, totalLineCrossDim + paddingAndBorderAxisCross);\n } else if (measureModeCrossDim === CSS_MEASURE_MODE_AT_MOST) {\n node.layout[measuredDim[crossAxis]] = fmaxf(\n fminf(availableInnerCrossDim + paddingAndBorderAxisCross,\n boundAxisWithinMinAndMax(node, crossAxis, totalLineCrossDim + paddingAndBorderAxisCross)),\n paddingAndBorderAxisCross);\n }\n\n // STEP 10: SETTING TRAILING POSITIONS FOR CHILDREN\n if (performLayout) {\n var/*bool*/ needsMainTrailingPos = false;\n var/*bool*/ needsCrossTrailingPos = false;\n\n if (mainAxis === CSS_FLEX_DIRECTION_ROW_REVERSE ||\n mainAxis === CSS_FLEX_DIRECTION_COLUMN_REVERSE) {\n needsMainTrailingPos = true;\n }\n\n if (crossAxis === CSS_FLEX_DIRECTION_ROW_REVERSE ||\n crossAxis === CSS_FLEX_DIRECTION_COLUMN_REVERSE) {\n needsCrossTrailingPos = true;\n }\n\n // Set trailing position if necessary.\n if (needsMainTrailingPos || needsCrossTrailingPos) {\n for (i = 0; i < childCount; ++i) {\n child = node.children[i];\n\n if (needsMainTrailingPos) {\n setTrailingPosition(node, child, mainAxis);\n }\n\n if (needsCrossTrailingPos) {\n setTrailingPosition(node, child, crossAxis);\n }\n }\n }\n }\n\n // STEP 11: SIZING AND POSITIONING ABSOLUTE CHILDREN\n currentAbsoluteChild = firstAbsoluteChild;\n while (currentAbsoluteChild !== undefined) {\n // Now that we know the bounds of the container, perform layout again on the\n // absolutely-positioned children.\n if (performLayout) {\n\n childWidth = CSS_UNDEFINED;\n childHeight = CSS_UNDEFINED;\n\n if (isStyleDimDefined(currentAbsoluteChild, CSS_FLEX_DIRECTION_ROW)) {\n childWidth = currentAbsoluteChild.style.width + getMarginAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_ROW);\n } else {\n // If the child doesn't have a specified width, compute the width based on the left/right offsets if they're defined.\n if (isPosDefined(currentAbsoluteChild, CSS_LEFT) && isPosDefined(currentAbsoluteChild, CSS_RIGHT)) {\n childWidth = node.layout.measuredWidth -\n (getLeadingBorder(node, CSS_FLEX_DIRECTION_ROW) + getTrailingBorder(node, CSS_FLEX_DIRECTION_ROW)) -\n (currentAbsoluteChild.style[CSS_LEFT] + currentAbsoluteChild.style[CSS_RIGHT]);\n childWidth = boundAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_ROW, childWidth);\n }\n }\n\n if (isStyleDimDefined(currentAbsoluteChild, CSS_FLEX_DIRECTION_COLUMN)) {\n childHeight = currentAbsoluteChild.style.height + getMarginAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_COLUMN);\n } else {\n // If the child doesn't have a specified height, compute the height based on the top/bottom offsets if they're defined.\n if (isPosDefined(currentAbsoluteChild, CSS_TOP) && isPosDefined(currentAbsoluteChild, CSS_BOTTOM)) {\n childHeight = node.layout.measuredHeight -\n (getLeadingBorder(node, CSS_FLEX_DIRECTION_COLUMN) + getTrailingBorder(node, CSS_FLEX_DIRECTION_COLUMN)) -\n (currentAbsoluteChild.style[CSS_TOP] + currentAbsoluteChild.style[CSS_BOTTOM]);\n childHeight = boundAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_COLUMN, childHeight);\n }\n }\n\n // If we're still missing one or the other dimension, measure the content.\n if (isUndefined(childWidth) || isUndefined(childHeight)) {\n childWidthMeasureMode = isUndefined(childWidth) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_EXACTLY;\n childHeightMeasureMode = isUndefined(childHeight) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_EXACTLY;\n\n // According to the spec, if the main size is not definite and the\n // child's inline axis is parallel to the main axis (i.e. it's\n // horizontal), the child should be sized using \"UNDEFINED\" in\n // the main size. Otherwise use \"AT_MOST\" in the cross axis.\n if (!isMainAxisRow && isUndefined(childWidth) && !isUndefined(availableInnerWidth)) {\n childWidth = availableInnerWidth;\n childWidthMeasureMode = CSS_MEASURE_MODE_AT_MOST;\n }\n\n // The W3C spec doesn't say anything about the 'overflow' property,\n // but all major browsers appear to implement the following logic.\n if (getOverflow(node) === CSS_OVERFLOW_HIDDEN) {\n if (isMainAxisRow && isUndefined(childHeight) && !isUndefined(availableInnerHeight)) {\n childHeight = availableInnerHeight;\n childHeightMeasureMode = CSS_MEASURE_MODE_AT_MOST;\n }\n }\n\n layoutNodeInternal(currentAbsoluteChild, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, false, 'abs-measure');\n childWidth = currentAbsoluteChild.layout.measuredWidth + getMarginAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_ROW);\n childHeight = currentAbsoluteChild.layout.measuredHeight + getMarginAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_COLUMN);\n }\n\n layoutNodeInternal(currentAbsoluteChild, childWidth, childHeight, direction, CSS_MEASURE_MODE_EXACTLY, CSS_MEASURE_MODE_EXACTLY, true, 'abs-layout');\n\n if (isPosDefined(currentAbsoluteChild, trailing[CSS_FLEX_DIRECTION_ROW]) &&\n !isPosDefined(currentAbsoluteChild, leading[CSS_FLEX_DIRECTION_ROW])) {\n currentAbsoluteChild.layout[leading[CSS_FLEX_DIRECTION_ROW]] =\n node.layout[measuredDim[CSS_FLEX_DIRECTION_ROW]] -\n currentAbsoluteChild.layout[measuredDim[CSS_FLEX_DIRECTION_ROW]] -\n getPosition(currentAbsoluteChild, trailing[CSS_FLEX_DIRECTION_ROW]);\n }\n\n if (isPosDefined(currentAbsoluteChild, trailing[CSS_FLEX_DIRECTION_COLUMN]) &&\n !isPosDefined(currentAbsoluteChild, leading[CSS_FLEX_DIRECTION_COLUMN])) {\n currentAbsoluteChild.layout[leading[CSS_FLEX_DIRECTION_COLUMN]] =\n node.layout[measuredDim[CSS_FLEX_DIRECTION_COLUMN]] -\n currentAbsoluteChild.layout[measuredDim[CSS_FLEX_DIRECTION_COLUMN]] -\n getPosition(currentAbsoluteChild, trailing[CSS_FLEX_DIRECTION_COLUMN]);\n }\n }\n\n currentAbsoluteChild = currentAbsoluteChild.nextChild;\n }\n }\n\n function canUseCachedMeasurement(\n isTextNode,\n availableWidth,\n availableHeight,\n marginRow,\n marginColumn,\n widthMeasureMode,\n heightMeasureMode,\n cachedLayout) {\n\n var isHeightSame =\n (cachedLayout.heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED && heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED) ||\n (cachedLayout.heightMeasureMode == heightMeasureMode && cachedLayout.availableHeight == availableHeight);\n\n var isWidthSame =\n (cachedLayout.widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED && widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED) ||\n (cachedLayout.widthMeasureMode == widthMeasureMode && cachedLayout.availableWidth == availableWidth);\n\n if (isHeightSame && isWidthSame) {\n return true;\n }\n\n var isHeightValid =\n (cachedLayout.heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED && heightMeasureMode == CSS_MEASURE_MODE_AT_MOST && cachedLayout.computedHeight <= (availableHeight - marginColumn)) ||\n (heightMeasureMode == CSS_MEASURE_MODE_EXACTLY && cachedLayout.computedHeight == (availableHeight - marginColumn));\n\n if (isWidthSame && isHeightValid) {\n return true;\n }\n\n var isWidthValid =\n (cachedLayout.widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED && widthMeasureMode == CSS_MEASURE_MODE_AT_MOST && cachedLayout.computedWidth <= (availableWidth - marginRow)) ||\n (widthMeasureMode == CSS_MEASURE_MODE_EXACTLY && cachedLayout.computedWidth == (availableWidth - marginRow));\n\n if (isHeightSame && isWidthValid) {\n return true;\n }\n\n if (isHeightValid && isWidthValid) {\n return true;\n }\n\n // We know this to be text so we can apply some more specialized heuristics.\n if (isTextNode) {\n if (isWidthSame) {\n if (heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED) {\n // Width is the same and height is not restricted. Re-use cahced value.\n return true;\n }\n\n if (heightMeasureMode == CSS_MEASURE_MODE_AT_MOST &&\n cachedLayout.computedHeight < (availableHeight - marginColumn)) {\n // Width is the same and height restriction is greater than the cached height. Re-use cached value.\n return true;\n }\n\n // Width is the same but height restriction imposes smaller height than previously measured.\n // Update the cached value to respect the new height restriction.\n cachedLayout.computedHeight = availableHeight - marginColumn;\n return true;\n }\n\n if (cachedLayout.widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED) {\n if (widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED ||\n (widthMeasureMode == CSS_MEASURE_MODE_AT_MOST &&\n cachedLayout.computedWidth <= (availableWidth - marginRow))) {\n // Previsouly this text was measured with no width restriction, if width is now restricted\n // but to a larger value than the previsouly measured width we can re-use the measurement\n // as we know it will fit.\n return true;\n }\n }\n }\n\n return false;\n }\n\n //\n // This is a wrapper around the layoutNodeImpl function. It determines\n // whether the layout request is redundant and can be skipped.\n //\n // Parameters:\n // Input parameters are the same as layoutNodeImpl (see above)\n // Return parameter is true if layout was performed, false if skipped\n //\n function layoutNodeInternal(node, availableWidth, availableHeight, parentDirection,\n widthMeasureMode, heightMeasureMode, performLayout, reason) {\n var layout = node.layout;\n\n var needToVisitNode = (node.isDirty && layout.generationCount !== gCurrentGenerationCount) ||\n layout.lastParentDirection !== parentDirection;\n\n if (needToVisitNode) {\n // Invalidate the cached results.\n if (layout.cachedMeasurements !== undefined) {\n layout.cachedMeasurements = [];\n }\n if (layout.cachedLayout !== undefined) {\n layout.cachedLayout.widthMeasureMode = undefined;\n layout.cachedLayout.heightMeasureMode = undefined;\n }\n }\n\n var i;\n var len;\n var cachedResults;\n\n // Determine whether the results are already cached. We maintain a separate\n // cache for layouts and measurements. A layout operation modifies the positions\n // and dimensions for nodes in the subtree. The algorithm assumes that each node\n // gets layed out a maximum of one time per tree layout, but multiple measurements\n // may be required to resolve all of the flex dimensions.\n // We handle nodes with measure functions specially here because they are the most\n // expensive to measure, so it's worth avoiding redundant measurements if at all possible.\n if (isMeasureDefined(node)) {\n var marginAxisRow = getMarginAxis(node, CSS_FLEX_DIRECTION_ROW);\n var marginAxisColumn = getMarginAxis(node, CSS_FLEX_DIRECTION_COLUMN);\n\n // First, try to use the layout cache.\n if (layout.cachedLayout &&\n canUseCachedMeasurement(node.isTextNode, availableWidth, availableHeight, marginAxisRow, marginAxisColumn,\n widthMeasureMode, heightMeasureMode, layout.cachedLayout)) {\n cachedResults = layout.cachedLayout;\n } else if (layout.cachedMeasurements) {\n // Try to use the measurement cache.\n for (i = 0, len = layout.cachedMeasurements.length; i < len; i++) {\n if (canUseCachedMeasurement(node.isTextNode, availableWidth, availableHeight, marginAxisRow, marginAxisColumn,\n widthMeasureMode, heightMeasureMode, layout.cachedMeasurements[i])) {\n cachedResults = layout.cachedMeasurements[i];\n break;\n }\n }\n }\n } else if (performLayout) {\n if (layout.cachedLayout &&\n layout.cachedLayout.availableWidth === availableWidth &&\n layout.cachedLayout.availableHeight === availableHeight &&\n layout.cachedLayout.widthMeasureMode === widthMeasureMode &&\n layout.cachedLayout.heightMeasureMode === heightMeasureMode) {\n cachedResults = layout.cachedLayout;\n }\n } else if (layout.cachedMeasurements) {\n for (i = 0, len = layout.cachedMeasurements.length; i < len; i++) {\n if (layout.cachedMeasurements[i].availableWidth === availableWidth &&\n layout.cachedMeasurements[i].availableHeight === availableHeight &&\n layout.cachedMeasurements[i].widthMeasureMode === widthMeasureMode &&\n layout.cachedMeasurements[i].heightMeasureMode === heightMeasureMode) {\n cachedResults = layout.cachedMeasurements[i];\n break;\n }\n }\n }\n\n if (!needToVisitNode && cachedResults !== undefined) {\n layout.measureWidth = cachedResults.computedWidth;\n layout.measureHeight = cachedResults.computedHeight;\n } else {\n layoutNodeImpl(node, availableWidth, availableHeight, parentDirection, widthMeasureMode, heightMeasureMode, performLayout);\n layout.lastParentDirection = parentDirection;\n\n if (cachedResults === undefined) {\n var newCacheEntry;\n if (performLayout) {\n // Use the single layout cache entry.\n if (layout.cachedLayout === undefined) {\n layout.cachedLayout = {};\n }\n newCacheEntry = layout.cachedLayout;\n } else {\n // Allocate a new measurement cache entry.\n if (layout.cachedMeasurements === undefined) {\n layout.cachedMeasurements = [];\n }\n newCacheEntry = {};\n layout.cachedMeasurements.push(newCacheEntry);\n }\n\n newCacheEntry.availableWidth = availableWidth;\n newCacheEntry.availableHeight = availableHeight;\n newCacheEntry.widthMeasureMode = widthMeasureMode;\n newCacheEntry.heightMeasureMode = heightMeasureMode;\n newCacheEntry.computedWidth = layout.measuredWidth;\n newCacheEntry.computedHeight = layout.measuredHeight;\n }\n }\n\n if (performLayout) {\n node.layout.width = node.layout.measuredWidth;\n node.layout.height = node.layout.measuredHeight;\n layout.shouldUpdate = true;\n }\n\n layout.generationCount = gCurrentGenerationCount;\n return (needToVisitNode || cachedResults === undefined);\n }\n\n function layoutNode(node, availableWidth, availableHeight, parentDirection) {\n // Increment the generation count. This will force the recursive routine to visit\n // all dirty nodes at least once. Subsequent visits will be skipped if the input\n // parameters don't change.\n gCurrentGenerationCount++;\n\n var widthMeasureMode = CSS_MEASURE_MODE_UNDEFINED;\n var heightMeasureMode = CSS_MEASURE_MODE_UNDEFINED;\n\n if (!isUndefined(availableWidth)) {\n widthMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n } else if (isStyleDimDefined(node, CSS_FLEX_DIRECTION_ROW)) {\n availableWidth = node.style.width + getMarginAxis(node, CSS_FLEX_DIRECTION_ROW);\n widthMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n } else if (node.style.maxWidth >= 0.0) {\n availableWidth = node.style.maxWidth;\n widthMeasureMode = CSS_MEASURE_MODE_AT_MOST;\n }\n\n if (!isUndefined(availableHeight)) {\n heightMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n } else if (isStyleDimDefined(node, CSS_FLEX_DIRECTION_COLUMN)) {\n availableHeight = node.style.height + getMarginAxis(node, CSS_FLEX_DIRECTION_COLUMN);\n heightMeasureMode = CSS_MEASURE_MODE_EXACTLY;\n } else if (node.style.maxHeight >= 0.0) {\n availableHeight = node.style.maxHeight;\n heightMeasureMode = CSS_MEASURE_MODE_AT_MOST;\n }\n\n if (layoutNodeInternal(node, availableWidth, availableHeight, parentDirection, widthMeasureMode, heightMeasureMode, true, 'initial')) {\n setPosition(node, node.layout.direction);\n }\n }\n\n return {\n layoutNodeImpl: layoutNodeImpl,\n computeLayout: layoutNode,\n fillNodes: fillNodes,\n canUseCachedMeasurement: canUseCachedMeasurement\n };\n})();\n\n// This module export is only used for the purposes of unit testing this file. When\n// the library is packaged this file is included within css-layout.js which forms\n// the public API.\nif (typeof exports === 'object') {\n module.exports = computeLayout;\n}\n\n\n return function(node) {\n /*eslint-disable */\n // disabling ESLint because this code relies on the above include\n computeLayout.fillNodes(node);\n computeLayout.computeLayout(node);\n /*eslint-enable */\n };\n}));\n"]} \ No newline at end of file diff --git a/java/CSharpTranspiler.js b/java/CSharpTranspiler.js deleted file mode 100644 index b9ae21bb..00000000 --- a/java/CSharpTranspiler.js +++ /dev/null @@ -1,195 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -function __transpileToCSharpCommon(code) { - return code - .replace(/'abs-layout'/g, '"abs-layout"') - .replace(/'abs-measure'/g, '"abs-measure"') - .replace(/'flex'/g, '"flex"') - .replace(/'measure'/g, '"measure"') - .replace(/'stretch'/g, '"stretch"') - .replace(/undefined/g, 'null') - .replace(/CSS_UNDEFINED/g, 'CSSConstants.UNDEFINED') - .replace(/CSS_JUSTIFY_/g, 'CSSJustify.') - .replace(/CSS_MEASURE_MODE_/g, 'CSSMeasureMode.') - .replace(/CSS_ALIGN_/g, 'CSSAlign.') - .replace(/CSS_POSITION_/g, 'CSSPositionType.') - .replace(/CSS_OVERFLOW_/g, 'CSSOverflow.') - .replace(/css_flex_direction_t/g, 'CSSFlexDirection') - .replace(/css_direction_t/g, 'CSSDirection') - .replace(/css_align_t/g, 'CSSAlign') - .replace(/css_justify_t/g, 'CSSJustify') - .replace(/css_measure_mode_t/g, 'CSSMeasureMode') - .replace(/css_dim_t/g, 'MeasureOutput') - .replace(/bool/g, 'boolean') - .replace(/style\[CSS_LEFT/g, 'style.position[POSITION_LEFT') - .replace(/style\[CSS_TOP/g, 'style.position[POSITION_TOP') - .replace(/style\[CSS_RIGHT/g, 'style.position[POSITION_RIGHT') - .replace(/style\[CSS_BOTTOM/g, 'style.position[POSITION_BOTTOM') - .replace(/style\[dim/g, 'style.dimensions[dim') - .replace(/(style|layout)\.width/g, '$1.dimensions[DIMENSION_WIDTH]') - .replace(/(style|layout)\.height/g, '$1.dimensions[DIMENSION_HEIGHT]') - .replace(/layout\[dim/g, 'layout.dimensions[dim') - .replace(/layout\[pos/g, 'layout.position[pos') - .replace(/layout\[leading/g, 'layout.position[leading') - .replace(/layout\[trailing/g, 'layout.position[trailing') - .replace(/layout\[measuredDim/g, 'layout.measuredDimensions[dim') - .replace(/layout\.measuredWidth/g, 'layout.measuredDimensions[DIMENSION_WIDTH]') - .replace(/layout\.measuredHeight/g, 'layout.measuredDimensions[DIMENSION_HEIGHT]') - .replace(/getPositionType\((.+?)\)/g, '$1.style.positionType') - .replace(/getJustifyContent\((.+?)\)/g, '$1.style.justifyContent') - .replace(/getAlignContent\((.+?)\)/g, '$1.style.alignContent') - .replace(/isPosDefined\((.+?),\s*(.+?)\)/g, '!isUndefined\($1.style.position[$2]\)') - .replace(/isStyleDimDefined\((.+?),\s*(.+?)\)/g, '($1.style.dimensions[dim[$2]] >= 0.0)') - .replace(/isLayoutDimDefined\((.+?),\s*(.+?)\)/g, '($1.layout.measuredDimensions[dim[$2]] >= 0.0)') - .replace(/getPosition\((.+?),\s*(.+?)\)/g, '\(isUndefined\($1.style.position[$2]\) ? 0 : $1.style.position[$2]\)') - .replace(/setTrailingPosition\((.+?),\s*(.+?),\s*(.+?)\)/g, '$2.layout.position[trailing[$3]] = $1.layout.measuredDimensions[dim[$3]] - ($2.style.positionType == CSSPositionType.Absolute ? 0 : $2.layout.measuredDimensions[dim[$3]]) - $2.layout.position[pos[$3]]') - .replace(/isFlex\((.+?)\)/g, '\($1.style.positionType == CSSPositionType.RELATIVE && $1.style.flex != 0\)') - .replace(/isFlexWrap\((.+?)\)/g, '\($1.style.flexWrap == CSSWrap.WRAP\)') - .replace(/getPaddingAndBorderAxis\((.+?),\s*(.+?)\)/g, '\(getLeadingPaddingAndBorder($1, $2) + getTrailingPaddingAndBorder($1, $2)\)') - .replace(/getMarginAxis\((.+?),\s*(.+?)\)/g, '\(getLeadingMargin($1, $2) + getTrailingMargin($1, $2)\)') - .replace(/getLeadingPaddingAndBorder\((.+?),\s*(.+?)\)/g, '\(getLeadingPadding($1, $2) + getLeadingBorder($1, $2)\)') - .replace(/getTrailingPaddingAndBorder\((.+?),\s*(.+?)\)/g, '\(getTrailingPadding($1, $2) + getTrailingBorder($1, $2)\)') - .replace(/getDimWithMargin\((.+?),\s*(.+?)\)/g, '\($1.layout.measuredDimensions[dim[$2]] + getLeadingMargin($1, $2) + getTrailingMargin($1, $2)\)') - .replace(/getLeadingMargin\((.+?),\s*(.+?)\)/g, '$1.style.margin.getWithFallback(leadingSpacing[$2], leading[$2])') - .replace(/getTrailingMargin\((.+?),\s*(.+?)\)/g, '$1.style.margin.getWithFallback(trailingSpacing[$2], trailing[$2])') - .replace(/getLeadingPadding\((.+?),\s*(.+?)\)/g, '$1.style.padding.getWithFallback(leadingSpacing[$2], leading[$2])') - .replace(/getTrailingPadding\((.+?),\s*(.+?)\)/g, '$1.style.padding.getWithFallback(trailingSpacing[$2], trailing[$2])') - .replace(/getLeadingBorder\((.+?),\s*(.+?)\)/g, '$1.style.border.getWithFallback(leadingSpacing[$2], leading[$2])') - .replace(/getTrailingBorder\((.+?),\s*(.+?)\)/g, '$1.style.border.getWithFallback(trailingSpacing[$2], trailing[$2])') - .replace(/isRowDirection\((.+?)\)/g, '\($1 == CSS_FLEX_DIRECTION_ROW || $1 == CSS_FLEX_DIRECTION_ROW_REVERSE\)') - .replace(/assert\((.+?),\s*'(.+?)'\)/g, 'Assertions.assertCondition($1, "$2")') - .replace(/isUndefined\((.+?)\)/g, 'float.IsNaN\($1\)') - .replace(/getOverflow\((.+?)\)/g, '$1.style.overflow') - .replace(/layoutNodeInternal\((.+?)\)/g, 'layoutNodeInternal(layoutContext, $1)') - .replace(/style\.position\[CSS_/g, 'style.position[POSITION_') - .replace(/\/\*\(c\)!([^*]+)\*\//g, '') - .replace(/var\/\*\(java\)!([^*]+)\*\//g, '$1') - .replace(/\/\*\(java\)!([^*]+)\*\//g, '$1') - - // additional case conversions - - .replace(/(CSSConstants|CSSWrap|CSSJustify|CSSMeasureMode|CSSAlign|CSSPositionType|CSSOverflow)\.([_A-Z]+)/g, - function(str, match1, match2) { - return match1 + '.' + constantToPascalCase(match2); - }); -} - -function __transpileSingleTestToCSharp(code) { - return __transpileToCSharpCommon(code) - .replace(/CSS_DIRECTION_/g, 'CSSDirection.') - .replace(/CSS_FLEX_DIRECTION_/g, 'CSSFlexDirection.') - .replace(/CSS_WRAP/g, 'CSSWrap.WRAP') - .replace(/new_test_css_node/g, 'new TestCSSNode') - .replace(// style.position[CSS_TOP] => style.position[CSSLayout.POSITION_TOP] - /(style|layout)\.position\[CSS_(LEFT|TOP|RIGHT|BOTTOM)\]/g, - function(str, match1, match2) { - return match1 + '.position[POSITION_' + match2 + ']'; - }) - .replace(// style.dimensions[CSS_WIDTH] => style.dimensions[CSSLayout.DIMENSION_WIDTH] - /(style|layout)\.dimensions\[CSS_(WIDTH|HEIGHT)\]/g, - function(str, match1, match2) { - return match1 + '.dimensions[DIMENSION_' + match2 + ']'; - }) - .replace(// style.maxDimensions[CSS_WIDTH] => style.maxWidth - /(style|layout)\.maxDimensions\[CSS_(WIDTH|HEIGHT)\]/g, - function(str, match1, match2) { - return match1 + '.max' + match2.substr(0, 1).toUpperCase() + match2.substr(1).toLowerCase(); - }) - .replace(// style.minDimensions[CSS_WIDTH] => style.minWidth - /(style|layout)\.minDimensions\[CSS_(WIDTH|HEIGHT)\]/g, - function(str, match1, match2) { - return match1 + '.min' + match2.substr(0, 1).toUpperCase() + match2.substr(1).toLowerCase(); - }) - .replace(// style.margin[CSS_TOP] = 12.3 => style.margin[Spacing.TOP].set(12.3) - /style\.(margin|border|padding)\[CSS_(TOP|BOTTOM|LEFT|RIGHT|START|END)\]\s+=\s+(-?[\.\d]+)/g, - function(str, match1, match2, match3) { - var propertyCap = match1.charAt(0).toUpperCase() + match1.slice(1); - return 'set' + propertyCap + '(Spacing.' + match2 + ', ' + match3 + ')'; - }) - .replace(// style.margin[CSS_TOP] => style.margin[Spacing.TOP] - /style\.(margin|border|padding)\[CSS_(TOP|BOTTOM|LEFT|RIGHT|START|END)\]/g, - function(str, match1, match2) { - return 'style.' + match1 + '.get(Spacing.' + match2 + ')'; - }) - .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+.+/g, '$1.setMeasureFunction(sTestMeasureFunction);') - - // additional case conversions - - .replace(/(CSSWrap|CSSFlexDirection)\.([_A-Z]+)/g, - function(str, match1, match2) { - return match1 + '.' + constantToPascalCase(match2); - }); -} - -function indent(code) { - return code - .split('\n') - .map(function(line) { return ' ' + line; }) - .join('\n'); -} - -function constantToPascalCase(str) { - return str[0] + str.substr(1) - .toLowerCase() - .replace(/_(.)/g, - function(_, m) { return m.toUpperCase(); }); -} - -var CSharpTranspiler = { - transpileLayoutEngine: function(code) { - return indent( - __transpileToCSharpCommon(code) - .replace('node.style.measure', 'node.measure') - .replace(/\.children\.length/g, '.getChildCount()') - .replace(/node.children\[i\]/g, 'node.getChildAt(i)') - .replace(/node.children\[j\]/g, 'node.getChildAt(j)') - .replace(/fmaxf/g, 'Math.Max') - .replace(/fminf/g, 'Math.Min') - .replace(/\/\*\([^\/]+\*\/\n/g, '') // remove comments for other languages - .replace(/var\/\*([^\/]+)\*\//g, '$1') - .replace(/ === /g, ' == ') - .replace(/ !== /g, ' != ') - .replace(/\n {2}/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 readonly string $1 = $2;') - .replace(/#define\s+(\w+)\s+(.+)/g, 'public static readonly float $1 = $2f;')); - }, - - transpileCTestsArray: function(allTestsInC) { - var allTestsInCSharp = []; - for (var i = 0; i < allTestsInC.length; i++) { - allTestsInCSharp[i] = - ' [Test]\n' + - ' public void TestCase' + i + '()\n' + - __transpileSingleTestToCSharp(allTestsInC[i]); - } - return allTestsInCSharp.join('\n\n'); - } -}; - -if (typeof module !== 'undefined') { - module.exports = CSharpTranspiler; -} diff --git a/java/JavaTranspiler.js b/java/JavaTranspiler.js deleted file mode 100644 index c7ec14b1..00000000 --- a/java/JavaTranspiler.js +++ /dev/null @@ -1,174 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -function __transpileToJavaCommon(code) { - return code - .replace(/'abs-layout'/g, '"abs-layout"') - .replace(/'abs-measure'/g, '"abs-measure"') - .replace(/'flex'/g, '"flex"') - .replace(/'measure'/g, '"measure"') - .replace(/'stretch'/g, '"stretch"') - .replace(/undefined/g, 'null') - .replace(/CSS_UNDEFINED/g, 'CSSConstants.UNDEFINED') - .replace(/CSS_JUSTIFY_/g, 'CSSJustify.') - .replace(/CSS_MEASURE_MODE_/g, 'CSSMeasureMode.') - .replace(/CSS_ALIGN_/g, 'CSSAlign.') - .replace(/CSS_POSITION_/g, 'CSSPositionType.') - .replace(/CSS_OVERFLOW_/g, 'CSSOverflow.') - .replace(/css_flex_direction_t/g, 'CSSFlexDirection') - .replace(/css_direction_t/g, 'CSSDirection') - .replace(/css_align_t/g, 'CSSAlign') - .replace(/css_justify_t/g, 'CSSJustify') - .replace(/css_measure_mode_t/g, 'CSSMeasureMode') - .replace(/css_dim_t/g, 'MeasureOutput') - .replace(/bool/g, 'boolean') - .replace(/style\[CSS_LEFT/g, 'style.position[POSITION_LEFT') - .replace(/style\[CSS_TOP/g, 'style.position[POSITION_TOP') - .replace(/style\[CSS_RIGHT/g, 'style.position[POSITION_RIGHT') - .replace(/style\[CSS_BOTTOM/g, 'style.position[POSITION_BOTTOM') - .replace(/style\[dim/g, 'style.dimensions[dim') - .replace(/(style|layout)\.width/g, '$1.dimensions[DIMENSION_WIDTH]') - .replace(/(style|layout)\.height/g, '$1.dimensions[DIMENSION_HEIGHT]') - .replace(/layout\[dim/g, 'layout.dimensions[dim') - .replace(/layout\[pos/g, 'layout.position[pos') - .replace(/layout\[leading/g, 'layout.position[leading') - .replace(/layout\[trailing/g, 'layout.position[trailing') - .replace(/layout\[measuredDim/g, 'layout.measuredDimensions[dim') - .replace(/layout\.measuredWidth/g, 'layout.measuredDimensions[DIMENSION_WIDTH]') - .replace(/layout\.measuredHeight/g, 'layout.measuredDimensions[DIMENSION_HEIGHT]') - .replace(/getPositionType\((.+?)\)/g, '$1.style.positionType') - .replace(/getJustifyContent\((.+?)\)/g, '$1.style.justifyContent') - .replace(/getAlignContent\((.+?)\)/g, '$1.style.alignContent') - .replace(/isPosDefined\((.+?),\s*(.+?)\)/g, '!isUndefined\($1.style.position[$2]\)') - .replace(/isStyleDimDefined\((.+?),\s*(.+?)\)/g, '($1.style.dimensions[dim[$2]] >= 0.0)') - .replace(/isLayoutDimDefined\((.+?),\s*(.+?)\)/g, '($1.layout.measuredDimensions[dim[$2]] >= 0.0)') - .replace(/getPosition\((.+?),\s*(.+?)\)/g, '\(isUndefined\($1.style.position[$2]\) ? 0 : $1.style.position[$2]\)') - .replace(/setTrailingPosition\((.+?),\s*(.+?),\s*(.+?)\)/g, '$2.layout.position[trailing[$3]] = $1.layout.measuredDimensions[dim[$3]] - ($2.style.positionType == CSSPositionType.ABSOLUTE ? 0 : $2.layout.measuredDimensions[dim[$3]]) - $2.layout.position[pos[$3]]') - .replace(/isFlex\((.+?)\)/g, '\($1.style.positionType == CSSPositionType.RELATIVE && $1.style.flex != 0\)') - .replace(/isFlexWrap\((.+?)\)/g, '\($1.style.flexWrap == CSSWrap.WRAP\)') - .replace(/getPaddingAndBorderAxis\((.+?),\s*(.+?)\)/g, '\(getLeadingPaddingAndBorder($1, $2) + getTrailingPaddingAndBorder($1, $2)\)') - .replace(/getMarginAxis\((.+?),\s*(.+?)\)/g, '\(getLeadingMargin($1, $2) + getTrailingMargin($1, $2)\)') - .replace(/getLeadingPaddingAndBorder\((.+?),\s*(.+?)\)/g, '\(getLeadingPadding($1, $2) + getLeadingBorder($1, $2)\)') - .replace(/getTrailingPaddingAndBorder\((.+?),\s*(.+?)\)/g, '\(getTrailingPadding($1, $2) + getTrailingBorder($1, $2)\)') - .replace(/getDimWithMargin\((.+?),\s*(.+?)\)/g, '\($1.layout.measuredDimensions[dim[$2]] + getLeadingMargin($1, $2) + getTrailingMargin($1, $2)\)') - .replace(/getLeadingMargin\((.+?),\s*(.+?)\)/g, '$1.style.margin.getWithFallback(leadingSpacing[$2], leading[$2])') - .replace(/getTrailingMargin\((.+?),\s*(.+?)\)/g, '$1.style.margin.getWithFallback(trailingSpacing[$2], trailing[$2])') - .replace(/getLeadingPadding\((.+?),\s*(.+?)\)/g, '$1.style.padding.getWithFallback(leadingSpacing[$2], leading[$2])') - .replace(/getTrailingPadding\((.+?),\s*(.+?)\)/g, '$1.style.padding.getWithFallback(trailingSpacing[$2], trailing[$2])') - .replace(/getLeadingBorder\((.+?),\s*(.+?)\)/g, '$1.style.border.getWithFallback(leadingSpacing[$2], leading[$2])') - .replace(/getTrailingBorder\((.+?),\s*(.+?)\)/g, '$1.style.border.getWithFallback(trailingSpacing[$2], trailing[$2])') - .replace(/isRowDirection\((.+?)\)/g, '\($1 == CSS_FLEX_DIRECTION_ROW || $1 == CSS_FLEX_DIRECTION_ROW_REVERSE\)') - .replace(/assert\((.+?),\s*'(.+?)'\)/g, 'Assertions.assertCondition($1, "$2")') - .replace(/isUndefined\((.+?)\)/g, 'Float.isNaN\($1\)') - .replace(/getOverflow\((.+?)\)/g, '$1.style.overflow') - .replace(/layoutNodeInternal\((.+?)\)/g, 'layoutNodeInternal(layoutContext, $1)') - .replace(/style\.position\[CSS_/g, 'style.position[POSITION_') - .replace(/\/\*\(c\)!([^*]+)\*\//g, '') - .replace(/var\/\*\(java\)!([^*]+)\*\//g, '$1') - .replace(/\/\*\(java\)!([^*]+)\*\//g, '$1'); -} - -function __transpileSingleTestToJava(code) { - return __transpileToJavaCommon(code) - .replace(/CSS_DIRECTION_/g, 'CSSDirection.') - .replace(/CSS_FLEX_DIRECTION_/g, 'CSSFlexDirection.') - .replace(/CSS_WRAP/g, 'CSSWrap.WRAP') - .replace(/new_test_css_node/g, 'new TestCSSNode') - .replace(// style.position[CSS_TOP] => style.position[CSSLayout.POSITION_TOP] - /(style|layout)\.position\[CSS_(LEFT|TOP|RIGHT|BOTTOM)\]/g, - function(str, match1, match2) { - return match1 + '.position[POSITION_' + match2 + ']'; - }) - .replace(// style.dimensions[CSS_WIDTH] => style.dimensions[CSSLayout.DIMENSION_WIDTH] - /(style|layout)\.dimensions\[CSS_(WIDTH|HEIGHT)\]/g, - function(str, match1, match2) { - return match1 + '.dimensions[DIMENSION_' + match2 + ']'; - }) - .replace(// style.maxDimensions[CSS_WIDTH] => style.maxWidth - /(style|layout)\.maxDimensions\[CSS_(WIDTH|HEIGHT)\]/g, - function(str, match1, match2) { - return match1 + '.max' + match2.substr(0, 1).toUpperCase() + match2.substr(1).toLowerCase(); - }) - .replace(// style.minDimensions[CSS_WIDTH] => style.minWidth - /(style|layout)\.minDimensions\[CSS_(WIDTH|HEIGHT)\]/g, - function(str, match1, match2) { - return match1 + '.min' + match2.substr(0, 1).toUpperCase() + match2.substr(1).toLowerCase(); - }) - .replace(// style.margin[CSS_TOP] = 12.3 => style.margin[Spacing.TOP].set(12.3) - /style\.(margin|border|padding)\[CSS_(TOP|BOTTOM|LEFT|RIGHT|START|END)\]\s+=\s+(-?[\.\d]+)/g, - function(str, match1, match2, match3) { - var propertyCap = match1.charAt(0).toUpperCase() + match1.slice(1); - return 'set' + propertyCap + '(Spacing.' + match2 + ', ' + match3 + ')'; - }) - .replace(// style.margin[CSS_TOP] => style.margin[Spacing.TOP] - /style\.(margin|border|padding)\[CSS_(TOP|BOTTOM|LEFT|RIGHT|START|END)\]/g, - function(str, match1, match2) { - return 'style.' + match1 + '.get(Spacing.' + match2 + ')'; - }) - .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+.+/g, '$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('node.style.measure', 'node.measure') - .replace(/\.children\.length/g, '.getChildCount()') - .replace(/node.children\[i\]/g, 'node.getChildAt(i)') - .replace(/node.children\[j\]/g, 'node.getChildAt(j)') - .replace(/fmaxf/g, 'Math.max') - .replace(/fminf/g, 'Math.min') - .replace(/\/\*\([^\/]+\*\/\n/g, '') // remove comments for other languages - .replace(/var\/\*([^\/]+)\*\//g, '$1') - .replace(/ === /g, ' == ') - .replace(/ !== /g, ' != ') - .replace(/\n {2}/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/java/Layout-test-utils.c b/java/Layout-test-utils.c deleted file mode 100644 index 06237650..00000000 --- a/java/Layout-test-utils.c +++ /dev/null @@ -1,216 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -#include "Layout-test-utils.h" -#include - -#ifdef _MSC_VER -#include -#define isnan _isnan - -/* define fmaxf & fminf if < VC12 */ -#if _MSC_VER < 1800 -__forceinline const float fmaxf(const float a, const float b) { - return (a > b) ? a : b; -} -__forceinline const float fminf(const float a, const float b) { - return (a < b) ? a : b; -} -#endif -#endif - - /** START_GENERATED **/ -#define SMALL_WIDTH 35 -#define SMALL_HEIGHT 18 -#define BIG_WIDTH 172 -#define BIG_HEIGHT 36 -#define BIG_MIN_WIDTH 100 -#define SMALL_TEXT "small" -#define LONG_TEXT "loooooooooong with space" -#define MEASURE_WITH_RATIO_2 "measureWithRatio2" -#define MEASURE_WITH_MATCH_PARENT "measureWithMatchParent" - /** END_GENERATED **/ - -typedef struct failed_test_t { - struct failed_test_t *next; - const char *name; - css_node_t *style; - css_node_t *expected; -} failed_test_t; - -static failed_test_t *failed_test_head = NULL; -static failed_test_t *failed_test_tail = NULL; -static void add_failed_test(const char *name, css_node_t *style, css_node_t *expected) { - failed_test_t *failed_test = (failed_test_t *)malloc(sizeof(failed_test_t)); - failed_test->next = NULL; - failed_test->name = name; - failed_test->style = style; - failed_test->expected = expected; - - if (!failed_test_head) { - failed_test_head = failed_test; - failed_test_tail = failed_test; - } else { - failed_test_tail->next = failed_test; - failed_test_tail = failed_test; - } -} - -static bool eq(float a, float b) { - return fabs(a - b) < 0.0001; -} - -static bool are_layout_equal(css_node_t *a, css_node_t *b) { - if (!eq(a->layout.dimensions[CSS_WIDTH], b->layout.dimensions[CSS_WIDTH]) || - !eq(a->layout.dimensions[CSS_HEIGHT], b->layout.dimensions[CSS_HEIGHT]) || - !eq(a->layout.position[CSS_TOP], b->layout.position[CSS_TOP]) || - !eq(a->layout.position[CSS_LEFT], b->layout.position[CSS_LEFT]) || - !eq(a->children_count, b->children_count)) { - return false; - } - for (int i = 0; i < a->children_count; ++i) { - if (!are_layout_equal(a->get_child(a->context, i), b->get_child(b->context, i))) { - return false; - } - } - return true; -} - -css_dim_t measure(void *context, float width, css_measure_mode_t widthMode, float height, css_measure_mode_t heightMode) { - const char *text = (const char *)context; - css_dim_t dim; - if (strcmp(text, SMALL_TEXT) == 0) { - if (widthMode == CSS_MEASURE_MODE_UNDEFINED) { - width = 1000000; - } - dim.dimensions[CSS_WIDTH] = fminf(SMALL_WIDTH, width); - dim.dimensions[CSS_HEIGHT] = SMALL_HEIGHT; - return dim; - } - if (strcmp(text, LONG_TEXT) == 0) { - if (widthMode == CSS_MEASURE_MODE_UNDEFINED) { - width = 1000000; - } - dim.dimensions[CSS_WIDTH] = width >= BIG_WIDTH ? BIG_WIDTH : fmaxf(BIG_MIN_WIDTH, width); - dim.dimensions[CSS_HEIGHT] = width >= BIG_WIDTH ? SMALL_HEIGHT : BIG_HEIGHT; - return dim; - } - - if (strcmp(text, MEASURE_WITH_RATIO_2) == 0) { - if (widthMode != CSS_MEASURE_MODE_UNDEFINED) { - dim.dimensions[CSS_WIDTH] = width; - dim.dimensions[CSS_HEIGHT] = width * 2; - } else if (heightMode != CSS_MEASURE_MODE_UNDEFINED) { - dim.dimensions[CSS_WIDTH] = height * 2; - dim.dimensions[CSS_HEIGHT] = height; - } else { - dim.dimensions[CSS_WIDTH] = 99999; - dim.dimensions[CSS_HEIGHT] = 99999; - } - return dim; - } - - if (strcmp(text, MEASURE_WITH_MATCH_PARENT) == 0) { - if (widthMode == CSS_MEASURE_MODE_UNDEFINED) { - width = 99999; - } - if (heightMode == CSS_MEASURE_MODE_UNDEFINED) { - height = 99999; - } - dim.dimensions[CSS_WIDTH] = width; - dim.dimensions[CSS_HEIGHT] = height; - return dim; - } - - // Should not go here - dim.dimensions[CSS_WIDTH] = CSS_UNDEFINED; - dim.dimensions[CSS_HEIGHT] = CSS_UNDEFINED; - return dim; -} - -static int test_ran_count = 0; -void test(const char *name, css_node_t *style, css_node_t *expected_layout) { - ++test_ran_count; - layoutNode(style, CSS_UNDEFINED, CSS_UNDEFINED, (css_direction_t)-1); - - if (!are_layout_equal(style, expected_layout)) { - printf("%sF%s", "\x1B[31m", "\x1B[0m"); - add_failed_test(name, style, expected_layout); - } else { - printf("%s.%s", "\x1B[32m", "\x1B[0m"); - free_css_node(style); - free_css_node(expected_layout); - } -} - -int tests_finished() { - failed_test_t *failed_test = failed_test_head; - printf("\n"); - - int tests_failed = 0; - while (failed_test) { - printf("%sFAIL%s %s\n", "\x1B[31m", "\x1B[0m", failed_test->name); - - printf("Input: "); - print_css_node(failed_test->style, (css_print_options_t)(CSS_PRINT_STYLE | CSS_PRINT_CHILDREN)); - printf("Output: "); - print_css_node(failed_test->style, (css_print_options_t)(CSS_PRINT_LAYOUT | CSS_PRINT_CHILDREN)); - - printf("Expected: "); - print_css_node(failed_test->expected, (css_print_options_t)(CSS_PRINT_LAYOUT | CSS_PRINT_CHILDREN)); - - free_css_node(failed_test->style); - free_css_node(failed_test->expected); - - failed_test_t *next_failed_test = failed_test->next; - free(failed_test); - failed_test = next_failed_test; - - tests_failed++; - } - printf("\n\n"); - - if (tests_failed > 0) { - printf("TESTS FAILED: %d\n", tests_failed); - return 1; - } else { - printf("ALL TESTS PASSED: %d tests ran.\n", test_ran_count); - return 0; - } -} - -static css_node_t* get_child(void *context, int i) { - css_node_t* children = (css_node_t*)context; - return &children[i]; -} - -static bool is_dirty(void *context) { - (void)context; // remove unused warning - return true; -} - -static void init_test_css_node(css_node_t *node) { - node->get_child = get_child; - node->is_dirty = is_dirty; -} - -css_node_t *new_test_css_node(void) { - css_node_t *node = new_css_node(); - init_test_css_node(node); - return node; -} - -void init_css_node_children(css_node_t *node, int children_count) { - node->context = calloc((size_t)children_count, sizeof(css_node_t)); - for (int i = 0; i < children_count; ++i) { - init_css_node(node->get_child(node->context, i)); - init_test_css_node(node->get_child(node->context, i)); - } - node->children_count = children_count; -} diff --git a/java/Layout-test-utils.h b/java/Layout-test-utils.h deleted file mode 100644 index a83162f9..00000000 --- a/java/Layout-test-utils.h +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -#include "Layout.h" -#include -#include - -void test(const char *name, css_node_t *style, css_node_t *expected_layout); -int tests_finished(void); -css_dim_t measure(void *context, float width, css_measure_mode_t widthMode, float height, css_measure_mode_t heightMode); -void init_css_node_children(css_node_t *node, int children_count); -css_node_t *new_test_css_node(void); diff --git a/java/Layout-test-utils.js b/java/Layout-test-utils.js deleted file mode 100644 index 6d9e6b1e..00000000 --- a/java/Layout-test-utils.js +++ /dev/null @@ -1,604 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ -/* globals document, computeLayout, navigator */ - -var layoutTestUtils = (function() { - - // - // Sets the test cases precision, by default set to 1.0, aka pixel precision - // (assuming the browser does pixel snapping - and that we're ok with being - // 'only' pixel perfect). - // - // Set it to '10' for .1 precision, etc... in theory the browser is doing - // 'pixel' snapping so 1.0 should do, the code is left for clarity... - // - // Set it to undefined to disable and use full precision. - // - var testMeasurePrecision = 1.0; - - if (typeof jasmine !== 'undefined') { - jasmine.matchersUtil.buildFailureMessage = function() { - var args = Array.prototype.slice.call(arguments, 0); - var matcherName = args[0]; - var isNot = args[1]; - var actual = args[2]; - var expected = args.slice(3); - var englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); }); - - var pp = function(node) { - return jasmine.pp(node) - .replace(/([\{\[]) /g, '$1') - .replace(/ ([\}\]:])/g, '$1'); - }; - - var message = 'Expected ' + - pp(actual) + - (isNot ? ' not ' : ' ') + - '\n' + - englishyPredicate; - - if (expected.length > 0) { - for (var i = 0; i < expected.length; i++) { - if (i > 0) { - message += ','; - } - message += ' ' + pp(expected[i]); - } - } - - return message + '.'; - }; - } - - var _cachedIframe; - - function renderIframe() { - var iframe = document.createElement('iframe'); - document.body.appendChild(iframe); - return iframe; - } - - function getIframe(iframe) { - if (_cachedIframe) { - return _cachedIframe; - } - - var doc = iframe.contentDocument; - - if (doc.readyState === 'complete') { - var style = document.createElement('style'); - style.textContent = (function() {/* - body, div { - box-sizing: border-box; - border: 0 solid black; - position: relative; - - display: flex; - display: -webkit-flex; - flex-direction: column; - -webkit-flex-direction: column; - align-items: stretch; - -webkit-align-items: stretch; - justify-content: flex-start; - -webkit-justify-content: flex-start; - flex-shrink: 0; - -webkit-flex-shrink: 0; - - margin: 0; - padding: 0; - min-width: 0; - } - - hack to ignore three hundred px width of the body {} - body > div { - align-self: flex-start; - } - */} + '').slice(15, -4); - doc.head.appendChild(style); - _cachedIframe = iframe; - return iframe; - } else { - setTimeout(getIframe.bind(null, iframe), 0); - } - } - - if (typeof window !== 'undefined') { - var iframe = renderIframe(); - getIframe(iframe); - } - - if (typeof computeLayout === 'object') { - var fillNodes = computeLayout.fillNodes; - var realComputeLayout = computeLayout.computeLayout; - var canUseCachedMeasurement = computeLayout.canUseCachedMeasurement; - } - - function extractNodes(node) { - var keysToCopy = [ - 'width', - 'height', - 'left', - 'top' - ]; - var layout = {}; - keysToCopy.forEach(function(key) { - layout[key] = node.layout[key]; - }); - - if (node.children && node.children.length > 0) { - layout.children = node.children.map(extractNodes); - } else { - delete node.children; - } - - delete node.layout; - - return layout; - } - - function roundLayout(layout) { - // Chrome rounds all the numbers with a precision of 1/64 - // Reproduce the same behavior - function round(number) { - var floored = Math.floor(number); - var decimal = number - floored; - if (decimal === 0) { - return number; - } - var minDifference = Infinity; - var minDecimal = Infinity; - for (var i = 1; i < 64; ++i) { - var roundedDecimal = i / 64; - var difference = Math.abs(roundedDecimal - decimal); - if (difference < minDifference) { - minDifference = difference; - minDecimal = roundedDecimal; - } - } - return floored + minDecimal; - } - - function rec(layout) { - layout.top = round(layout.top); - layout.left = round(layout.left); - layout.width = round(layout.width); - layout.height = round(layout.height); - if (layout.children) { - for (var i = 0; i < layout.children.length; ++i) { - rec(layout.children[i]); - } - } - } - - rec(layout); - return layout; - } - - function capitalizeFirst(str) { - return str.charAt(0).toUpperCase() + str.slice(1); - } - - function computeCSSLayout(rootNode) { - fillNodes(rootNode); - realComputeLayout(rootNode); - return roundLayout(extractNodes(rootNode)); - } - - function computeDOMLayout(node) { - var body = getIframe().contentDocument.body; - - function setStyle(div, name, value) { - div.style['-webkit-' + name] = value; - div.style['webkit' + capitalizeFirst(name)] = value; - div.style[name] = value; - } - - function transfer(div, node, name, ext) { - if (name in node.style) { - var value = node.style[name] + (ext || ''); - setStyle(div, name, value); - } - } - - function transferSpacing(div, node, type, suffix) { - transfer(div, node, type + suffix, 'px'); - transfer(div, node, type + 'Left' + suffix, 'px'); - transfer(div, node, type + 'Top' + suffix, 'px'); - transfer(div, node, type + 'Bottom' + suffix, 'px'); - transfer(div, node, type + 'Right' + suffix, 'px'); - transfer(div, node, type + 'Start' + suffix, 'px'); - transfer(div, node, type + 'End' + suffix, 'px'); - } - - function transferFlex(div, node) { - if ('flex' in node.style) { - var flex = node.style.flex; - var resolvedFlex = ( - flex < 0 ? '0 1 auto' : - flex > 0 ? (flex + ' 0 0') : - '0 0 auto' - ); - setStyle(div, 'flex', resolvedFlex); - } - } - - function renderNode(parent, node) { - var div = document.createElement('div'); - transfer(div, node, 'width', 'px'); - transfer(div, node, 'height', 'px'); - transfer(div, node, 'minWidth', 'px'); - transfer(div, node, 'minHeight', 'px'); - transfer(div, node, 'maxWidth', 'px'); - transfer(div, node, 'maxHeight', 'px'); - transfer(div, node, 'top', 'px'); - transfer(div, node, 'left', 'px'); - transfer(div, node, 'right', 'px'); - transfer(div, node, 'bottom', 'px'); - transferSpacing(div, node, 'margin', ''); - transferSpacing(div, node, 'padding', ''); - transferSpacing(div, node, 'border', 'Width'); - transfer(div, node, 'flexDirection'); - transfer(div, node, 'direction'); - transferFlex(div, node); - transfer(div, node, 'flexWrap'); - transfer(div, node, 'justifyContent'); - transfer(div, node, 'alignSelf'); - transfer(div, node, 'alignItems'); - transfer(div, node, 'alignContent'); - transfer(div, node, 'position'); - transfer(div, node, 'overflow'); - parent.appendChild(div); - (node.children || []).forEach(function(child) { - renderNode(div, child); - }); - if (node.style.measure) { - div.innerText = node.style.measure.toString(); - } - return div; - } - - var div = renderNode(body, node); - - function buildLayout(absoluteRect, div) { - var rect = div.getBoundingClientRect(); - var result = { - width: rect.width, - height: rect.height, - top: rect.top - absoluteRect.top, - left: rect.left - absoluteRect.left - }; - - var children = []; - for (var child = div.firstChild; child; child = child.nextSibling) { - if (child.nodeType !== 3 /* textNode */) { - children.push(buildLayout(rect, child)); - } - } - if (children.length) { - result.children = children; - } - return result; - } - var layout = buildLayout({left: 0, top: 0}, div); - body.removeChild(div); - return layout; - } - - function inplaceRoundNumbersInObject(obj) { - if (!testMeasurePrecision) { - // undefined/0, disables rounding - return; - } - - for (var key in obj) { - if (!obj.hasOwnProperty(key)) { - continue; - } - - var val = obj[key]; - if (typeof val === 'number') { - obj[key] = Math.floor((val * testMeasurePrecision) + 0.5) / testMeasurePrecision; - } else if (typeof val === 'object') { - inplaceRoundNumbersInObject(val); - } - } - } - - function nameLayout(name, layout) { - var namedLayout = {name: name}; - for (var key in layout) { - namedLayout[key] = layout[key]; - } - return namedLayout; - } - - function testFillNodes(node, filledNode) { - expect(fillNodes(node)).toEqual(filledNode); - } - - function testExtractNodes(node, extractedNode) { - expect(extractNodes(node)).toEqual(extractedNode); - } - - function testCanUseCachedMeasurement(canReuse, spec, cacheEntry) { - var availableWidth = spec.availableWidth; - var availableHeight = spec.availableHeight; - var widthMeasureMode = spec.widthMeasureMode; - var heightMeasureMode = spec.heightMeasureMode; - - expect( - canUseCachedMeasurement( - availableWidth, availableHeight, - 0, 0, - widthMeasureMode, heightMeasureMode, - cacheEntry - ) - ).toEqual(canReuse); - } - - function testNamedLayout(name, layoutA, layoutB) { - expect(nameLayout(name, layoutA)) - .toEqual(nameLayout(name, layoutB)); - } - - function isEqual(a, b) { - // computeCSSLayout and computeDOMLayout output a tree with same ordered elements - return JSON.stringify(a) === JSON.stringify(b); - } - - function reduceTest(node) { - function isWorking() { - return isEqual( - computeDOMLayout(node), - computeCSSLayout(node) - ); - } - if (isWorking()) { - return node; - } - - var isModified = true; - - function rec(node) { - var key; - var value; - - // Style - for (key in node.style) { - value = node.style[key]; - delete node.style[key]; - if (isWorking()) { - node.style[key] = value; - } else { - isModified = true; - } - } - // Round values - for (key in node.style) { - value = node.style[key]; - if (value > 100) { - node.style[key] = Math.round(value / 100) * 100; - } else if (value > 10) { - node.style[key] = Math.round(value / 10) * 10; - } else if (value > 1) { - node.style[key] = 5; - } - if (node.style[key] !== value) { - if (isWorking()) { - node.style[key] = value; - } else { - isModified = true; - } - } - } - // Children - for (var i = 0; node.children && i < node.children.length; ++i) { - value = node.children[i]; - node.children.splice(i, 1); - if (isWorking()) { - if (!node.children) { - node.children = []; - } - node.children.splice(i, 0, value); - rec(node.children[i]); - } else { - i--; - isModified = true; - } - } - } - while (isModified) { - isModified = false; - rec(node); - } - - return node; - } - - var iframeText; - function measureTextSizes(text, width) { - iframeText = iframeText || document.createElement('iframe'); - document.body.appendChild(iframeText); - - var body = iframeText.contentDocument.body; - if (width === undefined || isNaN(width)) { - width = Infinity; - } - - var div = document.createElement('div'); - div.style.width = (width === Infinity ? 10000000 : width) + 'px'; - div.style.display = 'flex'; - div.style.flexDirection = 'column'; - div.style.alignItems = 'flex-start'; - div.style.alignContent = 'flex-start'; - - var span = document.createElement('span'); - span.style.display = 'flex'; - span.style.flexDirection = 'column'; - span.style.alignItems = 'flex-start'; - span.style.alignContent = 'flex-start'; - span.innerText = text; - - div.appendChild(span); - body.appendChild(div); - var rect = span.getBoundingClientRect(); - body.removeChild(div); - return { - width: rect.width, - height: rect.height - }; - } - - var texts = { - small: 'small', - big: 'loooooooooong with space' - }; - - var preDefinedTextSizes = { - smallWidth: 34.671875, - smallHeight: 18, - bigWidth: 172.421875, - bigHeight: 36, - bigMinWidth: 100.4375 - }; - - // Note(prenaux): Clearly not what I would like, but it seems to be the only - // way :( My guess is that since the font on Windows is - // different than on OSX it has a different size. - if (typeof navigator !== 'undefined' && navigator.userAgent.indexOf('Windows NT') > -1) { - preDefinedTextSizes.bigHeight = 36; - } - - var textSizes; - if (typeof require === 'function') { - textSizes = preDefinedTextSizes; - } else { - textSizes = { - smallWidth: measureTextSizes(texts.small, 0).width, - smallHeight: measureTextSizes(texts.small, 0).height, - bigWidth: measureTextSizes(texts.big).width, - bigHeight: measureTextSizes(texts.big, 0).height, - bigMinWidth: measureTextSizes(texts.big, 0).width - }; - } - - // round the text sizes so that we dont have to update it for every browser - // update, assumes we're ok with pixel precision - inplaceRoundNumbersInObject(preDefinedTextSizes); - inplaceRoundNumbersInObject(textSizes); - - return { - texts: texts, - textSizes: textSizes, - preDefinedTextSizes: preDefinedTextSizes, - testLayout: function(node, expectedLayout) { - var layout = computeCSSLayout(node); - var domLayout = computeDOMLayout(node); - inplaceRoundNumbersInObject(layout); - inplaceRoundNumbersInObject(domLayout); - inplaceRoundNumbersInObject(expectedLayout); - testNamedLayout('expected-dom', expectedLayout, domLayout); - testNamedLayout('layout-dom', layout, domLayout); - }, - testLayoutAgainstDomOnly: function(node) { - var layout = computeCSSLayout(node); - var domLayout = computeDOMLayout(node); - inplaceRoundNumbersInObject(layout); - inplaceRoundNumbersInObject(domLayout); - testNamedLayout('layout-dom', layout, domLayout); - }, - testLayoutAgainstExpectedOnly: function(node, expectedLayout) { - var layout = computeCSSLayout(node); - inplaceRoundNumbersInObject(layout); - inplaceRoundNumbersInObject(expectedLayout); - testNamedLayout('expected-dom', expectedLayout, layout); - }, - testFillNodes: testFillNodes, - testExtractNodes: testExtractNodes, - testCanUseCachedMeasurement: testCanUseCachedMeasurement, - testRandomLayout: function(node) { - var layout = computeCSSLayout(node); - var domLayout = computeDOMLayout(node); - inplaceRoundNumbersInObject(layout); - inplaceRoundNumbersInObject(domLayout); - expect({node: node, layout: layout}) - .toEqual({node: node, layout: domLayout}); - }, - testsFinished: function() { - console.log('tests finished!'); - }, - computeLayout: computeCSSLayout, - computeDOMLayout: computeDOMLayout, - reduceTest: reduceTest, - text: function(text) { - var fn = function(width, widthMode, height, heightMode) { - if (widthMode === 'undefined') { - width = Infinity; - } - - // Constants for testing purposes between C/JS and other platforms - // Comment this block of code if you want to use the browser to - // generate proper sizes - if (text === texts.small) { - return { - width: Math.min(textSizes.smallWidth, width), - height: textSizes.smallHeight - }; - } - if (text === texts.big) { - var res = { - width: width >= textSizes.bigWidth ? textSizes.bigWidth : Math.max(textSizes.bigMinWidth, width), - height: width >= textSizes.bigWidth ? textSizes.smallHeight : textSizes.bigHeight - }; - return res; - } - }; - // Name of the function is used in DOM tests as a text in the measured node - // and as a way to tell different measure functions apart in transpiled tests - fn.toString = function() { return text; }; - return fn; - }, - measureWithRatio2: function() { - var fn = function(width, widthMode, height, heightMode) { - if (widthMode !== 'undefined') { - height = width * 2; - } else if (heightMode !== 'undefined') { - width = height * 2; - } else { - // This should be Infinity, but it would be pain to transpile, - // so let's just go with big numbers. - height = 99999; - width = 99999; - } - return {width: width, height: height}; - }; - // This is necessary for transpiled tests, see previous comment - fn.toString = function() { return 'measureWithRatio2'; }; - return fn; - }, - measureWithMatchParent: function() { - var fn = function(width, widthMode, height, heightMode) { - if (widthMode === 'undefined') { - width = 99999; - } - if (heightMode === 'undefined') { - height = 99999; - } - return {width: width, height: height}; - }; - // This is necessary for transpiled tests, see previous comment - fn.toString = function() { return 'measureWithMatchParent'; }; - return fn; - } - }; -})(); - -if (typeof module !== 'undefined') { - module.exports = layoutTestUtils; -} diff --git a/java/Layout.c b/java/Layout.c deleted file mode 100644 index a8e12f85..00000000 --- a/java/Layout.c +++ /dev/null @@ -1,1817 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -#include -#include -#include -#include -#include - -// in concatenated header, don't include Layout.h it's already at the top -#ifndef CSS_LAYOUT_IMPLEMENTATION -#include "Layout.h" -#endif - -#ifdef _MSC_VER -#include -#define isnan _isnan - -/* define fmaxf if < VC12 */ -#if _MSC_VER < 1800 -__forceinline const float fmaxf(const float a, const float b) { - return (a > b) ? a : b; -} -#endif -#endif - -#define POSITIVE_FLEX_IS_AUTO 0 - -int gCurrentGenerationCount = 0; - -bool layoutNodeInternal(css_node_t* node, float availableWidth, float availableHeight, css_direction_t parentDirection, - css_measure_mode_t widthMeasureMode, css_measure_mode_t heightMeasureMode, bool performLayout, char* reason); - -bool isUndefined(float value) { - return isnan(value); -} - -static bool eq(float a, float b) { - if (isUndefined(a)) { - return isUndefined(b); - } - return fabs(a - b) < 0.0001; -} - -void init_css_node(css_node_t* node) { - node->style.align_items = CSS_ALIGN_STRETCH; - node->style.align_content = CSS_ALIGN_FLEX_START; - - node->style.direction = CSS_DIRECTION_INHERIT; - node->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN; - - node->style.overflow = CSS_OVERFLOW_VISIBLE; - - // Some of the fields default to undefined and not 0 - node->style.dimensions[CSS_WIDTH] = CSS_UNDEFINED; - node->style.dimensions[CSS_HEIGHT] = CSS_UNDEFINED; - - node->style.minDimensions[CSS_WIDTH] = CSS_UNDEFINED; - node->style.minDimensions[CSS_HEIGHT] = CSS_UNDEFINED; - - node->style.maxDimensions[CSS_WIDTH] = CSS_UNDEFINED; - node->style.maxDimensions[CSS_HEIGHT] = CSS_UNDEFINED; - - node->style.position[CSS_LEFT] = CSS_UNDEFINED; - node->style.position[CSS_TOP] = CSS_UNDEFINED; - node->style.position[CSS_RIGHT] = CSS_UNDEFINED; - node->style.position[CSS_BOTTOM] = CSS_UNDEFINED; - - node->style.margin[CSS_START] = CSS_UNDEFINED; - node->style.margin[CSS_END] = CSS_UNDEFINED; - node->style.padding[CSS_START] = CSS_UNDEFINED; - node->style.padding[CSS_END] = CSS_UNDEFINED; - node->style.border[CSS_START] = CSS_UNDEFINED; - node->style.border[CSS_END] = CSS_UNDEFINED; - - node->layout.dimensions[CSS_WIDTH] = CSS_UNDEFINED; - node->layout.dimensions[CSS_HEIGHT] = CSS_UNDEFINED; - - // Such that the comparison is always going to be false - node->layout.last_parent_direction = (css_direction_t)-1; - node->layout.should_update = true; - node->layout.next_cached_measurements_index = 0; - - node->layout.measured_dimensions[CSS_WIDTH] = CSS_UNDEFINED; - node->layout.measured_dimensions[CSS_HEIGHT] = CSS_UNDEFINED; - node->layout.cached_layout.width_measure_mode = (css_measure_mode_t)-1; - node->layout.cached_layout.height_measure_mode = (css_measure_mode_t)-1; -} - -css_node_t* new_css_node() { - css_node_t* node = (css_node_t*)calloc(1, sizeof(*node)); - init_css_node(node); - return node; -} - -void free_css_node(css_node_t* node) { - free(node); -} - -static void indent(int n) { - for (int i = 0; i < n; ++i) { - printf(" "); - } -} - -static void print_number_0(const char* str, float number) { - if (!eq(number, 0)) { - printf("%s: %g, ", str, number); - } -} - -static void print_number_nan(const char* str, float number) { - if (!isnan(number)) { - printf("%s: %g, ", str, number); - } -} - -static bool four_equal(float four[4]) { - return - eq(four[0], four[1]) && - eq(four[0], four[2]) && - eq(four[0], four[3]); -} - - -static void print_css_node_rec( - css_node_t* node, - css_print_options_t options, - int level -) { - indent(level); - printf("{"); - - if (node->print) { - node->print(node->context); - } - - if (options & CSS_PRINT_LAYOUT) { - printf("layout: {"); - printf("width: %g, ", node->layout.dimensions[CSS_WIDTH]); - printf("height: %g, ", node->layout.dimensions[CSS_HEIGHT]); - printf("top: %g, ", node->layout.position[CSS_TOP]); - printf("left: %g", node->layout.position[CSS_LEFT]); - printf("}, "); - } - - if (options & CSS_PRINT_STYLE) { - if (node->style.flex_direction == CSS_FLEX_DIRECTION_COLUMN) { - printf("flexDirection: 'column', "); - } else if (node->style.flex_direction == CSS_FLEX_DIRECTION_COLUMN_REVERSE) { - printf("flexDirection: 'column-reverse', "); - } else if (node->style.flex_direction == CSS_FLEX_DIRECTION_ROW) { - printf("flexDirection: 'row', "); - } else if (node->style.flex_direction == CSS_FLEX_DIRECTION_ROW_REVERSE) { - printf("flexDirection: 'row-reverse', "); - } - - if (node->style.justify_content == CSS_JUSTIFY_CENTER) { - printf("justifyContent: 'center', "); - } else if (node->style.justify_content == CSS_JUSTIFY_FLEX_END) { - printf("justifyContent: 'flex-end', "); - } else if (node->style.justify_content == CSS_JUSTIFY_SPACE_AROUND) { - printf("justifyContent: 'space-around', "); - } else if (node->style.justify_content == CSS_JUSTIFY_SPACE_BETWEEN) { - printf("justifyContent: 'space-between', "); - } - - if (node->style.align_items == CSS_ALIGN_CENTER) { - printf("alignItems: 'center', "); - } else if (node->style.align_items == CSS_ALIGN_FLEX_END) { - printf("alignItems: 'flex-end', "); - } else if (node->style.align_items == CSS_ALIGN_STRETCH) { - printf("alignItems: 'stretch', "); - } - - if (node->style.align_content == CSS_ALIGN_CENTER) { - printf("alignContent: 'center', "); - } else if (node->style.align_content == CSS_ALIGN_FLEX_END) { - printf("alignContent: 'flex-end', "); - } else if (node->style.align_content == CSS_ALIGN_STRETCH) { - printf("alignContent: 'stretch', "); - } - - if (node->style.align_self == CSS_ALIGN_FLEX_START) { - printf("alignSelf: 'flex-start', "); - } else if (node->style.align_self == CSS_ALIGN_CENTER) { - printf("alignSelf: 'center', "); - } else if (node->style.align_self == CSS_ALIGN_FLEX_END) { - printf("alignSelf: 'flex-end', "); - } else if (node->style.align_self == CSS_ALIGN_STRETCH) { - printf("alignSelf: 'stretch', "); - } - - print_number_nan("flex", node->style.flex); - - if (node->style.overflow == CSS_OVERFLOW_HIDDEN) { - printf("overflow: 'hidden', "); - } else if (node->style.overflow == CSS_OVERFLOW_VISIBLE) { - printf("overflow: 'visible', "); - } - - if (four_equal(node->style.margin)) { - print_number_0("margin", node->style.margin[CSS_LEFT]); - } else { - print_number_0("marginLeft", node->style.margin[CSS_LEFT]); - print_number_0("marginRight", node->style.margin[CSS_RIGHT]); - print_number_0("marginTop", node->style.margin[CSS_TOP]); - print_number_0("marginBottom", node->style.margin[CSS_BOTTOM]); - print_number_0("marginStart", node->style.margin[CSS_START]); - print_number_0("marginEnd", node->style.margin[CSS_END]); - } - - if (four_equal(node->style.padding)) { - print_number_0("padding", node->style.padding[CSS_LEFT]); - } else { - print_number_0("paddingLeft", node->style.padding[CSS_LEFT]); - print_number_0("paddingRight", node->style.padding[CSS_RIGHT]); - print_number_0("paddingTop", node->style.padding[CSS_TOP]); - print_number_0("paddingBottom", node->style.padding[CSS_BOTTOM]); - print_number_0("paddingStart", node->style.padding[CSS_START]); - print_number_0("paddingEnd", node->style.padding[CSS_END]); - } - - if (four_equal(node->style.border)) { - print_number_0("borderWidth", node->style.border[CSS_LEFT]); - } else { - print_number_0("borderLeftWidth", node->style.border[CSS_LEFT]); - print_number_0("borderRightWidth", node->style.border[CSS_RIGHT]); - print_number_0("borderTopWidth", node->style.border[CSS_TOP]); - print_number_0("borderBottomWidth", node->style.border[CSS_BOTTOM]); - print_number_0("borderStartWidth", node->style.border[CSS_START]); - print_number_0("borderEndWidth", node->style.border[CSS_END]); - } - - print_number_nan("width", node->style.dimensions[CSS_WIDTH]); - print_number_nan("height", node->style.dimensions[CSS_HEIGHT]); - print_number_nan("maxWidth", node->style.maxDimensions[CSS_WIDTH]); - print_number_nan("maxHeight", node->style.maxDimensions[CSS_HEIGHT]); - print_number_nan("minWidth", node->style.minDimensions[CSS_WIDTH]); - print_number_nan("minHeight", node->style.minDimensions[CSS_HEIGHT]); - - if (node->style.position_type == CSS_POSITION_ABSOLUTE) { - printf("position: 'absolute', "); - } - - print_number_nan("left", node->style.position[CSS_LEFT]); - print_number_nan("right", node->style.position[CSS_RIGHT]); - print_number_nan("top", node->style.position[CSS_TOP]); - print_number_nan("bottom", node->style.position[CSS_BOTTOM]); - } - - if (options & CSS_PRINT_CHILDREN && node->children_count > 0) { - printf("children: [\n"); - for (int i = 0; i < node->children_count; ++i) { - print_css_node_rec(node->get_child(node->context, i), options, level + 1); - } - indent(level); - printf("]},\n"); - } else { - printf("},\n"); - } -} - -void print_css_node(css_node_t* node, css_print_options_t options) { - print_css_node_rec(node, options, 0); -} - -static css_position_t leading[4] = { - /* CSS_FLEX_DIRECTION_COLUMN = */ CSS_TOP, - /* CSS_FLEX_DIRECTION_COLUMN_REVERSE = */ CSS_BOTTOM, - /* CSS_FLEX_DIRECTION_ROW = */ CSS_LEFT, - /* CSS_FLEX_DIRECTION_ROW_REVERSE = */ CSS_RIGHT -}; -static css_position_t trailing[4] = { - /* CSS_FLEX_DIRECTION_COLUMN = */ CSS_BOTTOM, - /* CSS_FLEX_DIRECTION_COLUMN_REVERSE = */ CSS_TOP, - /* CSS_FLEX_DIRECTION_ROW = */ CSS_RIGHT, - /* CSS_FLEX_DIRECTION_ROW_REVERSE = */ CSS_LEFT -}; -static css_position_t pos[4] = { - /* CSS_FLEX_DIRECTION_COLUMN = */ CSS_TOP, - /* CSS_FLEX_DIRECTION_COLUMN_REVERSE = */ CSS_BOTTOM, - /* CSS_FLEX_DIRECTION_ROW = */ CSS_LEFT, - /* CSS_FLEX_DIRECTION_ROW_REVERSE = */ CSS_RIGHT -}; -static css_dimension_t dim[4] = { - /* CSS_FLEX_DIRECTION_COLUMN = */ CSS_HEIGHT, - /* CSS_FLEX_DIRECTION_COLUMN_REVERSE = */ CSS_HEIGHT, - /* CSS_FLEX_DIRECTION_ROW = */ CSS_WIDTH, - /* CSS_FLEX_DIRECTION_ROW_REVERSE = */ CSS_WIDTH -}; - -static bool isRowDirection(css_flex_direction_t flex_direction) { - return flex_direction == CSS_FLEX_DIRECTION_ROW || - flex_direction == CSS_FLEX_DIRECTION_ROW_REVERSE; -} - -static bool isColumnDirection(css_flex_direction_t flex_direction) { - return flex_direction == CSS_FLEX_DIRECTION_COLUMN || - flex_direction == CSS_FLEX_DIRECTION_COLUMN_REVERSE; -} - -static bool isFlexBasisAuto(css_node_t* node) { -#if POSITIVE_FLEX_IS_AUTO - // All flex values are auto. - (void) node; - return true; -#else - // A flex value > 0 implies a basis of zero. - return node->style.flex <= 0; -#endif -} - -static float getFlexGrowFactor(css_node_t* node) { - // Flex grow is implied by positive values for flex. - if (node->style.flex > 0) { - return node->style.flex; - } - return 0; -} - -static float getFlexShrinkFactor(css_node_t* node) { -#if POSITIVE_FLEX_IS_AUTO - // A flex shrink factor of 1 is implied by non-zero values for flex. - if (node->style.flex != 0) { - return 1; - } -#else - // A flex shrink factor of 1 is implied by negative values for flex. - if (node->style.flex < 0) { - return 1; - } -#endif - return 0; -} - -static float getLeadingMargin(css_node_t* node, css_flex_direction_t axis) { - if (isRowDirection(axis) && !isUndefined(node->style.margin[CSS_START])) { - return node->style.margin[CSS_START]; - } - - return node->style.margin[leading[axis]]; -} - -static float getTrailingMargin(css_node_t* node, css_flex_direction_t axis) { - if (isRowDirection(axis) && !isUndefined(node->style.margin[CSS_END])) { - return node->style.margin[CSS_END]; - } - - return node->style.margin[trailing[axis]]; -} - -static float getLeadingPadding(css_node_t* node, css_flex_direction_t axis) { - if (isRowDirection(axis) && - !isUndefined(node->style.padding[CSS_START]) && - node->style.padding[CSS_START] >= 0) { - return node->style.padding[CSS_START]; - } - - if (node->style.padding[leading[axis]] >= 0) { - return node->style.padding[leading[axis]]; - } - - return 0; -} - -static float getTrailingPadding(css_node_t* node, css_flex_direction_t axis) { - if (isRowDirection(axis) && - !isUndefined(node->style.padding[CSS_END]) && - node->style.padding[CSS_END] >= 0) { - return node->style.padding[CSS_END]; - } - - if (node->style.padding[trailing[axis]] >= 0) { - return node->style.padding[trailing[axis]]; - } - - return 0; -} - -static float getLeadingBorder(css_node_t* node, css_flex_direction_t axis) { - if (isRowDirection(axis) && - !isUndefined(node->style.border[CSS_START]) && - node->style.border[CSS_START] >= 0) { - return node->style.border[CSS_START]; - } - - if (node->style.border[leading[axis]] >= 0) { - return node->style.border[leading[axis]]; - } - - return 0; -} - -static float getTrailingBorder(css_node_t* node, css_flex_direction_t axis) { - if (isRowDirection(axis) && - !isUndefined(node->style.border[CSS_END]) && - node->style.border[CSS_END] >= 0) { - return node->style.border[CSS_END]; - } - - if (node->style.border[trailing[axis]] >= 0) { - return node->style.border[trailing[axis]]; - } - - return 0; -} - -static float getLeadingPaddingAndBorder(css_node_t* node, css_flex_direction_t axis) { - return getLeadingPadding(node, axis) + getLeadingBorder(node, axis); -} - -static float getTrailingPaddingAndBorder(css_node_t* node, css_flex_direction_t axis) { - return getTrailingPadding(node, axis) + getTrailingBorder(node, axis); -} - -static float getMarginAxis(css_node_t* node, css_flex_direction_t axis) { - return getLeadingMargin(node, axis) + getTrailingMargin(node, axis); -} - -static float getPaddingAndBorderAxis(css_node_t* node, css_flex_direction_t axis) { - return getLeadingPaddingAndBorder(node, axis) + getTrailingPaddingAndBorder(node, axis); -} - -static css_align_t getAlignItem(css_node_t* node, css_node_t* child) { - if (child->style.align_self != CSS_ALIGN_AUTO) { - return child->style.align_self; - } - return node->style.align_items; -} - -static css_direction_t resolveDirection(css_node_t* node, css_direction_t parentDirection) { - css_direction_t direction = node->style.direction; - - if (direction == CSS_DIRECTION_INHERIT) { - direction = parentDirection > CSS_DIRECTION_INHERIT ? parentDirection : CSS_DIRECTION_LTR; - } - - return direction; -} - -static css_flex_direction_t getFlexDirection(css_node_t* node) { - return node->style.flex_direction; -} - -static css_flex_direction_t resolveAxis(css_flex_direction_t flex_direction, css_direction_t direction) { - if (direction == CSS_DIRECTION_RTL) { - if (flex_direction == CSS_FLEX_DIRECTION_ROW) { - return CSS_FLEX_DIRECTION_ROW_REVERSE; - } else if (flex_direction == CSS_FLEX_DIRECTION_ROW_REVERSE) { - return CSS_FLEX_DIRECTION_ROW; - } - } - - return flex_direction; -} - -static css_flex_direction_t getCrossFlexDirection(css_flex_direction_t flex_direction, css_direction_t direction) { - if (isColumnDirection(flex_direction)) { - return resolveAxis(CSS_FLEX_DIRECTION_ROW, direction); - } else { - return CSS_FLEX_DIRECTION_COLUMN; - } -} - -static float getFlex(css_node_t* node) { - return node->style.flex; -} - -static bool isFlex(css_node_t* node) { - return ( - node->style.position_type == CSS_POSITION_RELATIVE && - getFlex(node) != 0 - ); -} - -static bool isFlexWrap(css_node_t* node) { - return node->style.flex_wrap == CSS_WRAP; -} - -static float getDimWithMargin(css_node_t* node, css_flex_direction_t axis) { - return node->layout.measured_dimensions[dim[axis]] + - getLeadingMargin(node, axis) + - getTrailingMargin(node, axis); -} - -static bool isStyleDimDefined(css_node_t* node, css_flex_direction_t axis) { - float value = node->style.dimensions[dim[axis]]; - return !isUndefined(value) && value >= 0.0; -} - -static bool isLayoutDimDefined(css_node_t* node, css_flex_direction_t axis) { - float value = node->layout.measured_dimensions[dim[axis]]; - return !isUndefined(value) && value >= 0.0; -} - -static bool isPosDefined(css_node_t* node, css_position_t position) { - return !isUndefined(node->style.position[position]); -} - -static bool isMeasureDefined(css_node_t* node) { - return node->measure; -} - -static float getPosition(css_node_t* node, css_position_t position) { - float result = node->style.position[position]; - if (!isUndefined(result)) { - return result; - } - return 0; -} - -static float boundAxisWithinMinAndMax(css_node_t* node, css_flex_direction_t axis, float value) { - float min = CSS_UNDEFINED; - float max = CSS_UNDEFINED; - - if (isColumnDirection(axis)) { - min = node->style.minDimensions[CSS_HEIGHT]; - max = node->style.maxDimensions[CSS_HEIGHT]; - } else if (isRowDirection(axis)) { - min = node->style.minDimensions[CSS_WIDTH]; - max = node->style.maxDimensions[CSS_WIDTH]; - } - - float boundValue = value; - - if (!isUndefined(max) && max >= 0.0 && boundValue > max) { - boundValue = max; - } - if (!isUndefined(min) && min >= 0.0 && boundValue < min) { - boundValue = min; - } - - return boundValue; -} - -// Like boundAxisWithinMinAndMax but also ensures that the value doesn't go below the -// padding and border amount. -static float boundAxis(css_node_t* node, css_flex_direction_t axis, float value) { - return fmaxf(boundAxisWithinMinAndMax(node, axis, value), getPaddingAndBorderAxis(node, axis)); -} - -static void setTrailingPosition(css_node_t* node, css_node_t* child, css_flex_direction_t axis) { - float size = child->style.position_type == CSS_POSITION_ABSOLUTE ? - 0 : - child->layout.measured_dimensions[dim[axis]]; - child->layout.position[trailing[axis]] = node->layout.measured_dimensions[dim[axis]] - size - child->layout.position[pos[axis]]; -} - -// If both left and right are defined, then use left. Otherwise return -// +left or -right depending on which is defined. -static float getRelativePosition(css_node_t* node, css_flex_direction_t axis) { - float lead = node->style.position[leading[axis]]; - if (!isUndefined(lead)) { - return lead; - } - return -getPosition(node, trailing[axis]); -} - -static void setPosition(css_node_t* node, css_direction_t direction) { - css_flex_direction_t mainAxis = resolveAxis(getFlexDirection(node), direction); - css_flex_direction_t crossAxis = getCrossFlexDirection(mainAxis, direction); - - node->layout.position[leading[mainAxis]] = getLeadingMargin(node, mainAxis) + - getRelativePosition(node, mainAxis); - node->layout.position[trailing[mainAxis]] = getTrailingMargin(node, mainAxis) + - getRelativePosition(node, mainAxis); - node->layout.position[leading[crossAxis]] = getLeadingMargin(node, crossAxis) + - getRelativePosition(node, crossAxis); - node->layout.position[trailing[crossAxis]] = getTrailingMargin(node, crossAxis) + - getRelativePosition(node, crossAxis); -} - -// -// This is the main routine that implements a subset of the flexbox layout algorithm -// described in the W3C CSS documentation: https://www.w3.org/TR/css3-flexbox/. -// -// Limitations of this algorithm, compared to the full standard: -// * Display property is always assumed to be 'flex' except for Text nodes, which -// are assumed to be 'inline-flex'. -// * The 'zIndex' property (or any form of z ordering) is not supported. Nodes are -// stacked in document order. -// * The 'order' property is not supported. The order of flex items is always defined -// by document order. -// * The 'visibility' property is always assumed to be 'visible'. Values of 'collapse' -// and 'hidden' are not supported. -// * The 'wrap' property supports only 'nowrap' (which is the default) or 'wrap'. The -// rarely-used 'wrap-reverse' is not supported. -// * Rather than allowing arbitrary combinations of flexGrow, flexShrink and -// flexBasis, this algorithm supports only the three most common combinations: -// flex: 0 is equiavlent to flex: 0 0 auto -// flex: n (where n is a positive value) is equivalent to flex: n 1 auto -// If POSITIVE_FLEX_IS_AUTO is 0, then it is equivalent to flex: n 0 0 -// This is faster because the content doesn't need to be measured, but it's -// less flexible because the basis is always 0 and can't be overriden with -// the width/height attributes. -// flex: -1 (or any negative value) is equivalent to flex: 0 1 auto -// * Margins cannot be specified as 'auto'. They must be specified in terms of pixel -// values, and the default value is 0. -// * The 'baseline' value is not supported for alignItems and alignSelf properties. -// * Values of width, maxWidth, minWidth, height, maxHeight and minHeight must be -// specified as pixel values, not as percentages. -// * There is no support for calculation of dimensions based on intrinsic aspect ratios -// (e.g. images). -// * There is no support for forced breaks. -// * It does not support vertical inline directions (top-to-bottom or bottom-to-top text). -// -// Deviations from standard: -// * Section 4.5 of the spec indicates that all flex items have a default minimum -// main size. For text blocks, for example, this is the width of the widest word. -// Calculating the minimum width is expensive, so we forego it and assume a default -// minimum main size of 0. -// * Min/Max sizes in the main axis are not honored when resolving flexible lengths. -// * The spec indicates that the default value for 'flexDirection' is 'row', but -// the algorithm below assumes a default of 'column'. -// -// Input parameters: -// - node: current node to be sized and layed out -// - availableWidth & availableHeight: available size to be used for sizing the node -// or CSS_UNDEFINED if the size is not available; interpretation depends on layout -// flags -// - parentDirection: the inline (text) direction within the parent (left-to-right or -// right-to-left) -// - widthMeasureMode: indicates the sizing rules for the width (see below for explanation) -// - heightMeasureMode: indicates the sizing rules for the height (see below for explanation) -// - performLayout: specifies whether the caller is interested in just the dimensions -// of the node or it requires the entire node and its subtree to be layed out -// (with final positions) -// -// Details: -// This routine is called recursively to lay out subtrees of flexbox elements. It uses the -// information in node.style, which is treated as a read-only input. It is responsible for -// setting the layout.direction and layout.measured_dimensions fields for the input node as well -// as the layout.position and layout.line_index fields for its child nodes. The -// layout.measured_dimensions field includes any border or padding for the node but does -// not include margins. -// -// The spec describes four different layout modes: "fill available", "max content", "min content", -// and "fit content". Of these, we don't use "min content" because we don't support default -// minimum main sizes (see above for details). Each of our measure modes maps to a layout mode -// from the spec (https://www.w3.org/TR/css3-sizing/#terms): -// - CSS_MEASURE_MODE_UNDEFINED: max content -// - CSS_MEASURE_MODE_EXACTLY: fill available -// - CSS_MEASURE_MODE_AT_MOST: fit content -// -// When calling layoutNodeImpl and layoutNodeInternal, if the caller passes an available size of -// undefined then it must also pass a measure mode of CSS_MEASURE_MODE_UNDEFINED in that dimension. -// -static void layoutNodeImpl(css_node_t* node, float availableWidth, float availableHeight, - css_direction_t parentDirection, css_measure_mode_t widthMeasureMode, css_measure_mode_t heightMeasureMode, bool performLayout) { - /** START_GENERATED **/ - - assert(isUndefined(availableWidth) ? widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED : true); // availableWidth is indefinite so widthMeasureMode must be CSS_MEASURE_MODE_UNDEFINED - assert(isUndefined(availableHeight) ? heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED : true); // availableHeight is indefinite so heightMeasureMode must be CSS_MEASURE_MODE_UNDEFINED - - float paddingAndBorderAxisRow = getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW); - float paddingAndBorderAxisColumn = getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN); - float marginAxisRow = getMarginAxis(node, CSS_FLEX_DIRECTION_ROW); - float marginAxisColumn = getMarginAxis(node, CSS_FLEX_DIRECTION_COLUMN); - - // Set the resolved resolution in the node's layout. - css_direction_t direction = resolveDirection(node, parentDirection); - node->layout.direction = direction; - - // For content (text) nodes, determine the dimensions based on the text contents. - if (isMeasureDefined(node)) { - float innerWidth = availableWidth - marginAxisRow - paddingAndBorderAxisRow; - float innerHeight = availableHeight - marginAxisColumn - paddingAndBorderAxisColumn; - - if (widthMeasureMode == CSS_MEASURE_MODE_EXACTLY && heightMeasureMode == CSS_MEASURE_MODE_EXACTLY) { - - // Don't bother sizing the text if both dimensions are already defined. - node->layout.measured_dimensions[CSS_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, availableWidth - marginAxisRow); - node->layout.measured_dimensions[CSS_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, availableHeight - marginAxisColumn); - } else if (innerWidth <= 0 || innerHeight <= 0) { - - // Don't bother sizing the text if there's no horizontal or vertical space. - node->layout.measured_dimensions[CSS_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, 0); - node->layout.measured_dimensions[CSS_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, 0); - } else { - - // Measure the text under the current constraints. - css_dim_t measureDim = node->measure( - node->context, - - innerWidth, - widthMeasureMode, - innerHeight, - heightMeasureMode - ); - - node->layout.measured_dimensions[CSS_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, - (widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED || widthMeasureMode == CSS_MEASURE_MODE_AT_MOST) ? - measureDim.dimensions[CSS_WIDTH] + paddingAndBorderAxisRow : - availableWidth - marginAxisRow); - node->layout.measured_dimensions[CSS_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, - (heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED || heightMeasureMode == CSS_MEASURE_MODE_AT_MOST) ? - measureDim.dimensions[CSS_HEIGHT] + paddingAndBorderAxisColumn : - availableHeight - marginAxisColumn); - } - - return; - } - - // For nodes with no children, use the available values if they were provided, or - // the minimum size as indicated by the padding and border sizes. - int childCount = node->children_count; - if (childCount == 0) { - node->layout.measured_dimensions[CSS_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, - (widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED || widthMeasureMode == CSS_MEASURE_MODE_AT_MOST) ? - paddingAndBorderAxisRow : - availableWidth - marginAxisRow); - node->layout.measured_dimensions[CSS_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, - (heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED || heightMeasureMode == CSS_MEASURE_MODE_AT_MOST) ? - paddingAndBorderAxisColumn : - availableHeight - marginAxisColumn); - return; - } - - // If we're not being asked to perform a full layout, we can handle a number of common - // cases here without incurring the cost of the remaining function. - if (!performLayout) { - // If we're being asked to size the content with an at most constraint but there is no available width, - // the measurement will always be zero. - if (widthMeasureMode == CSS_MEASURE_MODE_AT_MOST && availableWidth <= 0 && - heightMeasureMode == CSS_MEASURE_MODE_AT_MOST && availableHeight <= 0) { - node->layout.measured_dimensions[CSS_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, 0); - node->layout.measured_dimensions[CSS_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, 0); - return; - } - - if (widthMeasureMode == CSS_MEASURE_MODE_AT_MOST && availableWidth <= 0) { - node->layout.measured_dimensions[CSS_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, 0); - node->layout.measured_dimensions[CSS_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, isUndefined(availableHeight) ? 0 : (availableHeight - marginAxisColumn)); - return; - } - - if (heightMeasureMode == CSS_MEASURE_MODE_AT_MOST && availableHeight <= 0) { - node->layout.measured_dimensions[CSS_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, isUndefined(availableWidth) ? 0 : (availableWidth - marginAxisRow)); - node->layout.measured_dimensions[CSS_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, 0); - return; - } - - // If we're being asked to use an exact width/height, there's no need to measure the children. - if (widthMeasureMode == CSS_MEASURE_MODE_EXACTLY && heightMeasureMode == CSS_MEASURE_MODE_EXACTLY) { - node->layout.measured_dimensions[CSS_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, availableWidth - marginAxisRow); - node->layout.measured_dimensions[CSS_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, availableHeight - marginAxisColumn); - return; - } - } - - // STEP 1: CALCULATE VALUES FOR REMAINDER OF ALGORITHM - css_flex_direction_t mainAxis = resolveAxis(getFlexDirection(node), direction); - css_flex_direction_t crossAxis = getCrossFlexDirection(mainAxis, direction); - bool isMainAxisRow = isRowDirection(mainAxis); - css_justify_t justifyContent = node->style.justify_content; - bool isNodeFlexWrap = isFlexWrap(node); - - css_node_t* firstAbsoluteChild = NULL; - css_node_t* currentAbsoluteChild = NULL; - - float leadingPaddingAndBorderMain = getLeadingPaddingAndBorder(node, mainAxis); - float trailingPaddingAndBorderMain = getTrailingPaddingAndBorder(node, mainAxis); - float leadingPaddingAndBorderCross = getLeadingPaddingAndBorder(node, crossAxis); - float paddingAndBorderAxisMain = getPaddingAndBorderAxis(node, mainAxis); - float paddingAndBorderAxisCross = getPaddingAndBorderAxis(node, crossAxis); - - css_measure_mode_t measureModeMainDim = isMainAxisRow ? widthMeasureMode : heightMeasureMode; - css_measure_mode_t measureModeCrossDim = isMainAxisRow ? heightMeasureMode : widthMeasureMode; - - // STEP 2: DETERMINE AVAILABLE SIZE IN MAIN AND CROSS DIRECTIONS - float availableInnerWidth = availableWidth - marginAxisRow - paddingAndBorderAxisRow; - float availableInnerHeight = availableHeight - marginAxisColumn - paddingAndBorderAxisColumn; - float availableInnerMainDim = isMainAxisRow ? availableInnerWidth : availableInnerHeight; - float availableInnerCrossDim = isMainAxisRow ? availableInnerHeight : availableInnerWidth; - - // STEP 3: DETERMINE FLEX BASIS FOR EACH ITEM - css_node_t* child; - int i; - float childWidth; - float childHeight; - css_measure_mode_t childWidthMeasureMode; - css_measure_mode_t childHeightMeasureMode; - for (i = 0; i < childCount; i++) { - child = node->get_child(node->context, i); - - if (performLayout) { - // Set the initial position (relative to the parent). - css_direction_t childDirection = resolveDirection(child, direction); - setPosition(child, childDirection); - } - - // Absolute-positioned children don't participate in flex layout. Add them - // to a list that we can process later. - if (child->style.position_type == CSS_POSITION_ABSOLUTE) { - - // Store a private linked list of absolutely positioned children - // so that we can efficiently traverse them later. - if (firstAbsoluteChild == NULL) { - firstAbsoluteChild = child; - } - if (currentAbsoluteChild != NULL) { - currentAbsoluteChild->next_child = child; - } - currentAbsoluteChild = child; - child->next_child = NULL; - } else { - - if (isMainAxisRow && isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW)) { - - // The width is definite, so use that as the flex basis. - child->layout.flex_basis = fmaxf(child->style.dimensions[CSS_WIDTH], getPaddingAndBorderAxis(child, CSS_FLEX_DIRECTION_ROW)); - } else if (!isMainAxisRow && isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN)) { - - // The height is definite, so use that as the flex basis. - child->layout.flex_basis = fmaxf(child->style.dimensions[CSS_HEIGHT], getPaddingAndBorderAxis(child, CSS_FLEX_DIRECTION_COLUMN)); - } else if (!isFlexBasisAuto(child) && !isUndefined(availableInnerMainDim)) { - - // If the basis isn't 'auto', it is assumed to be zero. - child->layout.flex_basis = fmaxf(0, getPaddingAndBorderAxis(child, mainAxis)); - } else { - - // Compute the flex basis and hypothetical main size (i.e. the clamped flex basis). - childWidth = CSS_UNDEFINED; - childHeight = CSS_UNDEFINED; - childWidthMeasureMode = CSS_MEASURE_MODE_UNDEFINED; - childHeightMeasureMode = CSS_MEASURE_MODE_UNDEFINED; - - if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW)) { - childWidth = child->style.dimensions[CSS_WIDTH] + getMarginAxis(child, CSS_FLEX_DIRECTION_ROW); - childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } - if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN)) { - childHeight = child->style.dimensions[CSS_HEIGHT] + getMarginAxis(child, CSS_FLEX_DIRECTION_COLUMN); - childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } - - // According to the spec, if the main size is not definite and the - // child's inline axis is parallel to the main axis (i.e. it's - // horizontal), the child should be sized using "UNDEFINED" in - // the main size. Otherwise use "AT_MOST" in the cross axis. - if (!isMainAxisRow && isUndefined(childWidth) && !isUndefined(availableInnerWidth)) { - childWidth = availableInnerWidth; - childWidthMeasureMode = CSS_MEASURE_MODE_AT_MOST; - } - - // The W3C spec doesn't say anything about the 'overflow' property, - // but all major browsers appear to implement the following logic. - if (node->style.overflow == CSS_OVERFLOW_HIDDEN) { - if (isMainAxisRow && isUndefined(childHeight) && !isUndefined(availableInnerHeight)) { - childHeight = availableInnerHeight; - childHeightMeasureMode = CSS_MEASURE_MODE_AT_MOST; - } - } - - // If child has no defined size in the cross axis and is set to stretch, set the cross - // axis to be measured exactly with the available inner width - if (!isMainAxisRow && - !isUndefined(availableInnerWidth) && - !isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW) && - widthMeasureMode == CSS_MEASURE_MODE_EXACTLY && - getAlignItem(node, child) == CSS_ALIGN_STRETCH) { - childWidth = availableInnerWidth; - childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } - if (isMainAxisRow && - !isUndefined(availableInnerHeight) && - !isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN) && - heightMeasureMode == CSS_MEASURE_MODE_EXACTLY && - getAlignItem(node, child) == CSS_ALIGN_STRETCH) { - childHeight = availableInnerHeight; - childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } - - // Measure the child - layoutNodeInternal(child, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, false, "measure"); - - child->layout.flex_basis = fmaxf(isMainAxisRow ? child->layout.measured_dimensions[CSS_WIDTH] : child->layout.measured_dimensions[CSS_HEIGHT], getPaddingAndBorderAxis(child, mainAxis)); - } - } - } - - // STEP 4: COLLECT FLEX ITEMS INTO FLEX LINES - - // Indexes of children that represent the first and last items in the line. - int startOfLineIndex = 0; - int endOfLineIndex = 0; - - // Number of lines. - int lineCount = 0; - - // Accumulated cross dimensions of all lines so far. - float totalLineCrossDim = 0; - - // Max main dimension of all the lines. - float maxLineMainDim = 0; - - while (endOfLineIndex < childCount) { - - // Number of items on the currently line. May be different than the difference - // between start and end indicates because we skip over absolute-positioned items. - int itemsOnLine = 0; - - // sizeConsumedOnCurrentLine is accumulation of the dimensions and margin - // of all the children on the current line. 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 sizeConsumedOnCurrentLine = 0; - - float totalFlexGrowFactors = 0; - float totalFlexShrinkScaledFactors = 0; - - i = startOfLineIndex; - - // Maintain a linked list of the child nodes that can shrink and/or grow. - css_node_t* firstRelativeChild = NULL; - css_node_t* currentRelativeChild = NULL; - - // Add items to the current line until it's full or we run out of items. - while (i < childCount) { - child = node->get_child(node->context, i); - child->line_index = lineCount; - - if (child->style.position_type != CSS_POSITION_ABSOLUTE) { - float outerFlexBasis = child->layout.flex_basis + getMarginAxis(child, mainAxis); - - // If this is a multi-line flow and this item pushes us over the available size, we've - // hit the end of the current line. Break out of the loop and lay out the current line. - if (sizeConsumedOnCurrentLine + outerFlexBasis > availableInnerMainDim && isNodeFlexWrap && itemsOnLine > 0) { - break; - } - - sizeConsumedOnCurrentLine += outerFlexBasis; - itemsOnLine++; - - if (isFlex(child)) { - totalFlexGrowFactors += getFlexGrowFactor(child); - - // Unlike the grow factor, the shrink factor is scaled relative to the child - // dimension. - totalFlexShrinkScaledFactors += getFlexShrinkFactor(child) * child->layout.flex_basis; - } - - // Store a private linked list of children that need to be layed out. - if (firstRelativeChild == NULL) { - firstRelativeChild = child; - } - if (currentRelativeChild != NULL) { - currentRelativeChild->next_child = child; - } - currentRelativeChild = child; - child->next_child = NULL; - } - - i++; - endOfLineIndex++; - } - - // If we don't need to measure the cross axis, we can skip the entire flex step. - bool canSkipFlex = !performLayout && measureModeCrossDim == CSS_MEASURE_MODE_EXACTLY; - - // 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; - - // STEP 5: RESOLVING FLEXIBLE LENGTHS ON MAIN AXIS - // Calculate the remaining available space that needs to be allocated. - // If the main dimension size isn't known, it is computed based on - // the line length, so there's no more space left to distribute. - float remainingFreeSpace = 0; - if (!isUndefined(availableInnerMainDim)) { - remainingFreeSpace = availableInnerMainDim - sizeConsumedOnCurrentLine; - } else if (sizeConsumedOnCurrentLine < 0) { - // availableInnerMainDim is indefinite which means the node is being sized based on its content. - // sizeConsumedOnCurrentLine is negative which means the node will allocate 0 pixels for - // its content. Consequently, remainingFreeSpace is 0 - sizeConsumedOnCurrentLine. - remainingFreeSpace = -sizeConsumedOnCurrentLine; - } - - float originalRemainingFreeSpace = remainingFreeSpace; - float deltaFreeSpace = 0; - - if (!canSkipFlex) { - float childFlexBasis; - float flexShrinkScaledFactor; - float flexGrowFactor; - float baseMainSize; - float boundMainSize; - - // Do two passes over the flex items to figure out how to distribute the remaining space. - // The first pass finds the items whose min/max constraints trigger, freezes them at those - // sizes, and excludes those sizes from the remaining space. The second pass sets the size - // of each flexible item. It distributes the remaining space amongst the items whose min/max - // constraints didn't trigger in pass 1. For the other items, it sets their sizes by forcing - // their min/max constraints to trigger again. - // - // This two pass approach for resolving min/max constraints deviates from the spec. The - // spec (https://www.w3.org/TR/css-flexbox-1/#resolve-flexible-lengths) describes a process - // that needs to be repeated a variable number of times. The algorithm implemented here - // won't handle all cases but it was simpler to implement and it mitigates performance - // concerns because we know exactly how many passes it'll do. - - // First pass: detect the flex items whose min/max constraints trigger - float deltaFlexShrinkScaledFactors = 0; - float deltaFlexGrowFactors = 0; - currentRelativeChild = firstRelativeChild; - while (currentRelativeChild != NULL) { - childFlexBasis = currentRelativeChild->layout.flex_basis; - - if (remainingFreeSpace < 0) { - flexShrinkScaledFactor = getFlexShrinkFactor(currentRelativeChild) * childFlexBasis; - - // Is this child able to shrink? - if (flexShrinkScaledFactor != 0) { - baseMainSize = childFlexBasis + - remainingFreeSpace / totalFlexShrinkScaledFactors * flexShrinkScaledFactor; - boundMainSize = boundAxis(currentRelativeChild, mainAxis, baseMainSize); - if (baseMainSize != boundMainSize) { - // By excluding this item's size and flex factor from remaining, this item's - // min/max constraints should also trigger in the second pass resulting in the - // item's size calculation being identical in the first and second passes. - deltaFreeSpace -= boundMainSize - childFlexBasis; - deltaFlexShrinkScaledFactors -= flexShrinkScaledFactor; - } - } - } else if (remainingFreeSpace > 0) { - flexGrowFactor = getFlexGrowFactor(currentRelativeChild); - - // Is this child able to grow? - if (flexGrowFactor != 0) { - baseMainSize = childFlexBasis + - remainingFreeSpace / totalFlexGrowFactors * flexGrowFactor; - boundMainSize = boundAxis(currentRelativeChild, mainAxis, baseMainSize); - if (baseMainSize != boundMainSize) { - // By excluding this item's size and flex factor from remaining, this item's - // min/max constraints should also trigger in the second pass resulting in the - // item's size calculation being identical in the first and second passes. - deltaFreeSpace -= boundMainSize - childFlexBasis; - deltaFlexGrowFactors -= flexGrowFactor; - } - } - } - - currentRelativeChild = currentRelativeChild->next_child; - } - - totalFlexShrinkScaledFactors += deltaFlexShrinkScaledFactors; - totalFlexGrowFactors += deltaFlexGrowFactors; - remainingFreeSpace += deltaFreeSpace; - - // Second pass: resolve the sizes of the flexible items - deltaFreeSpace = 0; - currentRelativeChild = firstRelativeChild; - while (currentRelativeChild != NULL) { - childFlexBasis = currentRelativeChild->layout.flex_basis; - float updatedMainSize = childFlexBasis; - - if (remainingFreeSpace < 0) { - flexShrinkScaledFactor = getFlexShrinkFactor(currentRelativeChild) * childFlexBasis; - - // Is this child able to shrink? - if (flexShrinkScaledFactor != 0) { - updatedMainSize = boundAxis(currentRelativeChild, mainAxis, childFlexBasis + - remainingFreeSpace / totalFlexShrinkScaledFactors * flexShrinkScaledFactor); - } - } else if (remainingFreeSpace > 0) { - flexGrowFactor = getFlexGrowFactor(currentRelativeChild); - - // Is this child able to grow? - if (flexGrowFactor != 0) { - updatedMainSize = boundAxis(currentRelativeChild, mainAxis, childFlexBasis + - remainingFreeSpace / totalFlexGrowFactors * flexGrowFactor); - } - } - - deltaFreeSpace -= updatedMainSize - childFlexBasis; - - if (isMainAxisRow) { - childWidth = updatedMainSize + getMarginAxis(currentRelativeChild, CSS_FLEX_DIRECTION_ROW); - childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; - - if (!isUndefined(availableInnerCrossDim) && - !isStyleDimDefined(currentRelativeChild, CSS_FLEX_DIRECTION_COLUMN) && - heightMeasureMode == CSS_MEASURE_MODE_EXACTLY && - getAlignItem(node, currentRelativeChild) == CSS_ALIGN_STRETCH) { - childHeight = availableInnerCrossDim; - childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } else if (!isStyleDimDefined(currentRelativeChild, CSS_FLEX_DIRECTION_COLUMN)) { - childHeight = availableInnerCrossDim; - childHeightMeasureMode = isUndefined(childHeight) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_AT_MOST; - } else { - childHeight = currentRelativeChild->style.dimensions[CSS_HEIGHT] + getMarginAxis(currentRelativeChild, CSS_FLEX_DIRECTION_COLUMN); - childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } - } else { - childHeight = updatedMainSize + getMarginAxis(currentRelativeChild, CSS_FLEX_DIRECTION_COLUMN); - childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY; - - if (!isUndefined(availableInnerCrossDim) && - !isStyleDimDefined(currentRelativeChild, CSS_FLEX_DIRECTION_ROW) && - widthMeasureMode == CSS_MEASURE_MODE_EXACTLY && - getAlignItem(node, currentRelativeChild) == CSS_ALIGN_STRETCH) { - childWidth = availableInnerCrossDim; - childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } else if (!isStyleDimDefined(currentRelativeChild, CSS_FLEX_DIRECTION_ROW)) { - childWidth = availableInnerCrossDim; - childWidthMeasureMode = isUndefined(childWidth) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_AT_MOST; - } else { - childWidth = currentRelativeChild->style.dimensions[CSS_WIDTH] + getMarginAxis(currentRelativeChild, CSS_FLEX_DIRECTION_ROW); - childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } - } - - bool requiresStretchLayout = !isStyleDimDefined(currentRelativeChild, crossAxis) && - getAlignItem(node, currentRelativeChild) == CSS_ALIGN_STRETCH; - - // Recursively call the layout algorithm for this child with the updated main size. - layoutNodeInternal(currentRelativeChild, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, performLayout && !requiresStretchLayout, "flex"); - - currentRelativeChild = currentRelativeChild->next_child; - } - } - - remainingFreeSpace = originalRemainingFreeSpace + deltaFreeSpace; - - // STEP 6: MAIN-AXIS JUSTIFICATION & CROSS-AXIS SIZE DETERMINATION - - // At this point, all the children have their dimensions set in the main axis. - // Their dimensions are also set in the cross axis with the exception of items - // that are aligned "stretch". We need to compute these stretch values and - // set the final positions. - - // If we are using "at most" rules in the main axis, we won't distribute - // any remaining space at this point. - if (measureModeMainDim == CSS_MEASURE_MODE_AT_MOST) { - remainingFreeSpace = 0; - } - - // Use justifyContent to figure out how to allocate the remaining space - // available in the main axis. - if (justifyContent != CSS_JUSTIFY_FLEX_START) { - if (justifyContent == CSS_JUSTIFY_CENTER) { - leadingMainDim = remainingFreeSpace / 2; - } else if (justifyContent == CSS_JUSTIFY_FLEX_END) { - leadingMainDim = remainingFreeSpace; - } else if (justifyContent == CSS_JUSTIFY_SPACE_BETWEEN) { - remainingFreeSpace = fmaxf(remainingFreeSpace, 0); - if (itemsOnLine > 1) { - betweenMainDim = remainingFreeSpace / (itemsOnLine - 1); - } else { - betweenMainDim = 0; - } - } else if (justifyContent == CSS_JUSTIFY_SPACE_AROUND) { - // Space on the edges is half of the space between elements - betweenMainDim = remainingFreeSpace / itemsOnLine; - leadingMainDim = betweenMainDim / 2; - } - } - - float mainDim = leadingPaddingAndBorderMain + leadingMainDim; - float crossDim = 0; - - for (i = startOfLineIndex; i < endOfLineIndex; ++i) { - child = node->get_child(node->context, i); - - if (child->style.position_type == CSS_POSITION_ABSOLUTE && - isPosDefined(child, leading[mainAxis])) { - if (performLayout) { - // 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). - child->layout.position[pos[mainAxis]] = getPosition(child, leading[mainAxis]) + - getLeadingBorder(node, mainAxis) + - getLeadingMargin(child, mainAxis); - } - } else { - if (performLayout) { - // If the child is position absolute (without top/left) or relative, - // we put it at the current accumulated offset. - child->layout.position[pos[mainAxis]] += mainDim; - } - - // Now that we placed the element, we need to update the variables. - // We need to do that only for relative elements. Absolute elements - // do not take part in that phase. - if (child->style.position_type == CSS_POSITION_RELATIVE) { - if (canSkipFlex) { - // If we skipped the flex step, then we can't rely on the measuredDims because - // they weren't computed. This means we can't call getDimWithMargin. - mainDim += betweenMainDim + getMarginAxis(child, mainAxis) + child->layout.flex_basis; - crossDim = availableInnerCrossDim; - } else { - // The main dimension is the sum of all the elements dimension plus - // the spacing. - 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 = fmaxf(crossDim, getDimWithMargin(child, crossAxis)); - } - } - } - } - - mainDim += trailingPaddingAndBorderMain; - - float containerCrossAxis = availableInnerCrossDim; - if (measureModeCrossDim == CSS_MEASURE_MODE_UNDEFINED || measureModeCrossDim == CSS_MEASURE_MODE_AT_MOST) { - // Compute the cross axis from the max cross dimension of the children. - containerCrossAxis = boundAxis(node, crossAxis, crossDim + paddingAndBorderAxisCross) - paddingAndBorderAxisCross; - - if (measureModeCrossDim == CSS_MEASURE_MODE_AT_MOST) { - containerCrossAxis = fminf(containerCrossAxis, availableInnerCrossDim); - } - } - - // If there's no flex wrap, the cross dimension is defined by the container. - if (!isNodeFlexWrap && measureModeCrossDim == CSS_MEASURE_MODE_EXACTLY) { - crossDim = availableInnerCrossDim; - } - - // Clamp to the min/max size specified on the container. - crossDim = boundAxis(node, crossAxis, crossDim + paddingAndBorderAxisCross) - paddingAndBorderAxisCross; - - // STEP 7: CROSS-AXIS ALIGNMENT - // We can skip child alignment if we're just measuring the container. - if (performLayout) { - for (i = startOfLineIndex; i < endOfLineIndex; ++i) { - child = node->get_child(node->context, i); - - if (child->style.position_type == CSS_POSITION_ABSOLUTE) { - // If the child is absolutely positioned and has a top/left/bottom/right - // set, override all the previously computed positions to set it correctly. - if (isPosDefined(child, leading[crossAxis])) { - child->layout.position[pos[crossAxis]] = getPosition(child, leading[crossAxis]) + - getLeadingBorder(node, crossAxis) + - getLeadingMargin(child, crossAxis); - } else { - child->layout.position[pos[crossAxis]] = leadingPaddingAndBorderCross + - getLeadingMargin(child, crossAxis); - } - } else { - float leadingCrossDim = leadingPaddingAndBorderCross; - - // For a relative children, we're either using alignItems (parent) or - // alignSelf (child) in order to determine the position in the cross axis - css_align_t alignItem = getAlignItem(node, child); - - // If the child uses align stretch, we need to lay it out one more time, this time - // forcing the cross-axis size to be the computed cross size for the current line. - if (alignItem == CSS_ALIGN_STRETCH) { - childWidth = child->layout.measured_dimensions[CSS_WIDTH] + getMarginAxis(child, CSS_FLEX_DIRECTION_ROW); - childHeight = child->layout.measured_dimensions[CSS_HEIGHT] + getMarginAxis(child, CSS_FLEX_DIRECTION_COLUMN); - bool isCrossSizeDefinite = false; - - if (isMainAxisRow) { - isCrossSizeDefinite = isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN); - childHeight = crossDim; - } else { - isCrossSizeDefinite = isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW); - childWidth = crossDim; - } - - // If the child defines a definite size for its cross axis, there's no need to stretch. - if (!isCrossSizeDefinite) { - childWidthMeasureMode = isUndefined(childWidth) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_EXACTLY; - childHeightMeasureMode = isUndefined(childHeight) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_EXACTLY; - layoutNodeInternal(child, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, true, "stretch"); - } - } else if (alignItem != CSS_ALIGN_FLEX_START) { - float remainingCrossDim = containerCrossAxis - getDimWithMargin(child, crossAxis); - - if (alignItem == CSS_ALIGN_CENTER) { - leadingCrossDim += remainingCrossDim / 2; - } else { // CSS_ALIGN_FLEX_END - leadingCrossDim += remainingCrossDim; - } - } - - // And we apply the position - child->layout.position[pos[crossAxis]] += totalLineCrossDim + leadingCrossDim; - } - } - } - - totalLineCrossDim += crossDim; - maxLineMainDim = fmaxf(maxLineMainDim, mainDim); - - // Reset variables for new line. - lineCount++; - startOfLineIndex = endOfLineIndex; - endOfLineIndex = startOfLineIndex; - } - - // STEP 8: MULTI-LINE CONTENT ALIGNMENT - if (lineCount > 1 && performLayout && !isUndefined(availableInnerCrossDim)) { - float remainingAlignContentDim = availableInnerCrossDim - totalLineCrossDim; - - float crossDimLead = 0; - float currentLead = leadingPaddingAndBorderCross; - - css_align_t alignContent = node->style.align_content; - if (alignContent == CSS_ALIGN_FLEX_END) { - currentLead += remainingAlignContentDim; - } else if (alignContent == CSS_ALIGN_CENTER) { - currentLead += remainingAlignContentDim / 2; - } else if (alignContent == CSS_ALIGN_STRETCH) { - if (availableInnerCrossDim > totalLineCrossDim) { - crossDimLead = (remainingAlignContentDim / lineCount); - } - } - - int endIndex = 0; - for (i = 0; i < lineCount; ++i) { - int startIndex = endIndex; - int j; - - // compute the line's height and find the endIndex - float lineHeight = 0; - for (j = startIndex; j < childCount; ++j) { - child = node->get_child(node->context, j); - if (child->style.position_type != CSS_POSITION_RELATIVE) { - continue; - } - if (child->line_index != i) { - break; - } - if (isLayoutDimDefined(child, crossAxis)) { - lineHeight = fmaxf(lineHeight, - child->layout.measured_dimensions[dim[crossAxis]] + getMarginAxis(child, crossAxis)); - } - } - endIndex = j; - lineHeight += crossDimLead; - - if (performLayout) { - for (j = startIndex; j < endIndex; ++j) { - child = node->get_child(node->context, j); - if (child->style.position_type != CSS_POSITION_RELATIVE) { - continue; - } - - css_align_t alignContentAlignItem = getAlignItem(node, child); - if (alignContentAlignItem == CSS_ALIGN_FLEX_START) { - child->layout.position[pos[crossAxis]] = currentLead + getLeadingMargin(child, crossAxis); - } else if (alignContentAlignItem == CSS_ALIGN_FLEX_END) { - child->layout.position[pos[crossAxis]] = currentLead + lineHeight - getTrailingMargin(child, crossAxis) - child->layout.measured_dimensions[dim[crossAxis]]; - } else if (alignContentAlignItem == CSS_ALIGN_CENTER) { - childHeight = child->layout.measured_dimensions[dim[crossAxis]]; - child->layout.position[pos[crossAxis]] = currentLead + (lineHeight - childHeight) / 2; - } else if (alignContentAlignItem == CSS_ALIGN_STRETCH) { - child->layout.position[pos[crossAxis]] = currentLead + getLeadingMargin(child, crossAxis); - // TODO(prenaux): Correctly set the height of items with indefinite - // (auto) crossAxis dimension. - } - } - } - - currentLead += lineHeight; - } - } - - // STEP 9: COMPUTING FINAL DIMENSIONS - node->layout.measured_dimensions[CSS_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, availableWidth - marginAxisRow); - node->layout.measured_dimensions[CSS_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, availableHeight - marginAxisColumn); - - // If the user didn't specify a width or height for the node, set the - // dimensions based on the children. - if (measureModeMainDim == CSS_MEASURE_MODE_UNDEFINED) { - // Clamp the size to the min/max size, if specified, and make sure it - // doesn't go below the padding and border amount. - node->layout.measured_dimensions[dim[mainAxis]] = boundAxis(node, mainAxis, maxLineMainDim); - } else if (measureModeMainDim == CSS_MEASURE_MODE_AT_MOST) { - node->layout.measured_dimensions[dim[mainAxis]] = fmaxf( - fminf(availableInnerMainDim + paddingAndBorderAxisMain, - boundAxisWithinMinAndMax(node, mainAxis, maxLineMainDim)), - paddingAndBorderAxisMain); - } - - if (measureModeCrossDim == CSS_MEASURE_MODE_UNDEFINED) { - // Clamp the size to the min/max size, if specified, and make sure it - // doesn't go below the padding and border amount. - node->layout.measured_dimensions[dim[crossAxis]] = boundAxis(node, crossAxis, totalLineCrossDim + paddingAndBorderAxisCross); - } else if (measureModeCrossDim == CSS_MEASURE_MODE_AT_MOST) { - node->layout.measured_dimensions[dim[crossAxis]] = fmaxf( - fminf(availableInnerCrossDim + paddingAndBorderAxisCross, - boundAxisWithinMinAndMax(node, crossAxis, totalLineCrossDim + paddingAndBorderAxisCross)), - paddingAndBorderAxisCross); - } - - // STEP 10: SETTING TRAILING POSITIONS FOR CHILDREN - if (performLayout) { - bool needsMainTrailingPos = false; - bool needsCrossTrailingPos = false; - - if (mainAxis == CSS_FLEX_DIRECTION_ROW_REVERSE || - mainAxis == CSS_FLEX_DIRECTION_COLUMN_REVERSE) { - needsMainTrailingPos = true; - } - - if (crossAxis == CSS_FLEX_DIRECTION_ROW_REVERSE || - crossAxis == CSS_FLEX_DIRECTION_COLUMN_REVERSE) { - needsCrossTrailingPos = true; - } - - // Set trailing position if necessary. - if (needsMainTrailingPos || needsCrossTrailingPos) { - for (i = 0; i < childCount; ++i) { - child = node->get_child(node->context, i); - - if (needsMainTrailingPos) { - setTrailingPosition(node, child, mainAxis); - } - - if (needsCrossTrailingPos) { - setTrailingPosition(node, child, crossAxis); - } - } - } - } - - // STEP 11: SIZING AND POSITIONING ABSOLUTE CHILDREN - currentAbsoluteChild = firstAbsoluteChild; - while (currentAbsoluteChild != NULL) { - // Now that we know the bounds of the container, perform layout again on the - // absolutely-positioned children. - if (performLayout) { - - childWidth = CSS_UNDEFINED; - childHeight = CSS_UNDEFINED; - - if (isStyleDimDefined(currentAbsoluteChild, CSS_FLEX_DIRECTION_ROW)) { - childWidth = currentAbsoluteChild->style.dimensions[CSS_WIDTH] + getMarginAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_ROW); - } else { - // If the child doesn't have a specified width, compute the width based on the left/right offsets if they're defined. - if (isPosDefined(currentAbsoluteChild, CSS_LEFT) && isPosDefined(currentAbsoluteChild, CSS_RIGHT)) { - childWidth = node->layout.measured_dimensions[CSS_WIDTH] - - (getLeadingBorder(node, CSS_FLEX_DIRECTION_ROW) + getTrailingBorder(node, CSS_FLEX_DIRECTION_ROW)) - - (currentAbsoluteChild->style.position[CSS_LEFT] + currentAbsoluteChild->style.position[CSS_RIGHT]); - childWidth = boundAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_ROW, childWidth); - } - } - - if (isStyleDimDefined(currentAbsoluteChild, CSS_FLEX_DIRECTION_COLUMN)) { - childHeight = currentAbsoluteChild->style.dimensions[CSS_HEIGHT] + getMarginAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_COLUMN); - } else { - // If the child doesn't have a specified height, compute the height based on the top/bottom offsets if they're defined. - if (isPosDefined(currentAbsoluteChild, CSS_TOP) && isPosDefined(currentAbsoluteChild, CSS_BOTTOM)) { - childHeight = node->layout.measured_dimensions[CSS_HEIGHT] - - (getLeadingBorder(node, CSS_FLEX_DIRECTION_COLUMN) + getTrailingBorder(node, CSS_FLEX_DIRECTION_COLUMN)) - - (currentAbsoluteChild->style.position[CSS_TOP] + currentAbsoluteChild->style.position[CSS_BOTTOM]); - childHeight = boundAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_COLUMN, childHeight); - } - } - - // If we're still missing one or the other dimension, measure the content. - if (isUndefined(childWidth) || isUndefined(childHeight)) { - childWidthMeasureMode = isUndefined(childWidth) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_EXACTLY; - childHeightMeasureMode = isUndefined(childHeight) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_EXACTLY; - - // According to the spec, if the main size is not definite and the - // child's inline axis is parallel to the main axis (i.e. it's - // horizontal), the child should be sized using "UNDEFINED" in - // the main size. Otherwise use "AT_MOST" in the cross axis. - if (!isMainAxisRow && isUndefined(childWidth) && !isUndefined(availableInnerWidth)) { - childWidth = availableInnerWidth; - childWidthMeasureMode = CSS_MEASURE_MODE_AT_MOST; - } - - // The W3C spec doesn't say anything about the 'overflow' property, - // but all major browsers appear to implement the following logic. - if (node->style.overflow == CSS_OVERFLOW_HIDDEN) { - if (isMainAxisRow && isUndefined(childHeight) && !isUndefined(availableInnerHeight)) { - childHeight = availableInnerHeight; - childHeightMeasureMode = CSS_MEASURE_MODE_AT_MOST; - } - } - - layoutNodeInternal(currentAbsoluteChild, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, false, "abs-measure"); - childWidth = currentAbsoluteChild->layout.measured_dimensions[CSS_WIDTH] + getMarginAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_ROW); - childHeight = currentAbsoluteChild->layout.measured_dimensions[CSS_HEIGHT] + getMarginAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_COLUMN); - } - - layoutNodeInternal(currentAbsoluteChild, childWidth, childHeight, direction, CSS_MEASURE_MODE_EXACTLY, CSS_MEASURE_MODE_EXACTLY, true, "abs-layout"); - - if (isPosDefined(currentAbsoluteChild, trailing[CSS_FLEX_DIRECTION_ROW]) && - !isPosDefined(currentAbsoluteChild, leading[CSS_FLEX_DIRECTION_ROW])) { - currentAbsoluteChild->layout.position[leading[CSS_FLEX_DIRECTION_ROW]] = - node->layout.measured_dimensions[dim[CSS_FLEX_DIRECTION_ROW]] - - currentAbsoluteChild->layout.measured_dimensions[dim[CSS_FLEX_DIRECTION_ROW]] - - getPosition(currentAbsoluteChild, trailing[CSS_FLEX_DIRECTION_ROW]); - } - - if (isPosDefined(currentAbsoluteChild, trailing[CSS_FLEX_DIRECTION_COLUMN]) && - !isPosDefined(currentAbsoluteChild, leading[CSS_FLEX_DIRECTION_COLUMN])) { - currentAbsoluteChild->layout.position[leading[CSS_FLEX_DIRECTION_COLUMN]] = - node->layout.measured_dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] - - currentAbsoluteChild->layout.measured_dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] - - getPosition(currentAbsoluteChild, trailing[CSS_FLEX_DIRECTION_COLUMN]); - } - } - - currentAbsoluteChild = currentAbsoluteChild->next_child; - } - /** END_GENERATED **/ -} - -int gDepth = 0; -bool gPrintTree = false; -bool gPrintChanges = false; -bool gPrintSkips = false; - -static const char* spacer = " "; - -static const char* getSpacer(unsigned long level) { - unsigned long spacerLen = strlen(spacer); - if (level > spacerLen) { - level = spacerLen; - } - return &spacer[spacerLen - level]; -} - -static const char* getModeName(css_measure_mode_t mode, bool performLayout) { - const char* kMeasureModeNames[CSS_MEASURE_MODE_COUNT] = { - "UNDEFINED", - "EXACTLY", - "AT_MOST" - }; - const char* kLayoutModeNames[CSS_MEASURE_MODE_COUNT] = { - "LAY_UNDEFINED", - "LAY_EXACTLY", - "LAY_AT_MOST" - }; - - if (mode >= CSS_MEASURE_MODE_COUNT) { - return ""; - } - - return performLayout? kLayoutModeNames[mode] : kMeasureModeNames[mode]; -} - -static bool canUseCachedMeasurement( - bool is_text_node, - float available_width, - float available_height, - float margin_row, - float margin_column, - css_measure_mode_t width_measure_mode, - css_measure_mode_t height_measure_mode, - css_cached_measurement_t cached_layout) { - - bool is_height_same = - (cached_layout.height_measure_mode == CSS_MEASURE_MODE_UNDEFINED && height_measure_mode == CSS_MEASURE_MODE_UNDEFINED) || - (cached_layout.height_measure_mode == height_measure_mode && eq(cached_layout.available_height, available_height)); - - bool is_width_same = - (cached_layout.width_measure_mode == CSS_MEASURE_MODE_UNDEFINED && width_measure_mode == CSS_MEASURE_MODE_UNDEFINED) || - (cached_layout.width_measure_mode == width_measure_mode && eq(cached_layout.available_width, available_width)); - - if (is_height_same && is_width_same) { - return true; - } - - bool is_height_valid = - (cached_layout.height_measure_mode == CSS_MEASURE_MODE_UNDEFINED && height_measure_mode == CSS_MEASURE_MODE_AT_MOST && cached_layout.computed_height <= (available_height - margin_column)) || - (height_measure_mode == CSS_MEASURE_MODE_EXACTLY && eq(cached_layout.computed_height, available_height - margin_column)); - - if (is_width_same && is_height_valid) { - return true; - } - - bool is_width_valid = - (cached_layout.width_measure_mode == CSS_MEASURE_MODE_UNDEFINED && width_measure_mode == CSS_MEASURE_MODE_AT_MOST && cached_layout.computed_width <= (available_width - margin_row)) || - (width_measure_mode == CSS_MEASURE_MODE_EXACTLY && eq(cached_layout.computed_width, available_width - margin_row)); - - if (is_height_same && is_width_valid) { - return true; - } - - if (is_height_valid && is_width_valid) { - return true; - } - - // We know this to be text so we can apply some more specialized heuristics. - if (is_text_node) { - if (is_width_same) { - if (height_measure_mode == CSS_MEASURE_MODE_UNDEFINED) { - // Width is the same and height is not restricted. Re-use cahced value. - return true; - } - - if (height_measure_mode == CSS_MEASURE_MODE_AT_MOST && - cached_layout.computed_height < (available_height - margin_column)) { - // Width is the same and height restriction is greater than the cached height. Re-use cached value. - return true; - } - - // Width is the same but height restriction imposes smaller height than previously measured. - // Update the cached value to respect the new height restriction. - cached_layout.computed_height = available_height - margin_column; - return true; - } - - if (cached_layout.width_measure_mode == CSS_MEASURE_MODE_UNDEFINED) { - if (width_measure_mode == CSS_MEASURE_MODE_UNDEFINED || - (width_measure_mode == CSS_MEASURE_MODE_AT_MOST && - cached_layout.computed_width <= (available_width - margin_row))) { - // Previsouly this text was measured with no width restriction, if width is now restricted - // but to a larger value than the previsouly measured width we can re-use the measurement - // as we know it will fit. - return true; - } - } - } - - return false; -} - -// -// This is a wrapper around the layoutNodeImpl function. It determines -// whether the layout request is redundant and can be skipped. -// -// Parameters: -// Input parameters are the same as layoutNodeImpl (see above) -// Return parameter is true if layout was performed, false if skipped -// -bool layoutNodeInternal(css_node_t* node, float availableWidth, float availableHeight, - css_direction_t parentDirection, css_measure_mode_t widthMeasureMode, css_measure_mode_t heightMeasureMode, bool performLayout, char* reason) { - css_layout_t* layout = &node->layout; - - gDepth++; - - bool needToVisitNode = (node->is_dirty(node->context) && layout->generation_count != gCurrentGenerationCount) || - layout->last_parent_direction != parentDirection; - - if (needToVisitNode) { - // Invalidate the cached results. - layout->next_cached_measurements_index = 0; - layout->cached_layout.width_measure_mode = (css_measure_mode_t)-1; - layout->cached_layout.height_measure_mode = (css_measure_mode_t)-1; - } - - css_cached_measurement_t* cachedResults = NULL; - - // Determine whether the results are already cached. We maintain a separate - // cache for layouts and measurements. A layout operation modifies the positions - // and dimensions for nodes in the subtree. The algorithm assumes that each node - // gets layed out a maximum of one time per tree layout, but multiple measurements - // may be required to resolve all of the flex dimensions. - // We handle nodes with measure functions specially here because they are the most - // expensive to measure, so it's worth avoiding redundant measurements if at all possible. - if (isMeasureDefined(node)) { - float marginAxisRow = getMarginAxis(node, CSS_FLEX_DIRECTION_ROW); - float marginAxisColumn = getMarginAxis(node, CSS_FLEX_DIRECTION_COLUMN); - - // First, try to use the layout cache. - if (canUseCachedMeasurement(node->is_text_node && node->is_text_node(node->context), availableWidth, availableHeight, marginAxisRow, marginAxisColumn, - widthMeasureMode, heightMeasureMode, layout->cached_layout)) { - cachedResults = &layout->cached_layout; - } else { - // Try to use the measurement cache. - for (int i = 0; i < layout->next_cached_measurements_index; i++) { - if (canUseCachedMeasurement(node->is_text_node && node->is_text_node(node->context), availableWidth, availableHeight, marginAxisRow, marginAxisColumn, - widthMeasureMode, heightMeasureMode, layout->cached_measurements[i])) { - cachedResults = &layout->cached_measurements[i]; - break; - } - } - } - } else if (performLayout) { - if (eq(layout->cached_layout.available_width, availableWidth) && - eq(layout->cached_layout.available_height, availableHeight) && - layout->cached_layout.width_measure_mode == widthMeasureMode && - layout->cached_layout.height_measure_mode == heightMeasureMode) { - - cachedResults = &layout->cached_layout; - } - } else { - for (int i = 0; i < layout->next_cached_measurements_index; i++) { - if (eq(layout->cached_measurements[i].available_width, availableWidth) && - eq(layout->cached_measurements[i].available_height, availableHeight) && - layout->cached_measurements[i].width_measure_mode == widthMeasureMode && - layout->cached_measurements[i].height_measure_mode == heightMeasureMode) { - - cachedResults = &layout->cached_measurements[i]; - break; - } - } - } - - if (!needToVisitNode && cachedResults != NULL) { - layout->measured_dimensions[CSS_WIDTH] = cachedResults->computed_width; - layout->measured_dimensions[CSS_HEIGHT] = cachedResults->computed_height; - - if (gPrintChanges && gPrintSkips) { - printf("%s%d.{[skipped] ", getSpacer(gDepth), gDepth); - if (node->print) { - node->print(node->context); - } - printf("wm: %s, hm: %s, aw: %f ah: %f => d: (%f, %f) %s\n", - getModeName(widthMeasureMode, performLayout), - getModeName(heightMeasureMode, performLayout), - availableWidth, availableHeight, - cachedResults->computed_width, cachedResults->computed_height, reason); - } - } else { - - if (gPrintChanges) { - printf("%s%d.{%s", getSpacer(gDepth), gDepth, needToVisitNode ? "*" : ""); - if (node->print) { - node->print(node->context); - } - printf("wm: %s, hm: %s, aw: %f ah: %f %s\n", - getModeName(widthMeasureMode, performLayout), - getModeName(heightMeasureMode, performLayout), - availableWidth, availableHeight, reason); - } - - layoutNodeImpl(node, availableWidth, availableHeight, parentDirection, widthMeasureMode, heightMeasureMode, performLayout); - - if (gPrintChanges) { - printf("%s%d.}%s", getSpacer(gDepth), gDepth, needToVisitNode ? "*" : ""); - if (node->print) { - node->print(node->context); - } - printf("wm: %s, hm: %s, d: (%f, %f) %s\n", - getModeName(widthMeasureMode, performLayout), - getModeName(heightMeasureMode, performLayout), - layout->measured_dimensions[CSS_WIDTH], layout->measured_dimensions[CSS_HEIGHT], reason); - } - - layout->last_parent_direction = parentDirection; - - if (cachedResults == NULL) { - if (layout->next_cached_measurements_index == CSS_MAX_CACHED_RESULT_COUNT) { - if (gPrintChanges) { - printf("Out of cache entries!\n"); - } - layout->next_cached_measurements_index = 0; - } - - css_cached_measurement_t* newCacheEntry; - if (performLayout) { - // Use the single layout cache entry. - newCacheEntry = &layout->cached_layout; - } else { - // Allocate a new measurement cache entry. - newCacheEntry = &layout->cached_measurements[layout->next_cached_measurements_index]; - layout->next_cached_measurements_index++; - } - - newCacheEntry->available_width = availableWidth; - newCacheEntry->available_height = availableHeight; - newCacheEntry->width_measure_mode = widthMeasureMode; - newCacheEntry->height_measure_mode = heightMeasureMode; - newCacheEntry->computed_width = layout->measured_dimensions[CSS_WIDTH]; - newCacheEntry->computed_height = layout->measured_dimensions[CSS_HEIGHT]; - } - } - - if (performLayout) { - node->layout.dimensions[CSS_WIDTH] = node->layout.measured_dimensions[CSS_WIDTH]; - node->layout.dimensions[CSS_HEIGHT] = node->layout.measured_dimensions[CSS_HEIGHT]; - layout->should_update = true; - } - - gDepth--; - layout->generation_count = gCurrentGenerationCount; - return (needToVisitNode || cachedResults == NULL); -} - -void layoutNode(css_node_t* node, float availableWidth, float availableHeight, css_direction_t parentDirection) { - // Increment the generation count. This will force the recursive routine to visit - // all dirty nodes at least once. Subsequent visits will be skipped if the input - // parameters don't change. - gCurrentGenerationCount++; - - css_measure_mode_t widthMeasureMode = CSS_MEASURE_MODE_UNDEFINED; - css_measure_mode_t heightMeasureMode = CSS_MEASURE_MODE_UNDEFINED; - - if (!isUndefined(availableWidth)) { - widthMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } else if (isStyleDimDefined(node, CSS_FLEX_DIRECTION_ROW)) { - availableWidth = node->style.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] + getMarginAxis(node, CSS_FLEX_DIRECTION_ROW); - widthMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } else if (node->style.maxDimensions[CSS_WIDTH] >= 0.0) { - availableWidth = node->style.maxDimensions[CSS_WIDTH]; - widthMeasureMode = CSS_MEASURE_MODE_AT_MOST; - } - - if (!isUndefined(availableHeight)) { - heightMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } else if (isStyleDimDefined(node, CSS_FLEX_DIRECTION_COLUMN)) { - availableHeight = node->style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] + getMarginAxis(node, CSS_FLEX_DIRECTION_COLUMN); - heightMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } else if (node->style.maxDimensions[CSS_HEIGHT] >= 0.0) { - availableHeight = node->style.maxDimensions[CSS_HEIGHT]; - heightMeasureMode = CSS_MEASURE_MODE_AT_MOST; - } - - if (layoutNodeInternal(node, availableWidth, availableHeight, parentDirection, widthMeasureMode, heightMeasureMode, true, "initial")) { - - setPosition(node, node->layout.direction); - - if (gPrintTree) { - print_css_node(node, CSS_PRINT_LAYOUT | CSS_PRINT_CHILDREN | CSS_PRINT_STYLE); - } - } -} diff --git a/java/Layout.h b/java/Layout.h deleted file mode 100644 index bbfda26f..00000000 --- a/java/Layout.h +++ /dev/null @@ -1,200 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -#ifndef __LAYOUT_H -#define __LAYOUT_H - -#include -#ifndef __cplusplus -#include -#endif - -// Not defined in MSVC++ -#ifndef NAN -static const unsigned long __nan[2] = {0xffffffff, 0x7fffffff}; -#define NAN (*(const float *)__nan) -#endif - -#define CSS_UNDEFINED NAN - -typedef enum { - CSS_DIRECTION_INHERIT = 0, - CSS_DIRECTION_LTR, - CSS_DIRECTION_RTL -} css_direction_t; - -typedef enum { - CSS_FLEX_DIRECTION_COLUMN = 0, - CSS_FLEX_DIRECTION_COLUMN_REVERSE, - CSS_FLEX_DIRECTION_ROW, - CSS_FLEX_DIRECTION_ROW_REVERSE -} css_flex_direction_t; - -typedef enum { - CSS_JUSTIFY_FLEX_START = 0, - CSS_JUSTIFY_CENTER, - CSS_JUSTIFY_FLEX_END, - CSS_JUSTIFY_SPACE_BETWEEN, - CSS_JUSTIFY_SPACE_AROUND -} css_justify_t; - -typedef enum { - CSS_OVERFLOW_VISIBLE = 0, - CSS_OVERFLOW_HIDDEN -} css_overflow_t; - -// Note: auto is only a valid value for alignSelf. It is NOT a valid value for -// alignItems. -typedef enum { - CSS_ALIGN_AUTO = 0, - CSS_ALIGN_FLEX_START, - CSS_ALIGN_CENTER, - CSS_ALIGN_FLEX_END, - CSS_ALIGN_STRETCH -} css_align_t; - -typedef enum { - CSS_POSITION_RELATIVE = 0, - CSS_POSITION_ABSOLUTE -} css_position_type_t; - -typedef enum { - CSS_NOWRAP = 0, - CSS_WRAP -} css_wrap_type_t; - -// Note: left and top are shared between position[2] and position[4], so -// they have to be before right and bottom. -typedef enum { - CSS_LEFT = 0, - CSS_TOP, - CSS_RIGHT, - CSS_BOTTOM, - CSS_START, - CSS_END, - CSS_POSITION_COUNT -} css_position_t; - -typedef enum { - CSS_MEASURE_MODE_UNDEFINED = 0, - CSS_MEASURE_MODE_EXACTLY, - CSS_MEASURE_MODE_AT_MOST, - CSS_MEASURE_MODE_COUNT -} css_measure_mode_t; - -typedef enum { - CSS_WIDTH = 0, - CSS_HEIGHT -} css_dimension_t; - -typedef struct { - float available_width; - float available_height; - css_measure_mode_t width_measure_mode; - css_measure_mode_t height_measure_mode; - - float computed_width; - float computed_height; -} css_cached_measurement_t; - -enum { - // This value was chosen based on empiracle data. Even the most complicated - // layouts should not require more than 16 entries to fit within the cache. - CSS_MAX_CACHED_RESULT_COUNT = 16 -}; - -typedef struct { - float position[4]; - float dimensions[2]; - css_direction_t direction; - - float flex_basis; - - // Instead of recomputing the entire layout every single time, we - // cache some information to break early when nothing changed - bool should_update; - int generation_count; - css_direction_t last_parent_direction; - - int next_cached_measurements_index; - css_cached_measurement_t cached_measurements[CSS_MAX_CACHED_RESULT_COUNT]; - float measured_dimensions[2]; - - css_cached_measurement_t cached_layout; -} css_layout_t; - -typedef struct { - float dimensions[2]; -} css_dim_t; - -typedef struct { - css_direction_t direction; - css_flex_direction_t flex_direction; - css_justify_t justify_content; - css_align_t align_content; - css_align_t align_items; - css_align_t align_self; - css_position_type_t position_type; - css_wrap_type_t flex_wrap; - css_overflow_t overflow; - float flex; - float margin[6]; - float position[4]; - /** - * You should skip all the rules that contain negative values for the - * following attributes. For example: - * {padding: 10, paddingLeft: -5} - * should output: - * {left: 10 ...} - * the following two are incorrect: - * {left: -5 ...} - * {left: 0 ...} - */ - float padding[6]; - float border[6]; - float dimensions[2]; - float minDimensions[2]; - float maxDimensions[2]; -} css_style_t; - -typedef struct css_node css_node_t; -struct css_node { - css_style_t style; - css_layout_t layout; - int children_count; - int line_index; - - css_node_t* next_child; - - css_dim_t (*measure)(void *context, float width, css_measure_mode_t widthMode, float height, css_measure_mode_t heightMode); - void (*print)(void *context); - struct css_node* (*get_child)(void *context, int i); - bool (*is_dirty)(void *context); - bool (*is_text_node)(void *context); - void *context; -}; - -// Lifecycle of nodes and children -css_node_t *new_css_node(void); -void init_css_node(css_node_t *node); -void free_css_node(css_node_t *node); - -// Print utilities -typedef enum { - CSS_PRINT_LAYOUT = 1, - CSS_PRINT_STYLE = 2, - CSS_PRINT_CHILDREN = 4, -} css_print_options_t; -void print_css_node(css_node_t *node, css_print_options_t options); - -// Function that computes the layout! -void layoutNode(css_node_t *node, float availableWidth, float availableHeight, css_direction_t parentDirection); -bool isUndefined(float value); - -#endif diff --git a/java/Layout.js b/java/Layout.js deleted file mode 100755 index ea4d4b20..00000000 --- a/java/Layout.js +++ /dev/null @@ -1,1708 +0,0 @@ - /** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -var computeLayout = (function() { - - var POSITIVE_FLEX_IS_AUTO = false; - - var gCurrentGenerationCount = 0; - - var CSS_UNDEFINED; - - var CSS_LEFT = 'left'; - var CSS_TOP = 'top'; - var CSS_RIGHT = 'right'; - var CSS_BOTTOM = 'bottom'; - - var CSS_DIRECTION_INHERIT = 'inherit'; - var CSS_DIRECTION_LTR = 'ltr'; - var CSS_DIRECTION_RTL = 'rtl'; - - var CSS_FLEX_DIRECTION_ROW = 'row'; - var CSS_FLEX_DIRECTION_ROW_REVERSE = 'row-reverse'; - var CSS_FLEX_DIRECTION_COLUMN = 'column'; - var CSS_FLEX_DIRECTION_COLUMN_REVERSE = 'column-reverse'; - - var CSS_JUSTIFY_FLEX_START = 'flex-start'; - var CSS_JUSTIFY_CENTER = 'center'; - var CSS_JUSTIFY_FLEX_END = 'flex-end'; - var CSS_JUSTIFY_SPACE_BETWEEN = 'space-between'; - var CSS_JUSTIFY_SPACE_AROUND = 'space-around'; - - var CSS_ALIGN_FLEX_START = 'flex-start'; - var CSS_ALIGN_CENTER = 'center'; - var CSS_ALIGN_FLEX_END = 'flex-end'; - var CSS_ALIGN_STRETCH = 'stretch'; - - var CSS_POSITION_RELATIVE = 'relative'; - var CSS_POSITION_ABSOLUTE = 'absolute'; - - var CSS_OVERFLOW_VISIBLE = 'visible'; - var CSS_OVERFLOW_HIDDEN = 'hidden'; - - var CSS_MEASURE_MODE_UNDEFINED = 'undefined'; - var CSS_MEASURE_MODE_EXACTLY = 'exactly'; - var CSS_MEASURE_MODE_AT_MOST = 'at-most'; - - var leading = { - 'row': 'left', - 'row-reverse': 'right', - 'column': 'top', - 'column-reverse': 'bottom' - }; - var trailing = { - 'row': 'right', - 'row-reverse': 'left', - 'column': 'bottom', - 'column-reverse': 'top' - }; - var pos = { - 'row': 'left', - 'row-reverse': 'right', - 'column': 'top', - 'column-reverse': 'bottom' - }; - var dim = { - 'row': 'width', - 'row-reverse': 'width', - 'column': 'height', - 'column-reverse': 'height' - }; - var measuredDim = { - 'row': 'measuredWidth', - 'row-reverse': 'measuredWidth', - 'column': 'measuredHeight', - 'column-reverse': 'measuredHeight' - }; - - // When transpiled to Java / C the node type has layout, children and style - // properties. For the JavaScript version this function adds these properties - // if they don't already exist. - function fillNodes(node) { - if (!node.layout || node.isDirty) { - node.layout = { - width: undefined, - height: undefined, - top: 0, - left: 0, - right: 0, - bottom: 0 - }; - } - - if (!node.style) { - node.style = {}; - } - - if (!node.children) { - node.children = []; - } - - if (node.style.measure && node.children && node.children.length) { - throw new Error('Using custom measure function is supported only for leaf nodes.'); - } - - node.children.forEach(fillNodes); - return node; - } - - function isUndefined(value) { - return value === undefined || Number.isNaN(value); - } - - function isRowDirection(flexDirection) { - return flexDirection === CSS_FLEX_DIRECTION_ROW || - flexDirection === CSS_FLEX_DIRECTION_ROW_REVERSE; - } - - function isColumnDirection(flexDirection) { - return flexDirection === CSS_FLEX_DIRECTION_COLUMN || - flexDirection === CSS_FLEX_DIRECTION_COLUMN_REVERSE; - } - - function getFlex(node) { - if (node.style.flex === undefined) { - return 0; - } - return node.style.flex; - } - - function isFlexBasisAuto(node) { - if (POSITIVE_FLEX_IS_AUTO) { - // All flex values are auto. - return true; - } else { - // A flex value > 0 implies a basis of zero. - return getFlex(node) <= 0; - } - } - - function getFlexGrowFactor(node) { - // Flex grow is implied by positive values for flex. - if (getFlex(node) > 0) { - return getFlex(node); - } - return 0; - } - - function getFlexShrinkFactor(node) { - if (POSITIVE_FLEX_IS_AUTO) { - // A flex shrink factor of 1 is implied by non-zero values for flex. - if (getFlex(node) !== 0) { - return 1; - } - } else { - // A flex shrink factor of 1 is implied by negative values for flex. - if (getFlex(node) < 0) { - return 1; - } - } - return 0; - } - - function getLeadingMargin(node, axis) { - if (node.style.marginStart !== undefined && isRowDirection(axis)) { - return node.style.marginStart; - } - - var value = null; - switch (axis) { - case 'row': value = node.style.marginLeft; break; - case 'row-reverse': value = node.style.marginRight; break; - case 'column': value = node.style.marginTop; break; - case 'column-reverse': value = node.style.marginBottom; break; - } - - if (value !== undefined) { - return value; - } - - if (node.style.margin !== undefined) { - return node.style.margin; - } - - return 0; - } - - function getTrailingMargin(node, axis) { - if (node.style.marginEnd !== undefined && isRowDirection(axis)) { - return node.style.marginEnd; - } - - var value = null; - switch (axis) { - case 'row': value = node.style.marginRight; break; - case 'row-reverse': value = node.style.marginLeft; break; - case 'column': value = node.style.marginBottom; break; - case 'column-reverse': value = node.style.marginTop; break; - } - - if (value != null) { - return value; - } - - if (node.style.margin !== undefined) { - return node.style.margin; - } - - return 0; - } - - function getLeadingPadding(node, axis) { - if (node.style.paddingStart !== undefined && node.style.paddingStart >= 0 - && isRowDirection(axis)) { - return node.style.paddingStart; - } - - var value = null; - switch (axis) { - case 'row': value = node.style.paddingLeft; break; - case 'row-reverse': value = node.style.paddingRight; break; - case 'column': value = node.style.paddingTop; break; - case 'column-reverse': value = node.style.paddingBottom; break; - } - - if (value != null && value >= 0) { - return value; - } - - if (node.style.padding !== undefined && node.style.padding >= 0) { - return node.style.padding; - } - - return 0; - } - - function getTrailingPadding(node, axis) { - if (node.style.paddingEnd !== undefined && node.style.paddingEnd >= 0 - && isRowDirection(axis)) { - return node.style.paddingEnd; - } - - var value = null; - switch (axis) { - case 'row': value = node.style.paddingRight; break; - case 'row-reverse': value = node.style.paddingLeft; break; - case 'column': value = node.style.paddingBottom; break; - case 'column-reverse': value = node.style.paddingTop; break; - } - - if (value != null && value >= 0) { - return value; - } - - if (node.style.padding !== undefined && node.style.padding >= 0) { - return node.style.padding; - } - - return 0; - } - - function getLeadingBorder(node, axis) { - if (node.style.borderStartWidth !== undefined && node.style.borderStartWidth >= 0 - && isRowDirection(axis)) { - return node.style.borderStartWidth; - } - - var value = null; - switch (axis) { - case 'row': value = node.style.borderLeftWidth; break; - case 'row-reverse': value = node.style.borderRightWidth; break; - case 'column': value = node.style.borderTopWidth; break; - case 'column-reverse': value = node.style.borderBottomWidth; break; - } - - if (value != null && value >= 0) { - return value; - } - - if (node.style.borderWidth !== undefined && node.style.borderWidth >= 0) { - return node.style.borderWidth; - } - - return 0; - } - - function getTrailingBorder(node, axis) { - if (node.style.borderEndWidth !== undefined && node.style.borderEndWidth >= 0 - && isRowDirection(axis)) { - return node.style.borderEndWidth; - } - - var value = null; - switch (axis) { - case 'row': value = node.style.borderRightWidth; break; - case 'row-reverse': value = node.style.borderLeftWidth; break; - case 'column': value = node.style.borderBottomWidth; break; - case 'column-reverse': value = node.style.borderTopWidth; break; - } - - if (value != null && value >= 0) { - return value; - } - - if (node.style.borderWidth !== undefined && node.style.borderWidth >= 0) { - return node.style.borderWidth; - } - - return 0; - } - - function getLeadingPaddingAndBorder(node, axis) { - return getLeadingPadding(node, axis) + getLeadingBorder(node, axis); - } - - function getTrailingPaddingAndBorder(node, axis) { - return getTrailingPadding(node, axis) + getTrailingBorder(node, axis); - } - - function getMarginAxis(node, axis) { - return getLeadingMargin(node, axis) + getTrailingMargin(node, axis); - } - - function getPaddingAndBorderAxis(node, axis) { - return getLeadingPaddingAndBorder(node, axis) + - getTrailingPaddingAndBorder(node, axis); - } - - function getJustifyContent(node) { - if (node.style.justifyContent) { - return node.style.justifyContent; - } - return 'flex-start'; - } - - function getAlignContent(node) { - if (node.style.alignContent) { - return node.style.alignContent; - } - return 'flex-start'; - } - - function getAlignItem(node, child) { - if (child.style.alignSelf) { - return child.style.alignSelf; - } - if (node.style.alignItems) { - return node.style.alignItems; - } - return 'stretch'; - } - - function resolveAxis(axis, direction) { - if (direction === CSS_DIRECTION_RTL) { - if (axis === CSS_FLEX_DIRECTION_ROW) { - return CSS_FLEX_DIRECTION_ROW_REVERSE; - } else if (axis === CSS_FLEX_DIRECTION_ROW_REVERSE) { - return CSS_FLEX_DIRECTION_ROW; - } - } - - return axis; - } - - function resolveDirection(node, parentDirection) { - var direction; - if (node.style.direction) { - direction = node.style.direction; - } else { - direction = CSS_DIRECTION_INHERIT; - } - - if (direction === CSS_DIRECTION_INHERIT) { - direction = (parentDirection === undefined ? CSS_DIRECTION_LTR : parentDirection); - } - - return direction; - } - - function getFlexDirection(node) { - if (node.style.flexDirection) { - return node.style.flexDirection; - } - return CSS_FLEX_DIRECTION_COLUMN; - } - - function getCrossFlexDirection(flexDirection, direction) { - if (isColumnDirection(flexDirection)) { - return resolveAxis(CSS_FLEX_DIRECTION_ROW, direction); - } else { - return CSS_FLEX_DIRECTION_COLUMN; - } - } - - function getPositionType(node) { - if (node.style.position) { - return node.style.position; - } - return CSS_POSITION_RELATIVE; - } - - function getOverflow(node) { - if (node.style.overflow) { - return node.style.overflow; - } - return CSS_OVERFLOW_VISIBLE; - } - - function isFlex(node) { - return ( - getPositionType(node) === CSS_POSITION_RELATIVE && - node.style.flex !== undefined && node.style.flex !== 0 - ); - } - - function isFlexWrap(node) { - return node.style.flexWrap === 'wrap'; - } - - function getDimWithMargin(node, axis) { - return node.layout[measuredDim[axis]] + getMarginAxis(node, axis); - } - - function isStyleDimDefined(node, axis) { - return node.style[dim[axis]] !== undefined && node.style[dim[axis]] >= 0; - } - - function isLayoutDimDefined(node, axis) { - return node.layout[measuredDim[axis]] !== undefined && node.layout[measuredDim[axis]] >= 0; - } - - function isPosDefined(node, pos) { - return node.style[pos] !== undefined; - } - - function isMeasureDefined(node) { - return node.style.measure !== undefined; - } - - function getPosition(node, pos) { - if (node.style[pos] !== undefined) { - return node.style[pos]; - } - return 0; - } - - function boundAxisWithinMinAndMax(node, axis, value) { - var min = { - 'row': node.style.minWidth, - 'row-reverse': node.style.minWidth, - 'column': node.style.minHeight, - 'column-reverse': node.style.minHeight - }[axis]; - - var max = { - 'row': node.style.maxWidth, - 'row-reverse': node.style.maxWidth, - 'column': node.style.maxHeight, - 'column-reverse': node.style.maxHeight - }[axis]; - - var boundValue = value; - if (max !== undefined && max >= 0 && boundValue > max) { - boundValue = max; - } - if (min !== undefined && min >= 0 && boundValue < min) { - boundValue = min; - } - return boundValue; - } - - function fminf(a, b) { - if (a < b) { - return a; - } - return b; - } - - function fmaxf(a, b) { - if (a > b) { - return a; - } - return b; - } - - // Like boundAxisWithinMinAndMax but also ensures that the value doesn't go below the - // padding and border amount. - function boundAxis(node, axis, value) { - return fmaxf(boundAxisWithinMinAndMax(node, axis, value), getPaddingAndBorderAxis(node, axis)); - } - - function setTrailingPosition(node, child, axis) { - var size = (getPositionType(child) === CSS_POSITION_ABSOLUTE) ? - 0 : - child.layout[measuredDim[axis]]; - child.layout[trailing[axis]] = node.layout[measuredDim[axis]] - size - child.layout[pos[axis]]; - } - - // If both left and right are defined, then use left. Otherwise return - // +left or -right depending on which is defined. - function getRelativePosition(node, axis) { - if (node.style[leading[axis]] !== undefined) { - return getPosition(node, leading[axis]); - } - return -getPosition(node, trailing[axis]); - } - - function setPosition(node, direction) { - var mainAxis = resolveAxis(getFlexDirection(node), direction); - var crossAxis = getCrossFlexDirection(mainAxis, direction); - - node.layout[leading[mainAxis]] = getLeadingMargin(node, mainAxis) + - getRelativePosition(node, mainAxis); - node.layout[trailing[mainAxis]] = getTrailingMargin(node, mainAxis) + - getRelativePosition(node, mainAxis); - node.layout[leading[crossAxis]] = getLeadingMargin(node, crossAxis) + - getRelativePosition(node, crossAxis); - node.layout[trailing[crossAxis]] = getTrailingMargin(node, crossAxis) + - getRelativePosition(node, crossAxis); - } - - function assert(condition, message) { - if (!condition) { - throw new Error(message); - } - } - - // - // This is the main routine that implements a subset of the flexbox layout algorithm - // described in the W3C CSS documentation: https://www.w3.org/TR/css3-flexbox/. - // - // Limitations of this algorithm, compared to the full standard: - // * Display property is always assumed to be 'flex' except for Text nodes, which - // are assumed to be 'inline-flex'. - // * The 'zIndex' property (or any form of z ordering) is not supported. Nodes are - // stacked in document order. - // * The 'order' property is not supported. The order of flex items is always defined - // by document order. - // * The 'visibility' property is always assumed to be 'visible'. Values of 'collapse' - // and 'hidden' are not supported. - // * The 'wrap' property supports only 'nowrap' (which is the default) or 'wrap'. The - // rarely-used 'wrap-reverse' is not supported. - // * Rather than allowing arbitrary combinations of flexGrow, flexShrink and - // flexBasis, this algorithm supports only the three most common combinations: - // flex: 0 is equiavlent to flex: 0 0 auto - // flex: n (where n is a positive value) is equivalent to flex: n 1 auto - // If POSITIVE_FLEX_IS_AUTO is 0, then it is equivalent to flex: n 0 0 - // This is faster because the content doesn't need to be measured, but it's - // less flexible because the basis is always 0 and can't be overriden with - // the width/height attributes. - // flex: -1 (or any negative value) is equivalent to flex: 0 1 auto - // * Margins cannot be specified as 'auto'. They must be specified in terms of pixel - // values, and the default value is 0. - // * The 'baseline' value is not supported for alignItems and alignSelf properties. - // * Values of width, maxWidth, minWidth, height, maxHeight and minHeight must be - // specified as pixel values, not as percentages. - // * There is no support for calculation of dimensions based on intrinsic aspect ratios - // (e.g. images). - // * There is no support for forced breaks. - // * It does not support vertical inline directions (top-to-bottom or bottom-to-top text). - // - // Deviations from standard: - // * Section 4.5 of the spec indicates that all flex items have a default minimum - // main size. For text blocks, for example, this is the width of the widest word. - // Calculating the minimum width is expensive, so we forego it and assume a default - // minimum main size of 0. - // * Min/Max sizes in the main axis are not honored when resolving flexible lengths. - // * The spec indicates that the default value for 'flexDirection' is 'row', but - // the algorithm below assumes a default of 'column'. - // - // Input parameters: - // - node: current node to be sized and layed out - // - availableWidth & availableHeight: available size to be used for sizing the node - // or CSS_UNDEFINED if the size is not available; interpretation depends on layout - // flags - // - parentDirection: the inline (text) direction within the parent (left-to-right or - // right-to-left) - // - widthMeasureMode: indicates the sizing rules for the width (see below for explanation) - // - heightMeasureMode: indicates the sizing rules for the height (see below for explanation) - // - performLayout: specifies whether the caller is interested in just the dimensions - // of the node or it requires the entire node and its subtree to be layed out - // (with final positions) - // - // Details: - // This routine is called recursively to lay out subtrees of flexbox elements. It uses the - // information in node.style, which is treated as a read-only input. It is responsible for - // setting the layout.direction and layout.measured_dimensions fields for the input node as well - // as the layout.position and layout.line_index fields for its child nodes. The - // layout.measured_dimensions field includes any border or padding for the node but does - // not include margins. - // - // The spec describes four different layout modes: "fill available", "max content", "min content", - // and "fit content". Of these, we don't use "min content" because we don't support default - // minimum main sizes (see above for details). Each of our measure modes maps to a layout mode - // from the spec (https://www.w3.org/TR/css3-sizing/#terms): - // - CSS_MEASURE_MODE_UNDEFINED: max content - // - CSS_MEASURE_MODE_EXACTLY: fill available - // - CSS_MEASURE_MODE_AT_MOST: fit content - // - // When calling layoutNodeImpl and layoutNodeInternal, if the caller passes an available size of - // undefined then it must also pass a measure mode of CSS_MEASURE_MODE_UNDEFINED in that dimension. - // - function layoutNodeImpl(node, availableWidth, availableHeight, /*css_direction_t*/parentDirection, widthMeasureMode, heightMeasureMode, performLayout) { - assert(isUndefined(availableWidth) ? widthMeasureMode === CSS_MEASURE_MODE_UNDEFINED : true, 'availableWidth is indefinite so widthMeasureMode must be CSS_MEASURE_MODE_UNDEFINED'); - assert(isUndefined(availableHeight) ? heightMeasureMode === CSS_MEASURE_MODE_UNDEFINED : true, 'availableHeight is indefinite so heightMeasureMode must be CSS_MEASURE_MODE_UNDEFINED'); - - var/*float*/ paddingAndBorderAxisRow = getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW); - var/*float*/ paddingAndBorderAxisColumn = getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN); - var/*float*/ marginAxisRow = getMarginAxis(node, CSS_FLEX_DIRECTION_ROW); - var/*float*/ marginAxisColumn = getMarginAxis(node, CSS_FLEX_DIRECTION_COLUMN); - - // Set the resolved resolution in the node's layout. - var/*css_direction_t*/ direction = resolveDirection(node, parentDirection); - node.layout.direction = direction; - - // For content (text) nodes, determine the dimensions based on the text contents. - if (isMeasureDefined(node)) { - var/*float*/ innerWidth = availableWidth - marginAxisRow - paddingAndBorderAxisRow; - var/*float*/ innerHeight = availableHeight - marginAxisColumn - paddingAndBorderAxisColumn; - - if (widthMeasureMode === CSS_MEASURE_MODE_EXACTLY && heightMeasureMode === CSS_MEASURE_MODE_EXACTLY) { - - // Don't bother sizing the text if both dimensions are already defined. - node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW, availableWidth - marginAxisRow); - node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, availableHeight - marginAxisColumn); - } else if (innerWidth <= 0 || innerHeight <= 0) { - - // Don't bother sizing the text if there's no horizontal or vertical space. - node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW, 0); - node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, 0); - } else { - - // Measure the text under the current constraints. - var/*css_dim_t*/ measureDim = node.style.measure( - /*(c)!node->context,*/ - /*(java)!layoutContext.measureOutput,*/ - innerWidth, - widthMeasureMode, - innerHeight, - heightMeasureMode - ); - - node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW, - (widthMeasureMode === CSS_MEASURE_MODE_UNDEFINED || widthMeasureMode === CSS_MEASURE_MODE_AT_MOST) ? - measureDim.width + paddingAndBorderAxisRow : - availableWidth - marginAxisRow); - node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, - (heightMeasureMode === CSS_MEASURE_MODE_UNDEFINED || heightMeasureMode === CSS_MEASURE_MODE_AT_MOST) ? - measureDim.height + paddingAndBorderAxisColumn : - availableHeight - marginAxisColumn); - } - - return; - } - - // For nodes with no children, use the available values if they were provided, or - // the minimum size as indicated by the padding and border sizes. - var/*int*/ childCount = node.children.length; - if (childCount === 0) { - node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW, - (widthMeasureMode === CSS_MEASURE_MODE_UNDEFINED || widthMeasureMode === CSS_MEASURE_MODE_AT_MOST) ? - paddingAndBorderAxisRow : - availableWidth - marginAxisRow); - node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, - (heightMeasureMode === CSS_MEASURE_MODE_UNDEFINED || heightMeasureMode === CSS_MEASURE_MODE_AT_MOST) ? - paddingAndBorderAxisColumn : - availableHeight - marginAxisColumn); - return; - } - - // If we're not being asked to perform a full layout, we can handle a number of common - // cases here without incurring the cost of the remaining function. - if (!performLayout) { - // If we're being asked to size the content with an at most constraint but there is no available width, - // the measurement will always be zero. - if (widthMeasureMode === CSS_MEASURE_MODE_AT_MOST && availableWidth <= 0 && - heightMeasureMode === CSS_MEASURE_MODE_AT_MOST && availableHeight <= 0) { - node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW, 0); - node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, 0); - return; - } - - if (widthMeasureMode === CSS_MEASURE_MODE_AT_MOST && availableWidth <= 0) { - node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW, 0); - node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, isUndefined(availableHeight) ? 0 : (availableHeight - marginAxisColumn)); - return; - } - - if (heightMeasureMode === CSS_MEASURE_MODE_AT_MOST && availableHeight <= 0) { - node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW, isUndefined(availableWidth) ? 0 : (availableWidth - marginAxisRow)); - node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, 0); - return; - } - - // If we're being asked to use an exact width/height, there's no need to measure the children. - if (widthMeasureMode === CSS_MEASURE_MODE_EXACTLY && heightMeasureMode === CSS_MEASURE_MODE_EXACTLY) { - node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW, availableWidth - marginAxisRow); - node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, availableHeight - marginAxisColumn); - return; - } - } - - // STEP 1: CALCULATE VALUES FOR REMAINDER OF ALGORITHM - var/*(c)!css_flex_direction_t*//*(java)!int*/ mainAxis = resolveAxis(getFlexDirection(node), direction); - var/*(c)!css_flex_direction_t*//*(java)!int*/ crossAxis = getCrossFlexDirection(mainAxis, direction); - var/*bool*/ isMainAxisRow = isRowDirection(mainAxis); - var/*css_justify_t*/ justifyContent = getJustifyContent(node); - var/*bool*/ isNodeFlexWrap = isFlexWrap(node); - - var/*css_node_t**/ firstAbsoluteChild = undefined; - var/*css_node_t**/ currentAbsoluteChild = undefined; - - var/*float*/ leadingPaddingAndBorderMain = getLeadingPaddingAndBorder(node, mainAxis); - var/*float*/ trailingPaddingAndBorderMain = getTrailingPaddingAndBorder(node, mainAxis); - var/*float*/ leadingPaddingAndBorderCross = getLeadingPaddingAndBorder(node, crossAxis); - var/*float*/ paddingAndBorderAxisMain = getPaddingAndBorderAxis(node, mainAxis); - var/*float*/ paddingAndBorderAxisCross = getPaddingAndBorderAxis(node, crossAxis); - - var/*css_measure_mode_t*/ measureModeMainDim = isMainAxisRow ? widthMeasureMode : heightMeasureMode; - var/*css_measure_mode_t*/ measureModeCrossDim = isMainAxisRow ? heightMeasureMode : widthMeasureMode; - - // STEP 2: DETERMINE AVAILABLE SIZE IN MAIN AND CROSS DIRECTIONS - var/*float*/ availableInnerWidth = availableWidth - marginAxisRow - paddingAndBorderAxisRow; - var/*float*/ availableInnerHeight = availableHeight - marginAxisColumn - paddingAndBorderAxisColumn; - var/*float*/ availableInnerMainDim = isMainAxisRow ? availableInnerWidth : availableInnerHeight; - var/*float*/ availableInnerCrossDim = isMainAxisRow ? availableInnerHeight : availableInnerWidth; - - // STEP 3: DETERMINE FLEX BASIS FOR EACH ITEM - var/*css_node_t**/ child; - var/*int*/ i; - var/*float*/ childWidth; - var/*float*/ childHeight; - var/*css_measure_mode_t*/ childWidthMeasureMode; - var/*css_measure_mode_t*/ childHeightMeasureMode; - for (i = 0; i < childCount; i++) { - child = node.children[i]; - - if (performLayout) { - // Set the initial position (relative to the parent). - var/*css_direction_t*/ childDirection = resolveDirection(child, direction); - setPosition(child, childDirection); - } - - // Absolute-positioned children don't participate in flex layout. Add them - // to a list that we can process later. - if (getPositionType(child) === CSS_POSITION_ABSOLUTE) { - - // Store a private linked list of absolutely positioned children - // so that we can efficiently traverse them later. - if (firstAbsoluteChild === undefined) { - firstAbsoluteChild = child; - } - if (currentAbsoluteChild !== undefined) { - currentAbsoluteChild.nextChild = child; - } - currentAbsoluteChild = child; - child.nextChild = undefined; - } else { - - if (isMainAxisRow && isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW)) { - - // The width is definite, so use that as the flex basis. - child.layout.flexBasis = fmaxf(child.style.width, getPaddingAndBorderAxis(child, CSS_FLEX_DIRECTION_ROW)); - } else if (!isMainAxisRow && isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN)) { - - // The height is definite, so use that as the flex basis. - child.layout.flexBasis = fmaxf(child.style.height, getPaddingAndBorderAxis(child, CSS_FLEX_DIRECTION_COLUMN)); - } else if (!isFlexBasisAuto(child) && !isUndefined(availableInnerMainDim)) { - - // If the basis isn't 'auto', it is assumed to be zero. - child.layout.flexBasis = fmaxf(0, getPaddingAndBorderAxis(child, mainAxis)); - } else { - - // Compute the flex basis and hypothetical main size (i.e. the clamped flex basis). - childWidth = CSS_UNDEFINED; - childHeight = CSS_UNDEFINED; - childWidthMeasureMode = CSS_MEASURE_MODE_UNDEFINED; - childHeightMeasureMode = CSS_MEASURE_MODE_UNDEFINED; - - if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW)) { - childWidth = child.style.width + getMarginAxis(child, CSS_FLEX_DIRECTION_ROW); - childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } - if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN)) { - childHeight = child.style.height + getMarginAxis(child, CSS_FLEX_DIRECTION_COLUMN); - childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } - - // According to the spec, if the main size is not definite and the - // child's inline axis is parallel to the main axis (i.e. it's - // horizontal), the child should be sized using "UNDEFINED" in - // the main size. Otherwise use "AT_MOST" in the cross axis. - if (!isMainAxisRow && isUndefined(childWidth) && !isUndefined(availableInnerWidth)) { - childWidth = availableInnerWidth; - childWidthMeasureMode = CSS_MEASURE_MODE_AT_MOST; - } - - // The W3C spec doesn't say anything about the 'overflow' property, - // but all major browsers appear to implement the following logic. - if (getOverflow(node) === CSS_OVERFLOW_HIDDEN) { - if (isMainAxisRow && isUndefined(childHeight) && !isUndefined(availableInnerHeight)) { - childHeight = availableInnerHeight; - childHeightMeasureMode = CSS_MEASURE_MODE_AT_MOST; - } - } - - // If child has no defined size in the cross axis and is set to stretch, set the cross - // axis to be measured exactly with the available inner width - if (!isMainAxisRow && - !isUndefined(availableInnerWidth) && - !isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW) && - widthMeasureMode == CSS_MEASURE_MODE_EXACTLY && - getAlignItem(node, child) == CSS_ALIGN_STRETCH) { - childWidth = availableInnerWidth; - childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } - if (isMainAxisRow && - !isUndefined(availableInnerHeight) && - !isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN) && - heightMeasureMode == CSS_MEASURE_MODE_EXACTLY && - getAlignItem(node, child) == CSS_ALIGN_STRETCH) { - childHeight = availableInnerHeight; - childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } - - // Measure the child - layoutNodeInternal(child, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, false, 'measure'); - - child.layout.flexBasis = fmaxf(isMainAxisRow ? child.layout.measuredWidth : child.layout.measuredHeight, getPaddingAndBorderAxis(child, mainAxis)); - } - } - } - - // STEP 4: COLLECT FLEX ITEMS INTO FLEX LINES - - // Indexes of children that represent the first and last items in the line. - var/*int*/ startOfLineIndex = 0; - var/*int*/ endOfLineIndex = 0; - - // Number of lines. - var/*int*/ lineCount = 0; - - // Accumulated cross dimensions of all lines so far. - var/*float*/ totalLineCrossDim = 0; - - // Max main dimension of all the lines. - var/*float*/ maxLineMainDim = 0; - - while (endOfLineIndex < childCount) { - - // Number of items on the currently line. May be different than the difference - // between start and end indicates because we skip over absolute-positioned items. - var/*int*/ itemsOnLine = 0; - - // sizeConsumedOnCurrentLine is accumulation of the dimensions and margin - // of all the children on the current line. 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. - var/*float*/ sizeConsumedOnCurrentLine = 0; - - var/*float*/ totalFlexGrowFactors = 0; - var/*float*/ totalFlexShrinkScaledFactors = 0; - - i = startOfLineIndex; - - // Maintain a linked list of the child nodes that can shrink and/or grow. - var/*css_node_t**/ firstRelativeChild = undefined; - var/*css_node_t**/ currentRelativeChild = undefined; - - // Add items to the current line until it's full or we run out of items. - while (i < childCount) { - child = node.children[i]; - child.lineIndex = lineCount; - - if (getPositionType(child) !== CSS_POSITION_ABSOLUTE) { - var/*float*/ outerFlexBasis = child.layout.flexBasis + getMarginAxis(child, mainAxis); - - // If this is a multi-line flow and this item pushes us over the available size, we've - // hit the end of the current line. Break out of the loop and lay out the current line. - if (sizeConsumedOnCurrentLine + outerFlexBasis > availableInnerMainDim && isNodeFlexWrap && itemsOnLine > 0) { - break; - } - - sizeConsumedOnCurrentLine += outerFlexBasis; - itemsOnLine++; - - if (isFlex(child)) { - totalFlexGrowFactors += getFlexGrowFactor(child); - - // Unlike the grow factor, the shrink factor is scaled relative to the child - // dimension. - totalFlexShrinkScaledFactors += getFlexShrinkFactor(child) * child.layout.flexBasis; - } - - // Store a private linked list of children that need to be layed out. - if (firstRelativeChild === undefined) { - firstRelativeChild = child; - } - if (currentRelativeChild !== undefined) { - currentRelativeChild.nextChild = child; - } - currentRelativeChild = child; - child.nextChild = undefined; - } - - i++; - endOfLineIndex++; - } - - // If we don't need to measure the cross axis, we can skip the entire flex step. - var/*bool*/ canSkipFlex = !performLayout && measureModeCrossDim === CSS_MEASURE_MODE_EXACTLY; - - // 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. - var/*float*/ leadingMainDim = 0; - var/*float*/ betweenMainDim = 0; - - // STEP 5: RESOLVING FLEXIBLE LENGTHS ON MAIN AXIS - // Calculate the remaining available space that needs to be allocated. - // If the main dimension size isn't known, it is computed based on - // the line length, so there's no more space left to distribute. - var/*float*/ remainingFreeSpace = 0; - if (!isUndefined(availableInnerMainDim)) { - remainingFreeSpace = availableInnerMainDim - sizeConsumedOnCurrentLine; - } else if (sizeConsumedOnCurrentLine < 0) { - // availableInnerMainDim is indefinite which means the node is being sized based on its content. - // sizeConsumedOnCurrentLine is negative which means the node will allocate 0 pixels for - // its content. Consequently, remainingFreeSpace is 0 - sizeConsumedOnCurrentLine. - remainingFreeSpace = -sizeConsumedOnCurrentLine; - } - - var/*float*/ originalRemainingFreeSpace = remainingFreeSpace; - var/*float*/ deltaFreeSpace = 0; - - if (!canSkipFlex) { - var/*float*/ childFlexBasis; - var/*float*/ flexShrinkScaledFactor; - var/*float*/ flexGrowFactor; - var/*float*/ baseMainSize; - var/*float*/ boundMainSize; - - // Do two passes over the flex items to figure out how to distribute the remaining space. - // The first pass finds the items whose min/max constraints trigger, freezes them at those - // sizes, and excludes those sizes from the remaining space. The second pass sets the size - // of each flexible item. It distributes the remaining space amongst the items whose min/max - // constraints didn't trigger in pass 1. For the other items, it sets their sizes by forcing - // their min/max constraints to trigger again. - // - // This two pass approach for resolving min/max constraints deviates from the spec. The - // spec (https://www.w3.org/TR/css-flexbox-1/#resolve-flexible-lengths) describes a process - // that needs to be repeated a variable number of times. The algorithm implemented here - // won't handle all cases but it was simpler to implement and it mitigates performance - // concerns because we know exactly how many passes it'll do. - - // First pass: detect the flex items whose min/max constraints trigger - var/*float*/ deltaFlexShrinkScaledFactors = 0; - var/*float*/ deltaFlexGrowFactors = 0; - currentRelativeChild = firstRelativeChild; - while (currentRelativeChild !== undefined) { - childFlexBasis = currentRelativeChild.layout.flexBasis; - - if (remainingFreeSpace < 0) { - flexShrinkScaledFactor = getFlexShrinkFactor(currentRelativeChild) * childFlexBasis; - - // Is this child able to shrink? - if (flexShrinkScaledFactor !== 0) { - baseMainSize = childFlexBasis + - remainingFreeSpace / totalFlexShrinkScaledFactors * flexShrinkScaledFactor; - boundMainSize = boundAxis(currentRelativeChild, mainAxis, baseMainSize); - if (baseMainSize !== boundMainSize) { - // By excluding this item's size and flex factor from remaining, this item's - // min/max constraints should also trigger in the second pass resulting in the - // item's size calculation being identical in the first and second passes. - deltaFreeSpace -= boundMainSize - childFlexBasis; - deltaFlexShrinkScaledFactors -= flexShrinkScaledFactor; - } - } - } else if (remainingFreeSpace > 0) { - flexGrowFactor = getFlexGrowFactor(currentRelativeChild); - - // Is this child able to grow? - if (flexGrowFactor !== 0) { - baseMainSize = childFlexBasis + - remainingFreeSpace / totalFlexGrowFactors * flexGrowFactor; - boundMainSize = boundAxis(currentRelativeChild, mainAxis, baseMainSize); - if (baseMainSize !== boundMainSize) { - // By excluding this item's size and flex factor from remaining, this item's - // min/max constraints should also trigger in the second pass resulting in the - // item's size calculation being identical in the first and second passes. - deltaFreeSpace -= boundMainSize - childFlexBasis; - deltaFlexGrowFactors -= flexGrowFactor; - } - } - } - - currentRelativeChild = currentRelativeChild.nextChild; - } - - totalFlexShrinkScaledFactors += deltaFlexShrinkScaledFactors; - totalFlexGrowFactors += deltaFlexGrowFactors; - remainingFreeSpace += deltaFreeSpace; - - // Second pass: resolve the sizes of the flexible items - deltaFreeSpace = 0; - currentRelativeChild = firstRelativeChild; - while (currentRelativeChild !== undefined) { - childFlexBasis = currentRelativeChild.layout.flexBasis; - var/*float*/ updatedMainSize = childFlexBasis; - - if (remainingFreeSpace < 0) { - flexShrinkScaledFactor = getFlexShrinkFactor(currentRelativeChild) * childFlexBasis; - - // Is this child able to shrink? - if (flexShrinkScaledFactor !== 0) { - updatedMainSize = boundAxis(currentRelativeChild, mainAxis, childFlexBasis + - remainingFreeSpace / totalFlexShrinkScaledFactors * flexShrinkScaledFactor); - } - } else if (remainingFreeSpace > 0) { - flexGrowFactor = getFlexGrowFactor(currentRelativeChild); - - // Is this child able to grow? - if (flexGrowFactor !== 0) { - updatedMainSize = boundAxis(currentRelativeChild, mainAxis, childFlexBasis + - remainingFreeSpace / totalFlexGrowFactors * flexGrowFactor); - } - } - - deltaFreeSpace -= updatedMainSize - childFlexBasis; - - if (isMainAxisRow) { - childWidth = updatedMainSize + getMarginAxis(currentRelativeChild, CSS_FLEX_DIRECTION_ROW); - childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; - - if (!isUndefined(availableInnerCrossDim) && - !isStyleDimDefined(currentRelativeChild, CSS_FLEX_DIRECTION_COLUMN) && - heightMeasureMode == CSS_MEASURE_MODE_EXACTLY && - getAlignItem(node, currentRelativeChild) == CSS_ALIGN_STRETCH) { - childHeight = availableInnerCrossDim; - childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } else if (!isStyleDimDefined(currentRelativeChild, CSS_FLEX_DIRECTION_COLUMN)) { - childHeight = availableInnerCrossDim; - childHeightMeasureMode = isUndefined(childHeight) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_AT_MOST; - } else { - childHeight = currentRelativeChild.style.height + getMarginAxis(currentRelativeChild, CSS_FLEX_DIRECTION_COLUMN); - childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } - } else { - childHeight = updatedMainSize + getMarginAxis(currentRelativeChild, CSS_FLEX_DIRECTION_COLUMN); - childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY; - - if (!isUndefined(availableInnerCrossDim) && - !isStyleDimDefined(currentRelativeChild, CSS_FLEX_DIRECTION_ROW) && - widthMeasureMode == CSS_MEASURE_MODE_EXACTLY && - getAlignItem(node, currentRelativeChild) == CSS_ALIGN_STRETCH) { - childWidth = availableInnerCrossDim; - childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } else if (!isStyleDimDefined(currentRelativeChild, CSS_FLEX_DIRECTION_ROW)) { - childWidth = availableInnerCrossDim; - childWidthMeasureMode = isUndefined(childWidth) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_AT_MOST; - } else { - childWidth = currentRelativeChild.style.width + getMarginAxis(currentRelativeChild, CSS_FLEX_DIRECTION_ROW); - childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } - } - - var/*bool*/ requiresStretchLayout = !isStyleDimDefined(currentRelativeChild, crossAxis) && - getAlignItem(node, currentRelativeChild) === CSS_ALIGN_STRETCH; - - // Recursively call the layout algorithm for this child with the updated main size. - layoutNodeInternal(currentRelativeChild, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, performLayout && !requiresStretchLayout, 'flex'); - - currentRelativeChild = currentRelativeChild.nextChild; - } - } - - remainingFreeSpace = originalRemainingFreeSpace + deltaFreeSpace; - - // STEP 6: MAIN-AXIS JUSTIFICATION & CROSS-AXIS SIZE DETERMINATION - - // At this point, all the children have their dimensions set in the main axis. - // Their dimensions are also set in the cross axis with the exception of items - // that are aligned 'stretch'. We need to compute these stretch values and - // set the final positions. - - // If we are using "at most" rules in the main axis, we won't distribute - // any remaining space at this point. - if (measureModeMainDim === CSS_MEASURE_MODE_AT_MOST) { - remainingFreeSpace = 0; - } - - // Use justifyContent to figure out how to allocate the remaining space - // available in the main axis. - if (justifyContent !== CSS_JUSTIFY_FLEX_START) { - if (justifyContent === CSS_JUSTIFY_CENTER) { - leadingMainDim = remainingFreeSpace / 2; - } else if (justifyContent === CSS_JUSTIFY_FLEX_END) { - leadingMainDim = remainingFreeSpace; - } else if (justifyContent === CSS_JUSTIFY_SPACE_BETWEEN) { - remainingFreeSpace = fmaxf(remainingFreeSpace, 0); - if (itemsOnLine > 1) { - betweenMainDim = remainingFreeSpace / (itemsOnLine - 1); - } else { - betweenMainDim = 0; - } - } else if (justifyContent === CSS_JUSTIFY_SPACE_AROUND) { - // Space on the edges is half of the space between elements - betweenMainDim = remainingFreeSpace / itemsOnLine; - leadingMainDim = betweenMainDim / 2; - } - } - - var/*float*/ mainDim = leadingPaddingAndBorderMain + leadingMainDim; - var/*float*/ crossDim = 0; - - for (i = startOfLineIndex; i < endOfLineIndex; ++i) { - child = node.children[i]; - - if (getPositionType(child) === CSS_POSITION_ABSOLUTE && - isPosDefined(child, leading[mainAxis])) { - if (performLayout) { - // 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). - child.layout[pos[mainAxis]] = getPosition(child, leading[mainAxis]) + - getLeadingBorder(node, mainAxis) + - getLeadingMargin(child, mainAxis); - } - } else { - if (performLayout) { - // If the child is position absolute (without top/left) or relative, - // we put it at the current accumulated offset. - child.layout[pos[mainAxis]] += mainDim; - } - - // Now that we placed the element, we need to update the variables. - // We need to do that only for relative elements. Absolute elements - // do not take part in that phase. - if (getPositionType(child) === CSS_POSITION_RELATIVE) { - if (canSkipFlex) { - // If we skipped the flex step, then we can't rely on the measuredDims because - // they weren't computed. This means we can't call getDimWithMargin. - mainDim += betweenMainDim + getMarginAxis(child, mainAxis) + child.layout.flexBasis; - crossDim = availableInnerCrossDim; - } else { - // The main dimension is the sum of all the elements dimension plus - // the spacing. - 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 = fmaxf(crossDim, getDimWithMargin(child, crossAxis)); - } - } - } - } - - mainDim += trailingPaddingAndBorderMain; - - var/*float*/ containerCrossAxis = availableInnerCrossDim; - if (measureModeCrossDim === CSS_MEASURE_MODE_UNDEFINED || measureModeCrossDim === CSS_MEASURE_MODE_AT_MOST) { - // Compute the cross axis from the max cross dimension of the children. - containerCrossAxis = boundAxis(node, crossAxis, crossDim + paddingAndBorderAxisCross) - paddingAndBorderAxisCross; - - if (measureModeCrossDim === CSS_MEASURE_MODE_AT_MOST) { - containerCrossAxis = fminf(containerCrossAxis, availableInnerCrossDim); - } - } - - // If there's no flex wrap, the cross dimension is defined by the container. - if (!isNodeFlexWrap && measureModeCrossDim === CSS_MEASURE_MODE_EXACTLY) { - crossDim = availableInnerCrossDim; - } - - // Clamp to the min/max size specified on the container. - crossDim = boundAxis(node, crossAxis, crossDim + paddingAndBorderAxisCross) - paddingAndBorderAxisCross; - - // STEP 7: CROSS-AXIS ALIGNMENT - // We can skip child alignment if we're just measuring the container. - if (performLayout) { - for (i = startOfLineIndex; i < endOfLineIndex; ++i) { - child = node.children[i]; - - if (getPositionType(child) === CSS_POSITION_ABSOLUTE) { - // If the child is absolutely positioned and has a top/left/bottom/right - // set, override all the previously computed positions to set it correctly. - if (isPosDefined(child, leading[crossAxis])) { - child.layout[pos[crossAxis]] = getPosition(child, leading[crossAxis]) + - getLeadingBorder(node, crossAxis) + - getLeadingMargin(child, crossAxis); - } else { - child.layout[pos[crossAxis]] = leadingPaddingAndBorderCross + - getLeadingMargin(child, crossAxis); - } - } else { - var/*float*/ leadingCrossDim = leadingPaddingAndBorderCross; - - // For a relative children, we're either using alignItems (parent) or - // alignSelf (child) in order to determine the position in the cross axis - var/*css_align_t*/ alignItem = getAlignItem(node, child); - - // If the child uses align stretch, we need to lay it out one more time, this time - // forcing the cross-axis size to be the computed cross size for the current line. - if (alignItem === CSS_ALIGN_STRETCH) { - childWidth = child.layout.measuredWidth + getMarginAxis(child, CSS_FLEX_DIRECTION_ROW); - childHeight = child.layout.measuredHeight + getMarginAxis(child, CSS_FLEX_DIRECTION_COLUMN); - var/*bool*/ isCrossSizeDefinite = false; - - if (isMainAxisRow) { - isCrossSizeDefinite = isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN); - childHeight = crossDim; - } else { - isCrossSizeDefinite = isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW); - childWidth = crossDim; - } - - // If the child defines a definite size for its cross axis, there's no need to stretch. - if (!isCrossSizeDefinite) { - childWidthMeasureMode = isUndefined(childWidth) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_EXACTLY; - childHeightMeasureMode = isUndefined(childHeight) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_EXACTLY; - layoutNodeInternal(child, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, true, 'stretch'); - } - } else if (alignItem !== CSS_ALIGN_FLEX_START) { - var/*float*/ remainingCrossDim = containerCrossAxis - getDimWithMargin(child, crossAxis); - - if (alignItem === CSS_ALIGN_CENTER) { - leadingCrossDim += remainingCrossDim / 2; - } else { // CSS_ALIGN_FLEX_END - leadingCrossDim += remainingCrossDim; - } - } - - // And we apply the position - child.layout[pos[crossAxis]] += totalLineCrossDim + leadingCrossDim; - } - } - } - - totalLineCrossDim += crossDim; - maxLineMainDim = fmaxf(maxLineMainDim, mainDim); - - // Reset variables for new line. - lineCount++; - startOfLineIndex = endOfLineIndex; - endOfLineIndex = startOfLineIndex; - } - - // STEP 8: MULTI-LINE CONTENT ALIGNMENT - if (lineCount > 1 && performLayout && !isUndefined(availableInnerCrossDim)) { - var/*float*/ remainingAlignContentDim = availableInnerCrossDim - totalLineCrossDim; - - var/*float*/ crossDimLead = 0; - var/*float*/ currentLead = leadingPaddingAndBorderCross; - - var/*css_align_t*/ alignContent = getAlignContent(node); - if (alignContent === CSS_ALIGN_FLEX_END) { - currentLead += remainingAlignContentDim; - } else if (alignContent === CSS_ALIGN_CENTER) { - currentLead += remainingAlignContentDim / 2; - } else if (alignContent === CSS_ALIGN_STRETCH) { - if (availableInnerCrossDim > totalLineCrossDim) { - crossDimLead = (remainingAlignContentDim / lineCount); - } - } - - var/*int*/ endIndex = 0; - for (i = 0; i < lineCount; ++i) { - var/*int*/ startIndex = endIndex; - var/*int*/ j; - - // compute the line's height and find the endIndex - var/*float*/ lineHeight = 0; - for (j = startIndex; j < childCount; ++j) { - child = node.children[j]; - if (getPositionType(child) !== CSS_POSITION_RELATIVE) { - continue; - } - if (child.lineIndex !== i) { - break; - } - if (isLayoutDimDefined(child, crossAxis)) { - lineHeight = fmaxf(lineHeight, - child.layout[measuredDim[crossAxis]] + getMarginAxis(child, crossAxis)); - } - } - endIndex = j; - lineHeight += crossDimLead; - - if (performLayout) { - for (j = startIndex; j < endIndex; ++j) { - child = node.children[j]; - if (getPositionType(child) !== CSS_POSITION_RELATIVE) { - continue; - } - - var/*css_align_t*/ alignContentAlignItem = getAlignItem(node, child); - if (alignContentAlignItem === CSS_ALIGN_FLEX_START) { - child.layout[pos[crossAxis]] = currentLead + getLeadingMargin(child, crossAxis); - } else if (alignContentAlignItem === CSS_ALIGN_FLEX_END) { - child.layout[pos[crossAxis]] = currentLead + lineHeight - getTrailingMargin(child, crossAxis) - child.layout[measuredDim[crossAxis]]; - } else if (alignContentAlignItem === CSS_ALIGN_CENTER) { - childHeight = child.layout[measuredDim[crossAxis]]; - child.layout[pos[crossAxis]] = currentLead + (lineHeight - childHeight) / 2; - } else if (alignContentAlignItem === CSS_ALIGN_STRETCH) { - child.layout[pos[crossAxis]] = currentLead + getLeadingMargin(child, crossAxis); - // TODO(prenaux): Correctly set the height of items with indefinite - // (auto) crossAxis dimension. - } - } - } - - currentLead += lineHeight; - } - } - - // STEP 9: COMPUTING FINAL DIMENSIONS - node.layout.measuredWidth = boundAxis(node, CSS_FLEX_DIRECTION_ROW, availableWidth - marginAxisRow); - node.layout.measuredHeight = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, availableHeight - marginAxisColumn); - - // If the user didn't specify a width or height for the node, set the - // dimensions based on the children. - if (measureModeMainDim === CSS_MEASURE_MODE_UNDEFINED) { - // Clamp the size to the min/max size, if specified, and make sure it - // doesn't go below the padding and border amount. - node.layout[measuredDim[mainAxis]] = boundAxis(node, mainAxis, maxLineMainDim); - } else if (measureModeMainDim === CSS_MEASURE_MODE_AT_MOST) { - node.layout[measuredDim[mainAxis]] = fmaxf( - fminf(availableInnerMainDim + paddingAndBorderAxisMain, - boundAxisWithinMinAndMax(node, mainAxis, maxLineMainDim)), - paddingAndBorderAxisMain); - } - - if (measureModeCrossDim === CSS_MEASURE_MODE_UNDEFINED) { - // Clamp the size to the min/max size, if specified, and make sure it - // doesn't go below the padding and border amount. - node.layout[measuredDim[crossAxis]] = boundAxis(node, crossAxis, totalLineCrossDim + paddingAndBorderAxisCross); - } else if (measureModeCrossDim === CSS_MEASURE_MODE_AT_MOST) { - node.layout[measuredDim[crossAxis]] = fmaxf( - fminf(availableInnerCrossDim + paddingAndBorderAxisCross, - boundAxisWithinMinAndMax(node, crossAxis, totalLineCrossDim + paddingAndBorderAxisCross)), - paddingAndBorderAxisCross); - } - - // STEP 10: SETTING TRAILING POSITIONS FOR CHILDREN - if (performLayout) { - var/*bool*/ needsMainTrailingPos = false; - var/*bool*/ needsCrossTrailingPos = false; - - if (mainAxis === CSS_FLEX_DIRECTION_ROW_REVERSE || - mainAxis === CSS_FLEX_DIRECTION_COLUMN_REVERSE) { - needsMainTrailingPos = true; - } - - if (crossAxis === CSS_FLEX_DIRECTION_ROW_REVERSE || - crossAxis === CSS_FLEX_DIRECTION_COLUMN_REVERSE) { - needsCrossTrailingPos = true; - } - - // Set trailing position if necessary. - if (needsMainTrailingPos || needsCrossTrailingPos) { - for (i = 0; i < childCount; ++i) { - child = node.children[i]; - - if (needsMainTrailingPos) { - setTrailingPosition(node, child, mainAxis); - } - - if (needsCrossTrailingPos) { - setTrailingPosition(node, child, crossAxis); - } - } - } - } - - // STEP 11: SIZING AND POSITIONING ABSOLUTE CHILDREN - currentAbsoluteChild = firstAbsoluteChild; - while (currentAbsoluteChild !== undefined) { - // Now that we know the bounds of the container, perform layout again on the - // absolutely-positioned children. - if (performLayout) { - - childWidth = CSS_UNDEFINED; - childHeight = CSS_UNDEFINED; - - if (isStyleDimDefined(currentAbsoluteChild, CSS_FLEX_DIRECTION_ROW)) { - childWidth = currentAbsoluteChild.style.width + getMarginAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_ROW); - } else { - // If the child doesn't have a specified width, compute the width based on the left/right offsets if they're defined. - if (isPosDefined(currentAbsoluteChild, CSS_LEFT) && isPosDefined(currentAbsoluteChild, CSS_RIGHT)) { - childWidth = node.layout.measuredWidth - - (getLeadingBorder(node, CSS_FLEX_DIRECTION_ROW) + getTrailingBorder(node, CSS_FLEX_DIRECTION_ROW)) - - (currentAbsoluteChild.style[CSS_LEFT] + currentAbsoluteChild.style[CSS_RIGHT]); - childWidth = boundAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_ROW, childWidth); - } - } - - if (isStyleDimDefined(currentAbsoluteChild, CSS_FLEX_DIRECTION_COLUMN)) { - childHeight = currentAbsoluteChild.style.height + getMarginAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_COLUMN); - } else { - // If the child doesn't have a specified height, compute the height based on the top/bottom offsets if they're defined. - if (isPosDefined(currentAbsoluteChild, CSS_TOP) && isPosDefined(currentAbsoluteChild, CSS_BOTTOM)) { - childHeight = node.layout.measuredHeight - - (getLeadingBorder(node, CSS_FLEX_DIRECTION_COLUMN) + getTrailingBorder(node, CSS_FLEX_DIRECTION_COLUMN)) - - (currentAbsoluteChild.style[CSS_TOP] + currentAbsoluteChild.style[CSS_BOTTOM]); - childHeight = boundAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_COLUMN, childHeight); - } - } - - // If we're still missing one or the other dimension, measure the content. - if (isUndefined(childWidth) || isUndefined(childHeight)) { - childWidthMeasureMode = isUndefined(childWidth) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_EXACTLY; - childHeightMeasureMode = isUndefined(childHeight) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_EXACTLY; - - // According to the spec, if the main size is not definite and the - // child's inline axis is parallel to the main axis (i.e. it's - // horizontal), the child should be sized using "UNDEFINED" in - // the main size. Otherwise use "AT_MOST" in the cross axis. - if (!isMainAxisRow && isUndefined(childWidth) && !isUndefined(availableInnerWidth)) { - childWidth = availableInnerWidth; - childWidthMeasureMode = CSS_MEASURE_MODE_AT_MOST; - } - - // The W3C spec doesn't say anything about the 'overflow' property, - // but all major browsers appear to implement the following logic. - if (getOverflow(node) === CSS_OVERFLOW_HIDDEN) { - if (isMainAxisRow && isUndefined(childHeight) && !isUndefined(availableInnerHeight)) { - childHeight = availableInnerHeight; - childHeightMeasureMode = CSS_MEASURE_MODE_AT_MOST; - } - } - - layoutNodeInternal(currentAbsoluteChild, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, false, 'abs-measure'); - childWidth = currentAbsoluteChild.layout.measuredWidth + getMarginAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_ROW); - childHeight = currentAbsoluteChild.layout.measuredHeight + getMarginAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_COLUMN); - } - - layoutNodeInternal(currentAbsoluteChild, childWidth, childHeight, direction, CSS_MEASURE_MODE_EXACTLY, CSS_MEASURE_MODE_EXACTLY, true, 'abs-layout'); - - if (isPosDefined(currentAbsoluteChild, trailing[CSS_FLEX_DIRECTION_ROW]) && - !isPosDefined(currentAbsoluteChild, leading[CSS_FLEX_DIRECTION_ROW])) { - currentAbsoluteChild.layout[leading[CSS_FLEX_DIRECTION_ROW]] = - node.layout[measuredDim[CSS_FLEX_DIRECTION_ROW]] - - currentAbsoluteChild.layout[measuredDim[CSS_FLEX_DIRECTION_ROW]] - - getPosition(currentAbsoluteChild, trailing[CSS_FLEX_DIRECTION_ROW]); - } - - if (isPosDefined(currentAbsoluteChild, trailing[CSS_FLEX_DIRECTION_COLUMN]) && - !isPosDefined(currentAbsoluteChild, leading[CSS_FLEX_DIRECTION_COLUMN])) { - currentAbsoluteChild.layout[leading[CSS_FLEX_DIRECTION_COLUMN]] = - node.layout[measuredDim[CSS_FLEX_DIRECTION_COLUMN]] - - currentAbsoluteChild.layout[measuredDim[CSS_FLEX_DIRECTION_COLUMN]] - - getPosition(currentAbsoluteChild, trailing[CSS_FLEX_DIRECTION_COLUMN]); - } - } - - currentAbsoluteChild = currentAbsoluteChild.nextChild; - } - } - - function canUseCachedMeasurement( - isTextNode, - availableWidth, - availableHeight, - marginRow, - marginColumn, - widthMeasureMode, - heightMeasureMode, - cachedLayout) { - - var isHeightSame = - (cachedLayout.heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED && heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED) || - (cachedLayout.heightMeasureMode == heightMeasureMode && cachedLayout.availableHeight == availableHeight); - - var isWidthSame = - (cachedLayout.widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED && widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED) || - (cachedLayout.widthMeasureMode == widthMeasureMode && cachedLayout.availableWidth == availableWidth); - - if (isHeightSame && isWidthSame) { - return true; - } - - var isHeightValid = - (cachedLayout.heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED && heightMeasureMode == CSS_MEASURE_MODE_AT_MOST && cachedLayout.computedHeight <= (availableHeight - marginColumn)) || - (heightMeasureMode == CSS_MEASURE_MODE_EXACTLY && cachedLayout.computedHeight == (availableHeight - marginColumn)); - - if (isWidthSame && isHeightValid) { - return true; - } - - var isWidthValid = - (cachedLayout.widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED && widthMeasureMode == CSS_MEASURE_MODE_AT_MOST && cachedLayout.computedWidth <= (availableWidth - marginRow)) || - (widthMeasureMode == CSS_MEASURE_MODE_EXACTLY && cachedLayout.computedWidth == (availableWidth - marginRow)); - - if (isHeightSame && isWidthValid) { - return true; - } - - if (isHeightValid && isWidthValid) { - return true; - } - - // We know this to be text so we can apply some more specialized heuristics. - if (isTextNode) { - if (isWidthSame) { - if (heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED) { - // Width is the same and height is not restricted. Re-use cahced value. - return true; - } - - if (heightMeasureMode == CSS_MEASURE_MODE_AT_MOST && - cachedLayout.computedHeight < (availableHeight - marginColumn)) { - // Width is the same and height restriction is greater than the cached height. Re-use cached value. - return true; - } - - // Width is the same but height restriction imposes smaller height than previously measured. - // Update the cached value to respect the new height restriction. - cachedLayout.computedHeight = availableHeight - marginColumn; - return true; - } - - if (cachedLayout.widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED) { - if (widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED || - (widthMeasureMode == CSS_MEASURE_MODE_AT_MOST && - cachedLayout.computedWidth <= (availableWidth - marginRow))) { - // Previsouly this text was measured with no width restriction, if width is now restricted - // but to a larger value than the previsouly measured width we can re-use the measurement - // as we know it will fit. - return true; - } - } - } - - return false; - } - - // - // This is a wrapper around the layoutNodeImpl function. It determines - // whether the layout request is redundant and can be skipped. - // - // Parameters: - // Input parameters are the same as layoutNodeImpl (see above) - // Return parameter is true if layout was performed, false if skipped - // - function layoutNodeInternal(node, availableWidth, availableHeight, parentDirection, - widthMeasureMode, heightMeasureMode, performLayout, reason) { - var layout = node.layout; - - var needToVisitNode = (node.isDirty && layout.generationCount !== gCurrentGenerationCount) || - layout.lastParentDirection !== parentDirection; - - if (needToVisitNode) { - // Invalidate the cached results. - if (layout.cachedMeasurements !== undefined) { - layout.cachedMeasurements = []; - } - if (layout.cachedLayout !== undefined) { - layout.cachedLayout.widthMeasureMode = undefined; - layout.cachedLayout.heightMeasureMode = undefined; - } - } - - var i; - var len; - var cachedResults; - - // Determine whether the results are already cached. We maintain a separate - // cache for layouts and measurements. A layout operation modifies the positions - // and dimensions for nodes in the subtree. The algorithm assumes that each node - // gets layed out a maximum of one time per tree layout, but multiple measurements - // may be required to resolve all of the flex dimensions. - // We handle nodes with measure functions specially here because they are the most - // expensive to measure, so it's worth avoiding redundant measurements if at all possible. - if (isMeasureDefined(node)) { - var marginAxisRow = getMarginAxis(node, CSS_FLEX_DIRECTION_ROW); - var marginAxisColumn = getMarginAxis(node, CSS_FLEX_DIRECTION_COLUMN); - - // First, try to use the layout cache. - if (layout.cachedLayout && - canUseCachedMeasurement(node.isTextNode, availableWidth, availableHeight, marginAxisRow, marginAxisColumn, - widthMeasureMode, heightMeasureMode, layout.cachedLayout)) { - cachedResults = layout.cachedLayout; - } else if (layout.cachedMeasurements) { - // Try to use the measurement cache. - for (i = 0, len = layout.cachedMeasurements.length; i < len; i++) { - if (canUseCachedMeasurement(node.isTextNode, availableWidth, availableHeight, marginAxisRow, marginAxisColumn, - widthMeasureMode, heightMeasureMode, layout.cachedMeasurements[i])) { - cachedResults = layout.cachedMeasurements[i]; - break; - } - } - } - } else if (performLayout) { - if (layout.cachedLayout && - layout.cachedLayout.availableWidth === availableWidth && - layout.cachedLayout.availableHeight === availableHeight && - layout.cachedLayout.widthMeasureMode === widthMeasureMode && - layout.cachedLayout.heightMeasureMode === heightMeasureMode) { - cachedResults = layout.cachedLayout; - } - } else if (layout.cachedMeasurements) { - for (i = 0, len = layout.cachedMeasurements.length; i < len; i++) { - if (layout.cachedMeasurements[i].availableWidth === availableWidth && - layout.cachedMeasurements[i].availableHeight === availableHeight && - layout.cachedMeasurements[i].widthMeasureMode === widthMeasureMode && - layout.cachedMeasurements[i].heightMeasureMode === heightMeasureMode) { - cachedResults = layout.cachedMeasurements[i]; - break; - } - } - } - - if (!needToVisitNode && cachedResults !== undefined) { - layout.measureWidth = cachedResults.computedWidth; - layout.measureHeight = cachedResults.computedHeight; - } else { - layoutNodeImpl(node, availableWidth, availableHeight, parentDirection, widthMeasureMode, heightMeasureMode, performLayout); - layout.lastParentDirection = parentDirection; - - if (cachedResults === undefined) { - var newCacheEntry; - if (performLayout) { - // Use the single layout cache entry. - if (layout.cachedLayout === undefined) { - layout.cachedLayout = {}; - } - newCacheEntry = layout.cachedLayout; - } else { - // Allocate a new measurement cache entry. - if (layout.cachedMeasurements === undefined) { - layout.cachedMeasurements = []; - } - newCacheEntry = {}; - layout.cachedMeasurements.push(newCacheEntry); - } - - newCacheEntry.availableWidth = availableWidth; - newCacheEntry.availableHeight = availableHeight; - newCacheEntry.widthMeasureMode = widthMeasureMode; - newCacheEntry.heightMeasureMode = heightMeasureMode; - newCacheEntry.computedWidth = layout.measuredWidth; - newCacheEntry.computedHeight = layout.measuredHeight; - } - } - - if (performLayout) { - node.layout.width = node.layout.measuredWidth; - node.layout.height = node.layout.measuredHeight; - layout.shouldUpdate = true; - } - - layout.generationCount = gCurrentGenerationCount; - return (needToVisitNode || cachedResults === undefined); - } - - function layoutNode(node, availableWidth, availableHeight, parentDirection) { - // Increment the generation count. This will force the recursive routine to visit - // all dirty nodes at least once. Subsequent visits will be skipped if the input - // parameters don't change. - gCurrentGenerationCount++; - - var widthMeasureMode = CSS_MEASURE_MODE_UNDEFINED; - var heightMeasureMode = CSS_MEASURE_MODE_UNDEFINED; - - if (!isUndefined(availableWidth)) { - widthMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } else if (isStyleDimDefined(node, CSS_FLEX_DIRECTION_ROW)) { - availableWidth = node.style.width + getMarginAxis(node, CSS_FLEX_DIRECTION_ROW); - widthMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } else if (node.style.maxWidth >= 0.0) { - availableWidth = node.style.maxWidth; - widthMeasureMode = CSS_MEASURE_MODE_AT_MOST; - } - - if (!isUndefined(availableHeight)) { - heightMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } else if (isStyleDimDefined(node, CSS_FLEX_DIRECTION_COLUMN)) { - availableHeight = node.style.height + getMarginAxis(node, CSS_FLEX_DIRECTION_COLUMN); - heightMeasureMode = CSS_MEASURE_MODE_EXACTLY; - } else if (node.style.maxHeight >= 0.0) { - availableHeight = node.style.maxHeight; - heightMeasureMode = CSS_MEASURE_MODE_AT_MOST; - } - - if (layoutNodeInternal(node, availableWidth, availableHeight, parentDirection, widthMeasureMode, heightMeasureMode, true, 'initial')) { - setPosition(node, node.layout.direction); - } - } - - return { - layoutNodeImpl: layoutNodeImpl, - computeLayout: layoutNode, - fillNodes: fillNodes, - canUseCachedMeasurement: canUseCachedMeasurement - }; -})(); - -// This module export is only used for the purposes of unit testing this file. When -// the library is packaged this file is included within css-layout.js which forms -// the public API. -if (typeof exports === 'object') { - module.exports = computeLayout; -} diff --git a/java/java/src/com/facebook/csslayout/CSSAlign.java b/java/com/facebook/csslayout/CSSAlign.java similarity index 88% rename from java/java/src/com/facebook/csslayout/CSSAlign.java rename to java/com/facebook/csslayout/CSSAlign.java index f177270f..3e3cb0e9 100644 --- a/java/java/src/com/facebook/csslayout/CSSAlign.java +++ b/java/com/facebook/csslayout/CSSAlign.java @@ -1,11 +1,12 @@ /** - * Copyright (c) 2014, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ + package com.facebook.csslayout; public enum CSSAlign { diff --git a/java/java/src/com/facebook/csslayout/CSSCachedMeasurement.java b/java/com/facebook/csslayout/CSSCachedMeasurement.java similarity index 92% rename from java/java/src/com/facebook/csslayout/CSSCachedMeasurement.java rename to java/com/facebook/csslayout/CSSCachedMeasurement.java index 2ada4cf8..deb1de6a 100644 --- a/java/java/src/com/facebook/csslayout/CSSCachedMeasurement.java +++ b/java/com/facebook/csslayout/CSSCachedMeasurement.java @@ -1,11 +1,12 @@ /** - * Copyright (c) 2014, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ + package com.facebook.csslayout; public class CSSCachedMeasurement { diff --git a/java/java/src/com/facebook/csslayout/CSSConstants.java b/java/com/facebook/csslayout/CSSConstants.java similarity index 91% rename from java/java/src/com/facebook/csslayout/CSSConstants.java rename to java/com/facebook/csslayout/CSSConstants.java index ec0b3f7c..01a0d597 100644 --- a/java/java/src/com/facebook/csslayout/CSSConstants.java +++ b/java/com/facebook/csslayout/CSSConstants.java @@ -1,11 +1,12 @@ /** - * Copyright (c) 2014, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ + package com.facebook.csslayout; public class CSSConstants { diff --git a/java/java/src/com/facebook/csslayout/CSSDirection.java b/java/com/facebook/csslayout/CSSDirection.java similarity index 88% rename from java/java/src/com/facebook/csslayout/CSSDirection.java rename to java/com/facebook/csslayout/CSSDirection.java index 26e93bd6..0c27a929 100644 --- a/java/java/src/com/facebook/csslayout/CSSDirection.java +++ b/java/com/facebook/csslayout/CSSDirection.java @@ -1,11 +1,12 @@ /** - * Copyright (c) 2014, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ + package com.facebook.csslayout; public enum CSSDirection { diff --git a/java/java/src/com/facebook/csslayout/CSSFlexDirection.java b/java/com/facebook/csslayout/CSSFlexDirection.java similarity index 88% rename from java/java/src/com/facebook/csslayout/CSSFlexDirection.java rename to java/com/facebook/csslayout/CSSFlexDirection.java index b5040e25..30f92bd0 100644 --- a/java/java/src/com/facebook/csslayout/CSSFlexDirection.java +++ b/java/com/facebook/csslayout/CSSFlexDirection.java @@ -1,11 +1,12 @@ /** - * Copyright (c) 2014, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ + package com.facebook.csslayout; public enum CSSFlexDirection { diff --git a/java/java/src/com/facebook/csslayout/CSSJustify.java b/java/com/facebook/csslayout/CSSJustify.java similarity index 89% rename from java/java/src/com/facebook/csslayout/CSSJustify.java rename to java/com/facebook/csslayout/CSSJustify.java index 371b38cb..dfcc1cd2 100644 --- a/java/java/src/com/facebook/csslayout/CSSJustify.java +++ b/java/com/facebook/csslayout/CSSJustify.java @@ -1,11 +1,12 @@ /** - * Copyright (c) 2014, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ + package com.facebook.csslayout; public enum CSSJustify { diff --git a/java/java/src/com/facebook/csslayout/CSSLayout.java b/java/com/facebook/csslayout/CSSLayout.java similarity index 98% rename from java/java/src/com/facebook/csslayout/CSSLayout.java rename to java/com/facebook/csslayout/CSSLayout.java index 18e55d2c..ed2b8249 100644 --- a/java/java/src/com/facebook/csslayout/CSSLayout.java +++ b/java/com/facebook/csslayout/CSSLayout.java @@ -1,11 +1,12 @@ /** - * Copyright (c) 2014, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ + package com.facebook.csslayout; import java.util.Arrays; diff --git a/java/java/src/com/facebook/csslayout/CSSLayoutContext.java b/java/com/facebook/csslayout/CSSLayoutContext.java similarity index 93% rename from java/java/src/com/facebook/csslayout/CSSLayoutContext.java rename to java/com/facebook/csslayout/CSSLayoutContext.java index 64612e3a..70a9c886 100644 --- a/java/java/src/com/facebook/csslayout/CSSLayoutContext.java +++ b/java/com/facebook/csslayout/CSSLayoutContext.java @@ -1,11 +1,12 @@ /** - * Copyright (c) 2014, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ + package com.facebook.csslayout; /** diff --git a/java/java/src/com/facebook/csslayout/CSSMeasureMode.java b/java/com/facebook/csslayout/CSSMeasureMode.java similarity index 88% rename from java/java/src/com/facebook/csslayout/CSSMeasureMode.java rename to java/com/facebook/csslayout/CSSMeasureMode.java index eb327b33..e8ebb34f 100644 --- a/java/java/src/com/facebook/csslayout/CSSMeasureMode.java +++ b/java/com/facebook/csslayout/CSSMeasureMode.java @@ -1,11 +1,12 @@ /** - * Copyright (c) 2014, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ + package com.facebook.csslayout; public enum CSSMeasureMode { diff --git a/java/java/src/com/facebook/csslayout/CSSNode.java b/java/com/facebook/csslayout/CSSNode.java similarity index 99% rename from java/java/src/com/facebook/csslayout/CSSNode.java rename to java/com/facebook/csslayout/CSSNode.java index 454aa6d7..6bb7cf66 100644 --- a/java/java/src/com/facebook/csslayout/CSSNode.java +++ b/java/com/facebook/csslayout/CSSNode.java @@ -1,11 +1,12 @@ /** - * Copyright (c) 2014, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ + package com.facebook.csslayout; import javax.annotation.Nullable; diff --git a/java/java/src/com/facebook/csslayout/CSSOverflow.java b/java/com/facebook/csslayout/CSSOverflow.java similarity index 88% rename from java/java/src/com/facebook/csslayout/CSSOverflow.java rename to java/com/facebook/csslayout/CSSOverflow.java index d8201a37..29957a9a 100644 --- a/java/java/src/com/facebook/csslayout/CSSOverflow.java +++ b/java/com/facebook/csslayout/CSSOverflow.java @@ -1,11 +1,12 @@ /** - * Copyright (c) 2014, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ + package com.facebook.csslayout; public enum CSSOverflow { diff --git a/java/java/src/com/facebook/csslayout/CSSPositionType.java b/java/com/facebook/csslayout/CSSPositionType.java similarity index 88% rename from java/java/src/com/facebook/csslayout/CSSPositionType.java rename to java/com/facebook/csslayout/CSSPositionType.java index 6dca2dc3..19e27dd4 100644 --- a/java/java/src/com/facebook/csslayout/CSSPositionType.java +++ b/java/com/facebook/csslayout/CSSPositionType.java @@ -1,11 +1,12 @@ /** - * Copyright (c) 2014, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ + package com.facebook.csslayout; public enum CSSPositionType { diff --git a/java/java/src/com/facebook/csslayout/CSSStyle.java b/java/com/facebook/csslayout/CSSStyle.java similarity index 97% rename from java/java/src/com/facebook/csslayout/CSSStyle.java rename to java/com/facebook/csslayout/CSSStyle.java index ccb79265..8c86149e 100644 --- a/java/java/src/com/facebook/csslayout/CSSStyle.java +++ b/java/com/facebook/csslayout/CSSStyle.java @@ -1,11 +1,12 @@ /** - * Copyright (c) 2014, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ + package com.facebook.csslayout; import java.util.Arrays; diff --git a/java/java/src/com/facebook/csslayout/CSSWrap.java b/java/com/facebook/csslayout/CSSWrap.java similarity index 87% rename from java/java/src/com/facebook/csslayout/CSSWrap.java rename to java/com/facebook/csslayout/CSSWrap.java index 581481a4..895bb5d5 100644 --- a/java/java/src/com/facebook/csslayout/CSSWrap.java +++ b/java/com/facebook/csslayout/CSSWrap.java @@ -1,11 +1,12 @@ /** - * Copyright (c) 2014, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ + package com.facebook.csslayout; public enum CSSWrap { diff --git a/java/java/src/com/facebook/csslayout/CachedCSSLayout.java b/java/com/facebook/csslayout/CachedCSSLayout.java similarity index 94% rename from java/java/src/com/facebook/csslayout/CachedCSSLayout.java rename to java/com/facebook/csslayout/CachedCSSLayout.java index e5393ef6..a012a5ba 100644 --- a/java/java/src/com/facebook/csslayout/CachedCSSLayout.java +++ b/java/com/facebook/csslayout/CachedCSSLayout.java @@ -1,11 +1,12 @@ /** - * Copyright (c) 2014, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ + package com.facebook.csslayout; /** diff --git a/java/java/src/com/facebook/csslayout/FloatUtil.java b/java/com/facebook/csslayout/FloatUtil.java similarity index 92% rename from java/java/src/com/facebook/csslayout/FloatUtil.java rename to java/com/facebook/csslayout/FloatUtil.java index 37dd007b..8b211e8d 100644 --- a/java/java/src/com/facebook/csslayout/FloatUtil.java +++ b/java/com/facebook/csslayout/FloatUtil.java @@ -1,11 +1,12 @@ /** - * Copyright (c) 2014, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ + package com.facebook.csslayout; public class FloatUtil { diff --git a/java/java/src/com/facebook/csslayout/LayoutEngine.java b/java/com/facebook/csslayout/LayoutEngine.java similarity index 99% rename from java/java/src/com/facebook/csslayout/LayoutEngine.java rename to java/com/facebook/csslayout/LayoutEngine.java index 7649f0b2..bb8e90b6 100644 --- a/java/java/src/com/facebook/csslayout/LayoutEngine.java +++ b/java/com/facebook/csslayout/LayoutEngine.java @@ -1,11 +1,12 @@ /** - * Copyright (c) 2014, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ + package com.facebook.csslayout; import com.facebook.infer.annotation.Assertions; @@ -551,47 +552,46 @@ public class LayoutEngine { CSSMeasureMode widthMeasureMode, CSSMeasureMode heightMeasureMode, boolean performLayout) { - /** START_GENERATED **/ - + Assertions.assertCondition(Float.isNaN(availableWidth) ? widthMeasureMode == CSSMeasureMode.UNDEFINED : true, "availableWidth is indefinite so widthMeasureMode must be CSSMeasureMode.UNDEFINED"); Assertions.assertCondition(Float.isNaN(availableHeight) ? heightMeasureMode == CSSMeasureMode.UNDEFINED : true, "availableHeight is indefinite so heightMeasureMode must be CSSMeasureMode.UNDEFINED"); - + float paddingAndBorderAxisRow = ((node.style.padding.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_ROW], leading[CSS_FLEX_DIRECTION_ROW]) + node.style.border.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_ROW], leading[CSS_FLEX_DIRECTION_ROW])) + (node.style.padding.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_ROW], trailing[CSS_FLEX_DIRECTION_ROW]) + node.style.border.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_ROW], trailing[CSS_FLEX_DIRECTION_ROW]))); float paddingAndBorderAxisColumn = ((node.style.padding.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + node.style.border.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN])) + (node.style.padding.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN]) + node.style.border.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN]))); float marginAxisRow = (node.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_ROW], leading[CSS_FLEX_DIRECTION_ROW]) + node.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_ROW], trailing[CSS_FLEX_DIRECTION_ROW])); float marginAxisColumn = (node.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + node.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN])); - + // Set the resolved resolution in the node's layout. CSSDirection direction = resolveDirection(node, parentDirection); node.layout.direction = direction; - + // For content (text) nodes, determine the dimensions based on the text contents. if (isMeasureDefined(node)) { float innerWidth = availableWidth - marginAxisRow - paddingAndBorderAxisRow; float innerHeight = availableHeight - marginAxisColumn - paddingAndBorderAxisColumn; - + if (widthMeasureMode == CSSMeasureMode.EXACTLY && heightMeasureMode == CSSMeasureMode.EXACTLY) { - + // Don't bother sizing the text if both dimensions are already defined. node.layout.measuredDimensions[DIMENSION_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, availableWidth - marginAxisRow); node.layout.measuredDimensions[DIMENSION_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, availableHeight - marginAxisColumn); } else if (innerWidth <= 0 || innerHeight <= 0) { - + // Don't bother sizing the text if there's no horizontal or vertical space. node.layout.measuredDimensions[DIMENSION_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, 0); node.layout.measuredDimensions[DIMENSION_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, 0); } else { - + // Measure the text under the current constraints. MeasureOutput measureDim = node.measure( - + layoutContext.measureOutput, innerWidth, widthMeasureMode, innerHeight, heightMeasureMode ); - + node.layout.measuredDimensions[DIMENSION_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, (widthMeasureMode == CSSMeasureMode.UNDEFINED || widthMeasureMode == CSSMeasureMode.AT_MOST) ? measureDim.width + paddingAndBorderAxisRow : @@ -601,10 +601,10 @@ public class LayoutEngine { measureDim.height + paddingAndBorderAxisColumn : availableHeight - marginAxisColumn); } - + return; } - + // For nodes with no children, use the available values if they were provided, or // the minimum size as indicated by the padding and border sizes. int childCount = node.getChildCount(); @@ -619,7 +619,7 @@ public class LayoutEngine { availableHeight - marginAxisColumn); return; } - + // If we're not being asked to perform a full layout, we can handle a number of common // cases here without incurring the cost of the remaining function. if (!performLayout) { @@ -631,19 +631,19 @@ public class LayoutEngine { node.layout.measuredDimensions[DIMENSION_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, 0); return; } - + if (widthMeasureMode == CSSMeasureMode.AT_MOST && availableWidth <= 0) { node.layout.measuredDimensions[DIMENSION_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, 0); node.layout.measuredDimensions[DIMENSION_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, Float.isNaN(availableHeight) ? 0 : (availableHeight - marginAxisColumn)); return; } - + if (heightMeasureMode == CSSMeasureMode.AT_MOST && availableHeight <= 0) { node.layout.measuredDimensions[DIMENSION_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, Float.isNaN(availableWidth) ? 0 : (availableWidth - marginAxisRow)); node.layout.measuredDimensions[DIMENSION_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, 0); return; } - + // If we're being asked to use an exact width/height, there's no need to measure the children. if (widthMeasureMode == CSSMeasureMode.EXACTLY && heightMeasureMode == CSSMeasureMode.EXACTLY) { node.layout.measuredDimensions[DIMENSION_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, availableWidth - marginAxisRow); @@ -651,32 +651,32 @@ public class LayoutEngine { return; } } - + // STEP 1: CALCULATE VALUES FOR REMAINDER OF ALGORITHM int mainAxis = resolveAxis(getFlexDirection(node), direction); int crossAxis = getCrossFlexDirection(mainAxis, direction); boolean isMainAxisRow = (mainAxis == CSS_FLEX_DIRECTION_ROW || mainAxis == CSS_FLEX_DIRECTION_ROW_REVERSE); CSSJustify justifyContent = node.style.justifyContent; boolean isNodeFlexWrap = (node.style.flexWrap == CSSWrap.WRAP); - + CSSNode firstAbsoluteChild = null; CSSNode currentAbsoluteChild = null; - + float leadingPaddingAndBorderMain = (node.style.padding.getWithFallback(leadingSpacing[mainAxis], leading[mainAxis]) + node.style.border.getWithFallback(leadingSpacing[mainAxis], leading[mainAxis])); float trailingPaddingAndBorderMain = (node.style.padding.getWithFallback(trailingSpacing[mainAxis], trailing[mainAxis]) + node.style.border.getWithFallback(trailingSpacing[mainAxis], trailing[mainAxis])); float leadingPaddingAndBorderCross = (node.style.padding.getWithFallback(leadingSpacing[crossAxis], leading[crossAxis]) + node.style.border.getWithFallback(leadingSpacing[crossAxis], leading[crossAxis])); float paddingAndBorderAxisMain = ((node.style.padding.getWithFallback(leadingSpacing[mainAxis], leading[mainAxis]) + node.style.border.getWithFallback(leadingSpacing[mainAxis], leading[mainAxis])) + (node.style.padding.getWithFallback(trailingSpacing[mainAxis], trailing[mainAxis]) + node.style.border.getWithFallback(trailingSpacing[mainAxis], trailing[mainAxis]))); float paddingAndBorderAxisCross = ((node.style.padding.getWithFallback(leadingSpacing[crossAxis], leading[crossAxis]) + node.style.border.getWithFallback(leadingSpacing[crossAxis], leading[crossAxis])) + (node.style.padding.getWithFallback(trailingSpacing[crossAxis], trailing[crossAxis]) + node.style.border.getWithFallback(trailingSpacing[crossAxis], trailing[crossAxis]))); - + CSSMeasureMode measureModeMainDim = isMainAxisRow ? widthMeasureMode : heightMeasureMode; CSSMeasureMode measureModeCrossDim = isMainAxisRow ? heightMeasureMode : widthMeasureMode; - + // STEP 2: DETERMINE AVAILABLE SIZE IN MAIN AND CROSS DIRECTIONS float availableInnerWidth = availableWidth - marginAxisRow - paddingAndBorderAxisRow; float availableInnerHeight = availableHeight - marginAxisColumn - paddingAndBorderAxisColumn; float availableInnerMainDim = isMainAxisRow ? availableInnerWidth : availableInnerHeight; float availableInnerCrossDim = isMainAxisRow ? availableInnerHeight : availableInnerWidth; - + // STEP 3: DETERMINE FLEX BASIS FOR EACH ITEM CSSNode child; int i; @@ -686,17 +686,17 @@ public class LayoutEngine { CSSMeasureMode childHeightMeasureMode; for (i = 0; i < childCount; i++) { child = node.getChildAt(i); - + if (performLayout) { // Set the initial position (relative to the parent). CSSDirection childDirection = resolveDirection(child, direction); setPosition(child, childDirection); } - + // Absolute-positioned children don't participate in flex layout. Add them // to a list that we can process later. if (child.style.positionType == CSSPositionType.ABSOLUTE) { - + // Store a private linked list of absolutely positioned children // so that we can efficiently traverse them later. if (firstAbsoluteChild == null) { @@ -708,27 +708,27 @@ public class LayoutEngine { currentAbsoluteChild = child; child.nextChild = null; } else { - + if (isMainAxisRow && (child.style.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] >= 0.0)) { - + // The width is definite, so use that as the flex basis. child.layout.flexBasis = Math.max(child.style.dimensions[DIMENSION_WIDTH], ((child.style.padding.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_ROW], leading[CSS_FLEX_DIRECTION_ROW]) + child.style.border.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_ROW], leading[CSS_FLEX_DIRECTION_ROW])) + (child.style.padding.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_ROW], trailing[CSS_FLEX_DIRECTION_ROW]) + child.style.border.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_ROW], trailing[CSS_FLEX_DIRECTION_ROW])))); } else if (!isMainAxisRow && (child.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0)) { - + // The height is definite, so use that as the flex basis. child.layout.flexBasis = Math.max(child.style.dimensions[DIMENSION_HEIGHT], ((child.style.padding.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + child.style.border.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN])) + (child.style.padding.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN]) + child.style.border.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN])))); } else if (!isFlexBasisAuto(child) && !Float.isNaN(availableInnerMainDim)) { - + // If the basis isn't 'auto', it is assumed to be zero. child.layout.flexBasis = Math.max(0, ((child.style.padding.getWithFallback(leadingSpacing[mainAxis], leading[mainAxis]) + child.style.border.getWithFallback(leadingSpacing[mainAxis], leading[mainAxis])) + (child.style.padding.getWithFallback(trailingSpacing[mainAxis], trailing[mainAxis]) + child.style.border.getWithFallback(trailingSpacing[mainAxis], trailing[mainAxis])))); } else { - + // Compute the flex basis and hypothetical main size (i.e. the clamped flex basis). childWidth = CSSConstants.UNDEFINED; childHeight = CSSConstants.UNDEFINED; childWidthMeasureMode = CSSMeasureMode.UNDEFINED; childHeightMeasureMode = CSSMeasureMode.UNDEFINED; - + if ((child.style.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] >= 0.0)) { childWidth = child.style.dimensions[DIMENSION_WIDTH] + (child.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_ROW], leading[CSS_FLEX_DIRECTION_ROW]) + child.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_ROW], trailing[CSS_FLEX_DIRECTION_ROW])); childWidthMeasureMode = CSSMeasureMode.EXACTLY; @@ -737,7 +737,7 @@ public class LayoutEngine { childHeight = child.style.dimensions[DIMENSION_HEIGHT] + (child.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + child.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN])); childHeightMeasureMode = CSSMeasureMode.EXACTLY; } - + // According to the spec, if the main size is not definite and the // child's inline axis is parallel to the main axis (i.e. it's // horizontal), the child should be sized using "UNDEFINED" in @@ -746,7 +746,7 @@ public class LayoutEngine { childWidth = availableInnerWidth; childWidthMeasureMode = CSSMeasureMode.AT_MOST; } - + // The W3C spec doesn't say anything about the 'overflow' property, // but all major browsers appear to implement the following logic. if (node.style.overflow == CSSOverflow.HIDDEN) { @@ -755,7 +755,7 @@ public class LayoutEngine { childHeightMeasureMode = CSSMeasureMode.AT_MOST; } } - + // If child has no defined size in the cross axis and is set to stretch, set the cross // axis to be measured exactly with the available inner width if (!isMainAxisRow && @@ -774,76 +774,76 @@ public class LayoutEngine { childHeight = availableInnerHeight; childHeightMeasureMode = CSSMeasureMode.EXACTLY; } - + // Measure the child layoutNodeInternal(layoutContext, child, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, false, "measure"); - + child.layout.flexBasis = Math.max(isMainAxisRow ? child.layout.measuredDimensions[DIMENSION_WIDTH] : child.layout.measuredDimensions[DIMENSION_HEIGHT], ((child.style.padding.getWithFallback(leadingSpacing[mainAxis], leading[mainAxis]) + child.style.border.getWithFallback(leadingSpacing[mainAxis], leading[mainAxis])) + (child.style.padding.getWithFallback(trailingSpacing[mainAxis], trailing[mainAxis]) + child.style.border.getWithFallback(trailingSpacing[mainAxis], trailing[mainAxis])))); } } } - + // STEP 4: COLLECT FLEX ITEMS INTO FLEX LINES - + // Indexes of children that represent the first and last items in the line. int startOfLineIndex = 0; int endOfLineIndex = 0; - + // Number of lines. int lineCount = 0; - + // Accumulated cross dimensions of all lines so far. float totalLineCrossDim = 0; - + // Max main dimension of all the lines. float maxLineMainDim = 0; - + while (endOfLineIndex < childCount) { - + // Number of items on the currently line. May be different than the difference // between start and end indicates because we skip over absolute-positioned items. int itemsOnLine = 0; - + // sizeConsumedOnCurrentLine is accumulation of the dimensions and margin // of all the children on the current line. 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 sizeConsumedOnCurrentLine = 0; - + float totalFlexGrowFactors = 0; float totalFlexShrinkScaledFactors = 0; - + i = startOfLineIndex; - + // Maintain a linked list of the child nodes that can shrink and/or grow. CSSNode firstRelativeChild = null; CSSNode currentRelativeChild = null; - + // Add items to the current line until it's full or we run out of items. while (i < childCount) { child = node.getChildAt(i); child.lineIndex = lineCount; - + if (child.style.positionType != CSSPositionType.ABSOLUTE) { float outerFlexBasis = child.layout.flexBasis + (child.style.margin.getWithFallback(leadingSpacing[mainAxis], leading[mainAxis]) + child.style.margin.getWithFallback(trailingSpacing[mainAxis], trailing[mainAxis])); - + // If this is a multi-line flow and this item pushes us over the available size, we've // hit the end of the current line. Break out of the loop and lay out the current line. if (sizeConsumedOnCurrentLine + outerFlexBasis > availableInnerMainDim && isNodeFlexWrap && itemsOnLine > 0) { break; } - + sizeConsumedOnCurrentLine += outerFlexBasis; itemsOnLine++; - + if ((child.style.positionType == CSSPositionType.RELATIVE && child.style.flex != 0)) { totalFlexGrowFactors += getFlexGrowFactor(child); - + // Unlike the grow factor, the shrink factor is scaled relative to the child // dimension. totalFlexShrinkScaledFactors += getFlexShrinkFactor(child) * child.layout.flexBasis; } - + // Store a private linked list of children that need to be layed out. if (firstRelativeChild == null) { firstRelativeChild = child; @@ -854,20 +854,20 @@ public class LayoutEngine { currentRelativeChild = child; child.nextChild = null; } - + i++; endOfLineIndex++; } - + // If we don't need to measure the cross axis, we can skip the entire flex step. boolean canSkipFlex = !performLayout && measureModeCrossDim == CSSMeasureMode.EXACTLY; - + // 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; - + // STEP 5: RESOLVING FLEXIBLE LENGTHS ON MAIN AXIS // Calculate the remaining available space that needs to be allocated. // If the main dimension size isn't known, it is computed based on @@ -881,17 +881,17 @@ public class LayoutEngine { // its content. Consequently, remainingFreeSpace is 0 - sizeConsumedOnCurrentLine. remainingFreeSpace = -sizeConsumedOnCurrentLine; } - + float originalRemainingFreeSpace = remainingFreeSpace; float deltaFreeSpace = 0; - + if (!canSkipFlex) { float childFlexBasis; float flexShrinkScaledFactor; float flexGrowFactor; float baseMainSize; float boundMainSize; - + // Do two passes over the flex items to figure out how to distribute the remaining space. // The first pass finds the items whose min/max constraints trigger, freezes them at those // sizes, and excludes those sizes from the remaining space. The second pass sets the size @@ -904,17 +904,17 @@ public class LayoutEngine { // that needs to be repeated a variable number of times. The algorithm implemented here // won't handle all cases but it was simpler to implement and it mitigates performance // concerns because we know exactly how many passes it'll do. - + // First pass: detect the flex items whose min/max constraints trigger float deltaFlexShrinkScaledFactors = 0; float deltaFlexGrowFactors = 0; currentRelativeChild = firstRelativeChild; while (currentRelativeChild != null) { childFlexBasis = currentRelativeChild.layout.flexBasis; - + if (remainingFreeSpace < 0) { flexShrinkScaledFactor = getFlexShrinkFactor(currentRelativeChild) * childFlexBasis; - + // Is this child able to shrink? if (flexShrinkScaledFactor != 0) { baseMainSize = childFlexBasis + @@ -930,7 +930,7 @@ public class LayoutEngine { } } else if (remainingFreeSpace > 0) { flexGrowFactor = getFlexGrowFactor(currentRelativeChild); - + // Is this child able to grow? if (flexGrowFactor != 0) { baseMainSize = childFlexBasis + @@ -945,24 +945,24 @@ public class LayoutEngine { } } } - + currentRelativeChild = currentRelativeChild.nextChild; } - + totalFlexShrinkScaledFactors += deltaFlexShrinkScaledFactors; totalFlexGrowFactors += deltaFlexGrowFactors; remainingFreeSpace += deltaFreeSpace; - + // Second pass: resolve the sizes of the flexible items deltaFreeSpace = 0; currentRelativeChild = firstRelativeChild; while (currentRelativeChild != null) { childFlexBasis = currentRelativeChild.layout.flexBasis; float updatedMainSize = childFlexBasis; - + if (remainingFreeSpace < 0) { flexShrinkScaledFactor = getFlexShrinkFactor(currentRelativeChild) * childFlexBasis; - + // Is this child able to shrink? if (flexShrinkScaledFactor != 0) { updatedMainSize = boundAxis(currentRelativeChild, mainAxis, childFlexBasis + @@ -970,20 +970,20 @@ public class LayoutEngine { } } else if (remainingFreeSpace > 0) { flexGrowFactor = getFlexGrowFactor(currentRelativeChild); - + // Is this child able to grow? if (flexGrowFactor != 0) { updatedMainSize = boundAxis(currentRelativeChild, mainAxis, childFlexBasis + remainingFreeSpace / totalFlexGrowFactors * flexGrowFactor); } } - + deltaFreeSpace -= updatedMainSize - childFlexBasis; - + if (isMainAxisRow) { childWidth = updatedMainSize + (currentRelativeChild.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_ROW], leading[CSS_FLEX_DIRECTION_ROW]) + currentRelativeChild.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_ROW], trailing[CSS_FLEX_DIRECTION_ROW])); childWidthMeasureMode = CSSMeasureMode.EXACTLY; - + if (!Float.isNaN(availableInnerCrossDim) && !(currentRelativeChild.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0) && heightMeasureMode == CSSMeasureMode.EXACTLY && @@ -1000,7 +1000,7 @@ public class LayoutEngine { } else { childHeight = updatedMainSize + (currentRelativeChild.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + currentRelativeChild.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN])); childHeightMeasureMode = CSSMeasureMode.EXACTLY; - + if (!Float.isNaN(availableInnerCrossDim) && !(currentRelativeChild.style.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] >= 0.0) && widthMeasureMode == CSSMeasureMode.EXACTLY && @@ -1015,32 +1015,32 @@ public class LayoutEngine { childWidthMeasureMode = CSSMeasureMode.EXACTLY; } } - + boolean requiresStretchLayout = !(currentRelativeChild.style.dimensions[dim[crossAxis]] >= 0.0) && getAlignItem(node, currentRelativeChild) == CSSAlign.STRETCH; - + // Recursively call the layout algorithm for this child with the updated main size. layoutNodeInternal(layoutContext, currentRelativeChild, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, performLayout && !requiresStretchLayout, "flex"); - + currentRelativeChild = currentRelativeChild.nextChild; } } - + remainingFreeSpace = originalRemainingFreeSpace + deltaFreeSpace; - + // STEP 6: MAIN-AXIS JUSTIFICATION & CROSS-AXIS SIZE DETERMINATION - + // At this point, all the children have their dimensions set in the main axis. // Their dimensions are also set in the cross axis with the exception of items // that are aligned "stretch". We need to compute these stretch values and // set the final positions. - + // If we are using "at most" rules in the main axis, we won't distribute // any remaining space at this point. if (measureModeMainDim == CSSMeasureMode.AT_MOST) { remainingFreeSpace = 0; } - + // Use justifyContent to figure out how to allocate the remaining space // available in the main axis. if (justifyContent != CSSJustify.FLEX_START) { @@ -1061,13 +1061,13 @@ public class LayoutEngine { leadingMainDim = betweenMainDim / 2; } } - + float mainDim = leadingPaddingAndBorderMain + leadingMainDim; float crossDim = 0; - + for (i = startOfLineIndex; i < endOfLineIndex; ++i) { child = node.getChildAt(i); - + if (child.style.positionType == CSSPositionType.ABSOLUTE && !Float.isNaN(child.style.position[leading[mainAxis]])) { if (performLayout) { @@ -1084,7 +1084,7 @@ public class LayoutEngine { // we put it at the current accumulated offset. child.layout.position[pos[mainAxis]] += mainDim; } - + // Now that we placed the element, we need to update the variables. // We need to do that only for relative elements. Absolute elements // do not take part in that phase. @@ -1098,7 +1098,7 @@ public class LayoutEngine { // The main dimension is the sum of all the elements dimension plus // the spacing. mainDim += betweenMainDim + (child.layout.measuredDimensions[dim[mainAxis]] + child.style.margin.getWithFallback(leadingSpacing[mainAxis], leading[mainAxis]) + child.style.margin.getWithFallback(trailingSpacing[mainAxis], trailing[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, (child.layout.measuredDimensions[dim[crossAxis]] + child.style.margin.getWithFallback(leadingSpacing[crossAxis], leading[crossAxis]) + child.style.margin.getWithFallback(trailingSpacing[crossAxis], trailing[crossAxis]))); @@ -1106,33 +1106,33 @@ public class LayoutEngine { } } } - + mainDim += trailingPaddingAndBorderMain; - + float containerCrossAxis = availableInnerCrossDim; if (measureModeCrossDim == CSSMeasureMode.UNDEFINED || measureModeCrossDim == CSSMeasureMode.AT_MOST) { // Compute the cross axis from the max cross dimension of the children. containerCrossAxis = boundAxis(node, crossAxis, crossDim + paddingAndBorderAxisCross) - paddingAndBorderAxisCross; - + if (measureModeCrossDim == CSSMeasureMode.AT_MOST) { containerCrossAxis = Math.min(containerCrossAxis, availableInnerCrossDim); } } - + // If there's no flex wrap, the cross dimension is defined by the container. if (!isNodeFlexWrap && measureModeCrossDim == CSSMeasureMode.EXACTLY) { crossDim = availableInnerCrossDim; } - + // Clamp to the min/max size specified on the container. crossDim = boundAxis(node, crossAxis, crossDim + paddingAndBorderAxisCross) - paddingAndBorderAxisCross; - + // STEP 7: CROSS-AXIS ALIGNMENT // We can skip child alignment if we're just measuring the container. if (performLayout) { for (i = startOfLineIndex; i < endOfLineIndex; ++i) { child = node.getChildAt(i); - + if (child.style.positionType == CSSPositionType.ABSOLUTE) { // If the child is absolutely positioned and has a top/left/bottom/right // set, override all the previously computed positions to set it correctly. @@ -1146,18 +1146,18 @@ public class LayoutEngine { } } else { float leadingCrossDim = leadingPaddingAndBorderCross; - + // For a relative children, we're either using alignItems (parent) or // alignSelf (child) in order to determine the position in the cross axis CSSAlign alignItem = getAlignItem(node, child); - + // If the child uses align stretch, we need to lay it out one more time, this time // forcing the cross-axis size to be the computed cross size for the current line. if (alignItem == CSSAlign.STRETCH) { childWidth = child.layout.measuredDimensions[DIMENSION_WIDTH] + (child.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_ROW], leading[CSS_FLEX_DIRECTION_ROW]) + child.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_ROW], trailing[CSS_FLEX_DIRECTION_ROW])); childHeight = child.layout.measuredDimensions[DIMENSION_HEIGHT] + (child.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + child.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN])); boolean isCrossSizeDefinite = false; - + if (isMainAxisRow) { isCrossSizeDefinite = (child.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0); childHeight = crossDim; @@ -1165,7 +1165,7 @@ public class LayoutEngine { isCrossSizeDefinite = (child.style.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] >= 0.0); childWidth = crossDim; } - + // If the child defines a definite size for its cross axis, there's no need to stretch. if (!isCrossSizeDefinite) { childWidthMeasureMode = Float.isNaN(childWidth) ? CSSMeasureMode.UNDEFINED : CSSMeasureMode.EXACTLY; @@ -1174,36 +1174,36 @@ public class LayoutEngine { } } else if (alignItem != CSSAlign.FLEX_START) { float remainingCrossDim = containerCrossAxis - (child.layout.measuredDimensions[dim[crossAxis]] + child.style.margin.getWithFallback(leadingSpacing[crossAxis], leading[crossAxis]) + child.style.margin.getWithFallback(trailingSpacing[crossAxis], trailing[crossAxis])); - + if (alignItem == CSSAlign.CENTER) { leadingCrossDim += remainingCrossDim / 2; } else { // CSSAlign.FLEX_END leadingCrossDim += remainingCrossDim; } } - + // And we apply the position child.layout.position[pos[crossAxis]] += totalLineCrossDim + leadingCrossDim; } } } - + totalLineCrossDim += crossDim; maxLineMainDim = Math.max(maxLineMainDim, mainDim); - + // Reset variables for new line. lineCount++; startOfLineIndex = endOfLineIndex; endOfLineIndex = startOfLineIndex; } - + // STEP 8: MULTI-LINE CONTENT ALIGNMENT if (lineCount > 1 && performLayout && !Float.isNaN(availableInnerCrossDim)) { float remainingAlignContentDim = availableInnerCrossDim - totalLineCrossDim; - + float crossDimLead = 0; float currentLead = leadingPaddingAndBorderCross; - + CSSAlign alignContent = node.style.alignContent; if (alignContent == CSSAlign.FLEX_END) { currentLead += remainingAlignContentDim; @@ -1214,12 +1214,12 @@ public class LayoutEngine { crossDimLead = (remainingAlignContentDim / lineCount); } } - + int endIndex = 0; for (i = 0; i < lineCount; ++i) { int startIndex = endIndex; int j; - + // compute the line's height and find the endIndex float lineHeight = 0; for (j = startIndex; j < childCount; ++j) { @@ -1237,14 +1237,14 @@ public class LayoutEngine { } endIndex = j; lineHeight += crossDimLead; - + if (performLayout) { for (j = startIndex; j < endIndex; ++j) { child = node.getChildAt(j); if (child.style.positionType != CSSPositionType.RELATIVE) { continue; } - + CSSAlign alignContentAlignItem = getAlignItem(node, child); if (alignContentAlignItem == CSSAlign.FLEX_START) { child.layout.position[pos[crossAxis]] = currentLead + child.style.margin.getWithFallback(leadingSpacing[crossAxis], leading[crossAxis]); @@ -1260,15 +1260,15 @@ public class LayoutEngine { } } } - + currentLead += lineHeight; } } - + // STEP 9: COMPUTING FINAL DIMENSIONS node.layout.measuredDimensions[DIMENSION_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, availableWidth - marginAxisRow); node.layout.measuredDimensions[DIMENSION_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, availableHeight - marginAxisColumn); - + // If the user didn't specify a width or height for the node, set the // dimensions based on the children. if (measureModeMainDim == CSSMeasureMode.UNDEFINED) { @@ -1281,7 +1281,7 @@ public class LayoutEngine { boundAxisWithinMinAndMax(node, mainAxis, maxLineMainDim)), paddingAndBorderAxisMain); } - + if (measureModeCrossDim == CSSMeasureMode.UNDEFINED) { // Clamp the size to the min/max size, if specified, and make sure it // doesn't go below the padding and border amount. @@ -1292,48 +1292,48 @@ public class LayoutEngine { boundAxisWithinMinAndMax(node, crossAxis, totalLineCrossDim + paddingAndBorderAxisCross)), paddingAndBorderAxisCross); } - + // STEP 10: SETTING TRAILING POSITIONS FOR CHILDREN if (performLayout) { boolean needsMainTrailingPos = false; boolean needsCrossTrailingPos = false; - + if (mainAxis == CSS_FLEX_DIRECTION_ROW_REVERSE || mainAxis == CSS_FLEX_DIRECTION_COLUMN_REVERSE) { needsMainTrailingPos = true; } - + if (crossAxis == CSS_FLEX_DIRECTION_ROW_REVERSE || crossAxis == CSS_FLEX_DIRECTION_COLUMN_REVERSE) { needsCrossTrailingPos = true; } - + // Set trailing position if necessary. if (needsMainTrailingPos || needsCrossTrailingPos) { for (i = 0; i < childCount; ++i) { child = node.getChildAt(i); - + if (needsMainTrailingPos) { child.layout.position[trailing[mainAxis]] = node.layout.measuredDimensions[dim[mainAxis]] - (child.style.positionType == CSSPositionType.ABSOLUTE ? 0 : child.layout.measuredDimensions[dim[mainAxis]]) - child.layout.position[pos[mainAxis]]; } - + if (needsCrossTrailingPos) { child.layout.position[trailing[crossAxis]] = node.layout.measuredDimensions[dim[crossAxis]] - (child.style.positionType == CSSPositionType.ABSOLUTE ? 0 : child.layout.measuredDimensions[dim[crossAxis]]) - child.layout.position[pos[crossAxis]]; } } } } - + // STEP 11: SIZING AND POSITIONING ABSOLUTE CHILDREN currentAbsoluteChild = firstAbsoluteChild; while (currentAbsoluteChild != null) { // Now that we know the bounds of the container, perform layout again on the // absolutely-positioned children. if (performLayout) { - + childWidth = CSSConstants.UNDEFINED; childHeight = CSSConstants.UNDEFINED; - + if ((currentAbsoluteChild.style.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] >= 0.0)) { childWidth = currentAbsoluteChild.style.dimensions[DIMENSION_WIDTH] + (currentAbsoluteChild.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_ROW], leading[CSS_FLEX_DIRECTION_ROW]) + currentAbsoluteChild.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_ROW], trailing[CSS_FLEX_DIRECTION_ROW])); } else { @@ -1345,7 +1345,7 @@ public class LayoutEngine { childWidth = boundAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_ROW, childWidth); } } - + if ((currentAbsoluteChild.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0)) { childHeight = currentAbsoluteChild.style.dimensions[DIMENSION_HEIGHT] + (currentAbsoluteChild.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + currentAbsoluteChild.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN])); } else { @@ -1357,12 +1357,12 @@ public class LayoutEngine { childHeight = boundAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_COLUMN, childHeight); } } - + // If we're still missing one or the other dimension, measure the content. if (Float.isNaN(childWidth) || Float.isNaN(childHeight)) { childWidthMeasureMode = Float.isNaN(childWidth) ? CSSMeasureMode.UNDEFINED : CSSMeasureMode.EXACTLY; childHeightMeasureMode = Float.isNaN(childHeight) ? CSSMeasureMode.UNDEFINED : CSSMeasureMode.EXACTLY; - + // According to the spec, if the main size is not definite and the // child's inline axis is parallel to the main axis (i.e. it's // horizontal), the child should be sized using "UNDEFINED" in @@ -1371,7 +1371,7 @@ public class LayoutEngine { childWidth = availableInnerWidth; childWidthMeasureMode = CSSMeasureMode.AT_MOST; } - + // The W3C spec doesn't say anything about the 'overflow' property, // but all major browsers appear to implement the following logic. if (node.style.overflow == CSSOverflow.HIDDEN) { @@ -1380,14 +1380,14 @@ public class LayoutEngine { childHeightMeasureMode = CSSMeasureMode.AT_MOST; } } - + layoutNodeInternal(layoutContext, currentAbsoluteChild, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, false, "abs-measure"); childWidth = currentAbsoluteChild.layout.measuredDimensions[DIMENSION_WIDTH] + (currentAbsoluteChild.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_ROW], leading[CSS_FLEX_DIRECTION_ROW]) + currentAbsoluteChild.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_ROW], trailing[CSS_FLEX_DIRECTION_ROW])); childHeight = currentAbsoluteChild.layout.measuredDimensions[DIMENSION_HEIGHT] + (currentAbsoluteChild.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + currentAbsoluteChild.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN])); } - + layoutNodeInternal(layoutContext, currentAbsoluteChild, childWidth, childHeight, direction, CSSMeasureMode.EXACTLY, CSSMeasureMode.EXACTLY, true, "abs-layout"); - + if (!Float.isNaN(currentAbsoluteChild.style.position[trailing[CSS_FLEX_DIRECTION_ROW]]) && !!Float.isNaN(currentAbsoluteChild.style.position[leading[CSS_FLEX_DIRECTION_ROW]])) { currentAbsoluteChild.layout.position[leading[CSS_FLEX_DIRECTION_ROW]] = @@ -1395,7 +1395,7 @@ public class LayoutEngine { currentAbsoluteChild.layout.measuredDimensions[dim[CSS_FLEX_DIRECTION_ROW]] - (Float.isNaN(currentAbsoluteChild.style.position[trailing[CSS_FLEX_DIRECTION_ROW]]) ? 0 : currentAbsoluteChild.style.position[trailing[CSS_FLEX_DIRECTION_ROW]]); } - + if (!Float.isNaN(currentAbsoluteChild.style.position[trailing[CSS_FLEX_DIRECTION_COLUMN]]) && !!Float.isNaN(currentAbsoluteChild.style.position[leading[CSS_FLEX_DIRECTION_COLUMN]])) { currentAbsoluteChild.layout.position[leading[CSS_FLEX_DIRECTION_COLUMN]] = @@ -1404,9 +1404,8 @@ public class LayoutEngine { (Float.isNaN(currentAbsoluteChild.style.position[trailing[CSS_FLEX_DIRECTION_COLUMN]]) ? 0 : currentAbsoluteChild.style.position[trailing[CSS_FLEX_DIRECTION_COLUMN]]); } } - + currentAbsoluteChild = currentAbsoluteChild.nextChild; } - /** END_GENERATED **/ } } diff --git a/java/java/src/com/facebook/csslayout/MeasureOutput.java b/java/com/facebook/csslayout/MeasureOutput.java similarity index 90% rename from java/java/src/com/facebook/csslayout/MeasureOutput.java rename to java/com/facebook/csslayout/MeasureOutput.java index 3efa1f2e..65adfdf1 100644 --- a/java/java/src/com/facebook/csslayout/MeasureOutput.java +++ b/java/com/facebook/csslayout/MeasureOutput.java @@ -1,11 +1,12 @@ /** - * Copyright (c) 2014, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ + package com.facebook.csslayout; /** diff --git a/java/java/src/com/facebook/csslayout/Spacing.java b/java/com/facebook/csslayout/Spacing.java similarity index 99% rename from java/java/src/com/facebook/csslayout/Spacing.java rename to java/com/facebook/csslayout/Spacing.java index 02857c61..25a555fe 100644 --- a/java/java/src/com/facebook/csslayout/Spacing.java +++ b/java/com/facebook/csslayout/Spacing.java @@ -1,11 +1,12 @@ /** - * Copyright (c) 2014, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ + package com.facebook.csslayout; import javax.annotation.Nullable; diff --git a/java/csharp/.editorconfig b/java/csharp/.editorconfig deleted file mode 100644 index 7a7d6ba0..00000000 --- a/java/csharp/.editorconfig +++ /dev/null @@ -1,13 +0,0 @@ -root = true - -[*] -end_of_line=LF - -[*.cs] -indent_style=space -indent_size=4 - -[*.js] -indent_style=space -indent_size=2 - diff --git a/java/csharp/.gitignore b/java/csharp/.gitignore deleted file mode 100644 index 23a657d2..00000000 --- a/java/csharp/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -bin/ -obj/ -/packages/ -/.vs/ -*.user -*.nupkg diff --git a/java/csharp/Facebook.CSSLayout.Tests/CSSNodeTest.cs b/java/csharp/Facebook.CSSLayout.Tests/CSSNodeTest.cs deleted file mode 100644 index 87e9991b..00000000 --- a/java/csharp/Facebook.CSSLayout.Tests/CSSNodeTest.cs +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -using System; -using NUnit.Framework; - -namespace Facebook.CSSLayout.Tests -{ - /** - * Tests for {@link CSSNode}. - */ - public class CSSNodeTest - { - - [Test] - public void testAddChildGetParent() - { - CSSNode parent = new CSSNode(); - CSSNode child = new CSSNode(); - - Assert.IsNull(child.getParent()); - Assert.AreEqual(0, parent.getChildCount()); - - parent.addChildAt(child, 0); - - Assert.AreEqual(1, parent.getChildCount()); - Assert.AreEqual(child, parent.getChildAt(0)); - Assert.AreEqual(parent, child.getParent()); - - parent.removeChildAt(0); - - Assert.IsNull(child.getParent()); - Assert.AreEqual(0, parent.getChildCount()); - } - - [Test, ExpectedException(typeof(InvalidOperationException))] - 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/java/csharp/Facebook.CSSLayout.Tests/Facebook.CSSLayout.Tests.csproj b/java/csharp/Facebook.CSSLayout.Tests/Facebook.CSSLayout.Tests.csproj deleted file mode 100755 index 2aac63d0..00000000 --- a/java/csharp/Facebook.CSSLayout.Tests/Facebook.CSSLayout.Tests.csproj +++ /dev/null @@ -1,70 +0,0 @@ - - - - - Debug - AnyCPU - {E687C8FD-0A0D-450F-853D-EC301BE1C038} - Library - Properties - Facebook.CSSLayout.Tests - Facebook.CSSLayout.Tests - v4.5 - 512 - ..\ - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - False - ..\packages\NUnit.2.6.4\lib\nunit.framework.dll - - - - - - - - - - - - - - - - - - - {d534fb4b-a7d4-4a29-96d3-f39a91a259bd} - Facebook.CSSLayout - - - - - - - - diff --git a/java/csharp/Facebook.CSSLayout.Tests/LayoutCachingTest.cs b/java/csharp/Facebook.CSSLayout.Tests/LayoutCachingTest.cs deleted file mode 100644 index 31139492..00000000 --- a/java/csharp/Facebook.CSSLayout.Tests/LayoutCachingTest.cs +++ /dev/null @@ -1,240 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -using NUnit.Framework; - -namespace Facebook.CSSLayout.Tests -{ - - /** - * Tests for {@link LayoutEngine} and {@link CSSNode} to make sure layouts are only generated when - * needed. - */ - public class LayoutCachingTest - { - - private void assertTreeHasNewLayout(bool expectedHasNewLayout, CSSNode root) - { - Assert.AreEqual(expectedHasNewLayout, root.HasNewLayout); - - for (int i = 0; i < root.getChildCount(); i++) - { - assertTreeHasNewLayout(expectedHasNewLayout, root.getChildAt(i)); - } - } - - private void markLayoutAppliedForTree(CSSNode root) - { - root.MarkLayoutSeen(); - 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(); - Assert.IsTrue(root.HasNewLayout); - assertTreeHasNewLayout(false, c0); - assertTreeHasNewLayout(false, c1); - } - - [Test] - public void testInvalidatesCacheWhenChildAdded() - { - CSSNode root = new CSSNode(); - CSSNode c0 = new CSSNode(); - CSSNode c1 = new CSSNode(); - CSSNode c0c0 = new CSSNode(); - CSSNode c0c1 = new CSSNode(); - CSSNode c1c0 = new CSSNode(); - c0c1.Width = 200; - c0c1.Height = 200; - root.addChildAt(c0, 0); - root.addChildAt(c1, 1); - c0.addChildAt(c0c0, 0); - c0c0.addChildAt(c1c0, 0); - - root.calculateLayout(); - markLayoutAppliedForTree(root); - - c0.addChildAt(c0c1, 1); - - root.calculateLayout(); - Assert.IsTrue(root.HasNewLayout); - Assert.IsTrue(c0.HasNewLayout); - Assert.IsTrue(c0c1.HasNewLayout); - - Assert.IsTrue(c0c0.HasNewLayout); - Assert.IsTrue(c1.HasNewLayout); - - Assert.IsTrue(c1c0.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(); - markLayoutAppliedForTree(root); - - c1.AlignSelf = CSSAlign.Center; - root.calculateLayout(); - - Assert.IsTrue(root.HasNewLayout); - Assert.IsTrue(c1.HasNewLayout); - - Assert.IsTrue(c0.HasNewLayout); - Assert.IsFalse(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(); - markLayoutAppliedForTree(root); - - c1.SetMargin(CSSSpacingType.Left, 10); - root.calculateLayout(); - - Assert.IsTrue(root.HasNewLayout); - Assert.IsTrue(c1.HasNewLayout); - - Assert.IsTrue(c0.HasNewLayout); - Assert.IsTrue(c0c0.HasNewLayout); - } - - [Test] - public void testInvalidatesFullTreeWhenParentWidthChanges() - { - CSSNode root = new CSSNode(); - CSSNode c0 = new CSSNode(); - CSSNode c1 = new CSSNode(); - CSSNode c0c0 = new CSSNode(); - CSSNode c1c0 = new CSSNode(); - root.addChildAt(c0, 0); - root.addChildAt(c1, 1); - c0.addChildAt(c0c0, 0); - c1.addChildAt(c1c0, 0); - - root.calculateLayout(); - markLayoutAppliedForTree(root); - - c0.Width = 200; - root.calculateLayout(); - - Assert.IsTrue(root.HasNewLayout); - Assert.IsTrue(c0.HasNewLayout); - Assert.IsTrue(c0c0.HasNewLayout); - - Assert.IsTrue(c1.HasNewLayout); - Assert.IsTrue(c1c0.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.Width = 200; - - root.calculateLayout(); - markLayoutAppliedForTree(root); - - root.Width = 200; - root.calculateLayout(); - - Assert.IsTrue(root.HasNewLayout); - assertTreeHasNewLayout(false, c0); - assertTreeHasNewLayout(false, c1); - } - - [Test] - public void testInvalidateCacheWhenHeightChangesPosition() - { - CSSNode root = new CSSNode(); - CSSNode c0 = new CSSNode(); - CSSNode c1 = new CSSNode(); - CSSNode c1c0 = new CSSNode(); - root.addChildAt(c0, 0); - root.addChildAt(c1, 1); - c1.addChildAt(c1c0, 0); - - root.calculateLayout(); - markLayoutAppliedForTree(root); - - c0.Height = 100; - root.calculateLayout(); - - Assert.IsTrue(root.HasNewLayout); - Assert.IsTrue(c0.HasNewLayout); - Assert.IsTrue(c1.HasNewLayout); - Assert.IsFalse(c1c0.HasNewLayout); - } - - [Test] - public void testInvalidatesOnNewMeasureFunction() - { - 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(); - markLayoutAppliedForTree(root); - - c1.setMeasureFunction((node, width, widthMode, height, heightMode) => new MeasureOutput(100, 20)); - - root.calculateLayout(); - - Assert.IsTrue(root.HasNewLayout); - Assert.IsTrue(c1.HasNewLayout); - - Assert.IsTrue(c0.HasNewLayout); - Assert.IsTrue(c0c0.HasNewLayout); - } - } -} diff --git a/java/csharp/Facebook.CSSLayout.Tests/LayoutEngineTest.cs b/java/csharp/Facebook.CSSLayout.Tests/LayoutEngineTest.cs deleted file mode 100644 index 4950f230..00000000 --- a/java/csharp/Facebook.CSSLayout.Tests/LayoutEngineTest.cs +++ /dev/null @@ -1,9900 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -using System; -using NUnit.Framework; - -namespace Facebook.CSSLayout.Tests -{ - -/** - * Tests for {@link LayoutEngine} - */ -public class LayoutEngineTest -{ - const int POSITION_LEFT = CSSLayout.POSITION_LEFT; - const int POSITION_TOP = CSSLayout.POSITION_TOP; - const int POSITION_RIGHT = CSSLayout.POSITION_RIGHT; - const int POSITION_BOTTOM = CSSLayout.POSITION_BOTTOM; - const int DIMENSION_HEIGHT = CSSLayout.DIMENSION_HEIGHT; - const int DIMENSION_WIDTH = CSSLayout.DIMENSION_WIDTH; - - static readonly MeasureFunction sTestMeasureFunction = (node, width, widthMode, height, heightMode) => - { - TestCSSNode testNode = (TestCSSNode) node; - if (testNode.context.Equals(TestConstants.SMALL_TEXT)) { - if (widthMode == CSSMeasureMode.Undefined) { - width = 10000000; - } - return new MeasureOutput( - Math.Min(width, TestConstants.SMALL_WIDTH), - TestConstants.SMALL_HEIGHT); - } else if (testNode.context.Equals(TestConstants.LONG_TEXT)) { - if (widthMode == CSSMeasureMode.Undefined) { - width = 10000000; - } - return new MeasureOutput(width >= TestConstants.BIG_WIDTH - ? TestConstants.BIG_WIDTH - : Math.Max(TestConstants.BIG_MIN_WIDTH, width), - width >= TestConstants.BIG_WIDTH - ? TestConstants.SMALL_HEIGHT - : TestConstants.BIG_HEIGHT); - } else if (testNode.context.Equals(TestConstants.MEASURE_WITH_RATIO_2)) { - if (widthMode != CSSMeasureMode.Undefined) { - return new MeasureOutput(width, width * 2); - } else if (heightMode != CSSMeasureMode.Undefined) { - return new MeasureOutput(height * 2, height); - } else { - return new MeasureOutput(99999, 99999); - } - } else if (testNode.context.Equals(TestConstants.MEASURE_WITH_MATCH_PARENT)) { - if (widthMode == CSSMeasureMode.Undefined) { - width = 99999; - } - if (heightMode == CSSMeasureMode.Undefined) { - height = 99999; - } - return new MeasureOutput(width, height); - } else { - throw new Exception("Got unknown test: " + testNode.context); - } - }; - - private class TestCSSNode : CSSNode { - - public String context = null; - - public TestCSSNode getChildAt(int i) { - return (TestCSSNode) base[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.IsTrue( - areLayoutsEqual(actual, expected), - message + "\nActual:\n" + actual.ToString() + "\nExpected:\n" + expected.ToString() - ); -} - - private static bool areLayoutsEqual(CSSNode a, CSSNode b) { - bool doNodesHaveSameLayout = - areFloatsEqual(a.layout.position[POSITION_LEFT], b.layout.position[POSITION_LEFT]) && - areFloatsEqual(a.layout.position[POSITION_TOP], b.layout.position[POSITION_TOP]) && - areFloatsEqual(a.layout.dimensions[DIMENSION_WIDTH], b.layout.dimensions[DIMENSION_WIDTH]) && - areFloatsEqual(a.layout.dimensions[DIMENSION_HEIGHT], b.layout.dimensions[DIMENSION_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 bool 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.dimensions[DIMENSION_WIDTH] = 100; - node_0.style.dimensions[DIMENSION_HEIGHT] = 200; - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 100; - node_0.layout.dimensions[DIMENSION_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.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 500; - node_1.style.dimensions[DIMENSION_HEIGHT] = 500; - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_WIDTH] = 250; - node_1.style.dimensions[DIMENSION_HEIGHT] = 250; - node_1 = node_0.getChildAt(2); - node_1.style.dimensions[DIMENSION_WIDTH] = 125; - node_1.style.dimensions[DIMENSION_HEIGHT] = 125; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 500; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 500; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 500; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 250; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 250; - node_1 = node_0.getChildAt(2); - node_1.layout.position[POSITION_TOP] = 750; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 125; - node_1.layout.dimensions[DIMENSION_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.flexDirection = CSSFlexDirection.ColumnReverse; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 500; - node_1.style.dimensions[DIMENSION_HEIGHT] = 500; - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_WIDTH] = 250; - node_1.style.dimensions[DIMENSION_HEIGHT] = 250; - node_1 = node_0.getChildAt(2); - node_1.style.dimensions[DIMENSION_WIDTH] = 125; - node_1.style.dimensions[DIMENSION_HEIGHT] = 125; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 500; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 500; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 500; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 250; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 250; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 250; - node_1 = node_0.getChildAt(2); - node_1.layout.position[POSITION_TOP] = 125; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 125; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 125; - } - } - - test("should layout node with children in reverse", root_node, root_layout); - } - - [Test] - public void TestCase3() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 500; - node_1.style.dimensions[DIMENSION_HEIGHT] = 500; - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_WIDTH] = 500; - node_1.style.dimensions[DIMENSION_HEIGHT] = 500; - addChildren(node_1, 2); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.style.dimensions[DIMENSION_WIDTH] = 250; - node_2.style.dimensions[DIMENSION_HEIGHT] = 250; - node_2 = node_1.getChildAt(1); - node_2.style.dimensions[DIMENSION_WIDTH] = 250; - node_2.style.dimensions[DIMENSION_HEIGHT] = 250; - } - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 500; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 500; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 500; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 500; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 500; - addChildren(node_1, 2); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 0; - node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 250; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 250; - node_2 = node_1.getChildAt(1); - node_2.layout.position[POSITION_TOP] = 250; - node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 250; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 250; - } - } - } - - test("should layout node with nested children", root_node, root_layout); - } - - [Test] - public void TestCase4() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.ColumnReverse; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 500; - node_1.style.dimensions[DIMENSION_HEIGHT] = 500; - node_1 = node_0.getChildAt(1); - node_1.style.flexDirection = CSSFlexDirection.ColumnReverse; - node_1.style.dimensions[DIMENSION_WIDTH] = 500; - node_1.style.dimensions[DIMENSION_HEIGHT] = 500; - addChildren(node_1, 2); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.style.dimensions[DIMENSION_WIDTH] = 250; - node_2.style.dimensions[DIMENSION_HEIGHT] = 250; - node_2 = node_1.getChildAt(1); - node_2.style.dimensions[DIMENSION_WIDTH] = 250; - node_2.style.dimensions[DIMENSION_HEIGHT] = 250; - } - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 500; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 500; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 500; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 500; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 500; - addChildren(node_1, 2); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 250; - node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 250; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 250; - node_2 = node_1.getChildAt(1); - node_2.layout.position[POSITION_TOP] = 0; - node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 250; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 250; - } - } - } - - test("should layout node with nested children in reverse", root_node, root_layout); - } - - [Test] - public void TestCase5() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 100; - node_0.style.dimensions[DIMENSION_HEIGHT] = 200; - node_0.setMargin(Spacing.LEFT, 10); - node_0.setMargin(Spacing.TOP, 10); - node_0.setMargin(Spacing.RIGHT, 10); - node_0.setMargin(Spacing.BOTTOM, 10); - node_0.setMargin(Spacing.START, 10); - node_0.setMargin(Spacing.END, 10); - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 10; - node_0.layout.position[POSITION_LEFT] = 10; - node_0.layout.dimensions[DIMENSION_WIDTH] = 100; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 200; - } - - test("should layout node with margin", root_node, root_layout); - } - - [Test] - public void TestCase6() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - node_0.setMargin(Spacing.LEFT, 10); - node_0.setMargin(Spacing.TOP, 10); - node_0.setMargin(Spacing.RIGHT, 10); - node_0.setMargin(Spacing.BOTTOM, 10); - node_0.setMargin(Spacing.START, 10); - node_0.setMargin(Spacing.END, 10); - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1.setMargin(Spacing.LEFT, 50); - node_1.setMargin(Spacing.TOP, 50); - node_1.setMargin(Spacing.RIGHT, 50); - node_1.setMargin(Spacing.BOTTOM, 50); - node_1.setMargin(Spacing.START, 50); - node_1.setMargin(Spacing.END, 50); - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1.setMargin(Spacing.LEFT, 25); - node_1.setMargin(Spacing.TOP, 25); - node_1.setMargin(Spacing.RIGHT, 25); - node_1.setMargin(Spacing.BOTTOM, 25); - node_1.setMargin(Spacing.START, 25); - node_1.setMargin(Spacing.END, 25); - node_1 = node_0.getChildAt(2); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1.setMargin(Spacing.LEFT, 10); - node_1.setMargin(Spacing.TOP, 10); - node_1.setMargin(Spacing.RIGHT, 10); - node_1.setMargin(Spacing.BOTTOM, 10); - node_1.setMargin(Spacing.START, 10); - node_1.setMargin(Spacing.END, 10); - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 10; - node_0.layout.position[POSITION_LEFT] = 10; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 50; - node_1.layout.position[POSITION_LEFT] = 50; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 225; - node_1.layout.position[POSITION_LEFT] = 25; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(2); - node_1.layout.position[POSITION_TOP] = 360; - node_1.layout.position[POSITION_LEFT] = 10; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - test("should layout node with several children", root_node, root_layout); - } - - [Test] - public void TestCase7() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.ColumnReverse; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - node_0.setMargin(Spacing.LEFT, 10); - node_0.setMargin(Spacing.TOP, 10); - node_0.setMargin(Spacing.RIGHT, 10); - node_0.setMargin(Spacing.BOTTOM, 10); - node_0.setMargin(Spacing.START, 10); - node_0.setMargin(Spacing.END, 10); - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1.setMargin(Spacing.LEFT, 50); - node_1.setMargin(Spacing.TOP, 50); - node_1.setMargin(Spacing.RIGHT, 50); - node_1.setMargin(Spacing.BOTTOM, 50); - node_1.setMargin(Spacing.START, 50); - node_1.setMargin(Spacing.END, 50); - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1.setMargin(Spacing.LEFT, 25); - node_1.setMargin(Spacing.TOP, 25); - node_1.setMargin(Spacing.RIGHT, 25); - node_1.setMargin(Spacing.BOTTOM, 25); - node_1.setMargin(Spacing.START, 25); - node_1.setMargin(Spacing.END, 25); - node_1 = node_0.getChildAt(2); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1.setMargin(Spacing.LEFT, 10); - node_1.setMargin(Spacing.TOP, 10); - node_1.setMargin(Spacing.RIGHT, 10); - node_1.setMargin(Spacing.BOTTOM, 10); - node_1.setMargin(Spacing.START, 10); - node_1.setMargin(Spacing.END, 10); - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 10; - node_0.layout.position[POSITION_LEFT] = 10; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 850; - node_1.layout.position[POSITION_LEFT] = 50; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 675; - node_1.layout.position[POSITION_LEFT] = 25; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(2); - node_1.layout.position[POSITION_TOP] = 540; - node_1.layout.position[POSITION_LEFT] = 10; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - test("should layout node with several children in reverse", root_node, root_layout); - } - - [Test] - public void TestCase8() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.direction = CSSDirection.RTL; - node_0.style.flexDirection = CSSFlexDirection.RowReverse; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 200; - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_WIDTH] = 300; - node_1.style.dimensions[DIMENSION_HEIGHT] = 150; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 100; - node_1.layout.dimensions[DIMENSION_WIDTH] = 300; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 150; - } - } - - test("should layout rtl with reverse correctly", root_node, root_layout); - } - - [Test] - public void TestCase9() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 200; - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_WIDTH] = 300; - node_1.style.dimensions[DIMENSION_HEIGHT] = 150; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 100; - node_1.layout.dimensions[DIMENSION_WIDTH] = 300; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 150; - } - } - - test("should layout node with row flex direction", root_node, root_layout); - } - - [Test] - public void TestCase10() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.direction = CSSDirection.RTL; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 200; - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_WIDTH] = 300; - node_1.style.dimensions[DIMENSION_HEIGHT] = 150; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 900; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 600; - node_1.layout.dimensions[DIMENSION_WIDTH] = 300; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 150; - } - } - - test("should layout node with row flex direction in rtl", root_node, root_layout); - } - - [Test] - public void TestCase11() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 300; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 200; - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_WIDTH] = 300; - node_1.style.dimensions[DIMENSION_HEIGHT] = 150; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 300; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 350; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 200; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 300; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 150; - } - } - - test("should layout node based on children main dimensions", root_node, root_layout); - } - - [Test] - public void TestCase12() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.ColumnReverse; - node_0.style.dimensions[DIMENSION_WIDTH] = 300; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 200; - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_WIDTH] = 300; - node_1.style.dimensions[DIMENSION_HEIGHT] = 150; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 300; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 350; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 150; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 300; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 150; - } - } - - test("should layout node based on children main dimensions in reverse", root_node, root_layout); - } - - [Test] - public void TestCase13() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 200; - node_1 = node_0.getChildAt(1); - node_1.style.flex = 1; - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 200; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 800; - } - } - - test("should layout node with just flex", root_node, root_layout); - } - - [Test] - public void TestCase14() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.ColumnReverse; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 200; - node_1 = node_0.getChildAt(1); - node_1.style.flex = 1; - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 800; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 800; - } - } - - test("should layout node with just flex in reverse", root_node, root_layout); - } - - [Test] - public void TestCase15() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.flex = 1; - node_1.style.dimensions[DIMENSION_WIDTH] = 1000; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.style.flex = 1; - node_2.style.dimensions[DIMENSION_WIDTH] = 1000; - addChildren(node_2, 1); - { - TestCSSNode node_3; - node_3 = node_2.getChildAt(0); - node_3.style.flex = 1; - node_3.style.dimensions[DIMENSION_WIDTH] = 1000; - } - } - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 0; - node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_2, 1); - { - TestCSSNode node_3; - node_3 = node_2.getChildAt(0); - node_3.layout.position[POSITION_TOP] = 0; - node_3.layout.position[POSITION_LEFT] = 0; - node_3.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_3.layout.dimensions[DIMENSION_HEIGHT] = 1000; - } - } - } - } - - test("should layout node with flex recursively", root_node, root_layout); - } - - [Test] - public void TestCase16() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.ColumnReverse; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.flexDirection = CSSFlexDirection.ColumnReverse; - node_1.style.flex = 1; - node_1.style.dimensions[DIMENSION_WIDTH] = 1000; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.style.flexDirection = CSSFlexDirection.ColumnReverse; - node_2.style.flex = 1; - node_2.style.dimensions[DIMENSION_WIDTH] = 1000; - addChildren(node_2, 1); - { - TestCSSNode node_3; - node_3 = node_2.getChildAt(0); - node_3.style.flexDirection = CSSFlexDirection.ColumnReverse; - node_3.style.flex = 1; - node_3.style.dimensions[DIMENSION_WIDTH] = 1000; - } - } - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 0; - node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_2, 1); - { - TestCSSNode node_3; - node_3 = node_2.getChildAt(0); - node_3.layout.position[POSITION_TOP] = 0; - node_3.layout.position[POSITION_LEFT] = 0; - node_3.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_3.layout.dimensions[DIMENSION_HEIGHT] = 1000; - } - } - } - } - - test("should layout node with flex recursively in reverse", root_node, root_layout); - } - - [Test] - public void TestCase17() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - node_0.setMargin(Spacing.LEFT, 5); - node_0.setMargin(Spacing.TOP, 10); - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1.setMargin(Spacing.LEFT, 15); - node_1.setMargin(Spacing.TOP, 50); - node_1.setMargin(Spacing.BOTTOM, 20); - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1.setMargin(Spacing.LEFT, 30); - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 10; - node_0.layout.position[POSITION_LEFT] = 5; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 50; - node_1.layout.position[POSITION_LEFT] = 15; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 170; - node_1.layout.position[POSITION_LEFT] = 30; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - test("should layout node with targeted margin", root_node, root_layout); - } - - [Test] - public void TestCase18() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.ColumnReverse; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - node_0.setMargin(Spacing.LEFT, 5); - node_0.setMargin(Spacing.TOP, 10); - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1.setMargin(Spacing.LEFT, 15); - node_1.setMargin(Spacing.TOP, 50); - node_1.setMargin(Spacing.BOTTOM, 20); - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1.setMargin(Spacing.LEFT, 30); - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 10; - node_0.layout.position[POSITION_LEFT] = 5; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 880; - node_1.layout.position[POSITION_LEFT] = 15; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 730; - node_1.layout.position[POSITION_LEFT] = 30; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - test("should layout node with targeted margin in reverse", root_node, root_layout); - } - - [Test] - public void TestCase19() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.justifyContent = CSSJustify.FlexStart; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 100; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - test("should layout node with justifyContent: flex-start", root_node, root_layout); - } - - [Test] - public void TestCase20() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.ColumnReverse; - node_0.style.justifyContent = CSSJustify.FlexStart; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 900; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 800; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - test("should layout node with justifyContent: flex-start in reverse", root_node, root_layout); - } - - [Test] - public void TestCase21() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.justifyContent = CSSJustify.FlexEnd; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 800; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 900; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - test("should layout node with justifyContent: flex-end", root_node, root_layout); - } - - [Test] - public void TestCase22() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.ColumnReverse; - node_0.style.justifyContent = CSSJustify.FlexEnd; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 100; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - test("should layout node with justifyContent: flex-end in reverse", root_node, root_layout); - } - - [Test] - public void TestCase23() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.justifyContent = CSSJustify.SpaceBetween; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 900; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - test("should layout node with justifyContent: space-between", root_node, root_layout); - } - - [Test] - public void TestCase24() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.ColumnReverse; - node_0.style.justifyContent = CSSJustify.SpaceBetween; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 900; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - test("should layout node with justifyContent: space-between in reverse", root_node, root_layout); - } - - [Test] - public void TestCase25() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.justifyContent = CSSJustify.SpaceAround; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 200; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 700; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - test("should layout node with justifyContent: space-around", root_node, root_layout); - } - - [Test] - public void TestCase26() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.ColumnReverse; - node_0.style.justifyContent = CSSJustify.SpaceAround; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 700; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 200; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - test("should layout node with justifyContent: space-around in reverse", root_node, root_layout); - } - - [Test] - public void TestCase27() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.justifyContent = CSSJustify.Center; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 400; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 500; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - test("should layout node with justifyContent: center", root_node, root_layout); - } - - [Test] - public void TestCase28() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.ColumnReverse; - node_0.style.justifyContent = CSSJustify.Center; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 500; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 400; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - test("should layout node with justifyContent: center in reverse", root_node, root_layout); - } - - [Test] - public void TestCase29() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.flex = 1; - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 1000; - } - } - - test("should layout node with flex override height", root_node, root_layout); - } - - [Test] - public void TestCase30() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.alignItems = CSSAlign.FlexStart; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 200; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 200; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 100; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - test("should layout node with alignItems: flex-start", root_node, root_layout); - } - - [Test] - public void TestCase31() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.ColumnReverse; - node_0.style.alignItems = CSSAlign.FlexStart; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 200; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 900; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 200; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 800; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - test("should layout node with alignItems: flex-start in reverse", root_node, root_layout); - } - - [Test] - public void TestCase32() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.alignItems = CSSAlign.Center; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 200; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 400; - node_1.layout.dimensions[DIMENSION_WIDTH] = 200; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 100; - node_1.layout.position[POSITION_LEFT] = 450; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - test("should layout node with alignItems: center", root_node, root_layout); - } - - [Test] - public void TestCase33() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.ColumnReverse; - node_0.style.alignItems = CSSAlign.Center; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 200; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 900; - node_1.layout.position[POSITION_LEFT] = 400; - node_1.layout.dimensions[DIMENSION_WIDTH] = 200; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 800; - node_1.layout.position[POSITION_LEFT] = 450; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - test("should layout node with alignItems: center in reverse", root_node, root_layout); - } - - [Test] - public void TestCase34() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.alignItems = CSSAlign.FlexEnd; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 200; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 800; - node_1.layout.dimensions[DIMENSION_WIDTH] = 200; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 100; - node_1.layout.position[POSITION_LEFT] = 900; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - test("should layout node with alignItems: flex-end", root_node, root_layout); - } - - [Test] - public void TestCase35() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.ColumnReverse; - node_0.style.alignItems = CSSAlign.FlexEnd; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 200; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 900; - node_1.layout.position[POSITION_LEFT] = 800; - node_1.layout.dimensions[DIMENSION_WIDTH] = 200; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 800; - node_1.layout.position[POSITION_LEFT] = 900; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - test("should layout node with alignItems: flex-end in reverse", root_node, root_layout); - } - - [Test] - public void TestCase36() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.alignItems = CSSAlign.FlexEnd; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 200; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.style.alignSelf = CSSAlign.Center; - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 800; - node_1.layout.dimensions[DIMENSION_WIDTH] = 200; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 100; - node_1.layout.position[POSITION_LEFT] = 450; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - test("should layout node with alignSelf overrides alignItems", root_node, root_layout); - } - - [Test] - public void TestCase37() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.ColumnReverse; - node_0.style.alignItems = CSSAlign.FlexEnd; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 200; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.style.alignSelf = CSSAlign.Center; - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 900; - node_1.layout.position[POSITION_LEFT] = 800; - node_1.layout.dimensions[DIMENSION_WIDTH] = 200; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 800; - node_1.layout.position[POSITION_LEFT] = 450; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - test("should layout node with alignSelf overrides alignItems in reverse", root_node, root_layout); - } - - [Test] - public void TestCase38() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.alignItems = CSSAlign.Stretch; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - test("should layout node with alignItem: stretch", root_node, root_layout); - } - - [Test] - public void TestCase39() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.ColumnReverse; - node_0.style.alignItems = CSSAlign.Stretch; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 900; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - test("should layout node with alignItem: stretch in reverse", 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); - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 0; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 0; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout empty node", root_node, root_layout); - } - - [Test] - public void TestCase41() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.ColumnReverse; - 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.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 0; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 0; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout empty node in reverse", root_node, root_layout); - } - - [Test] - public void TestCase42() - { - 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.setMargin(Spacing.LEFT, 5); - node_1.setMargin(Spacing.TOP, 5); - node_1.setMargin(Spacing.RIGHT, 5); - node_1.setMargin(Spacing.BOTTOM, 5); - node_1.setMargin(Spacing.START, 5); - node_1.setMargin(Spacing.END, 5); - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 10; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 10; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 5; - node_1.layout.position[POSITION_LEFT] = 5; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout child with margin", root_node, root_layout); - } - - [Test] - public void TestCase43() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.ColumnReverse; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.setMargin(Spacing.LEFT, 5); - node_1.setMargin(Spacing.TOP, 5); - node_1.setMargin(Spacing.RIGHT, 5); - node_1.setMargin(Spacing.BOTTOM, 5); - node_1.setMargin(Spacing.START, 5); - node_1.setMargin(Spacing.END, 5); - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 10; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 10; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 5; - node_1.layout.position[POSITION_LEFT] = 5; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout child with margin in reverse", root_node, root_layout); - } - - [Test] - public void TestCase44() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_HEIGHT] = 200; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 0; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 100; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - } - } - - test("should not shrink children if not enough space", root_node, root_layout); - } - - [Test] - public void TestCase45() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.ColumnReverse; - node_0.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_HEIGHT] = 200; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 0; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = -200; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - } - } - - test("should not shrink children if not enough space in reverse", root_node, root_layout); - } - - [Test] - public void TestCase46() - { - 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.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 0; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - - test("should layout for center", root_node, root_layout); - } - - [Test] - public void TestCase47() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.justifyContent = CSSJustify.FlexEnd; - node_0.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.setMargin(Spacing.TOP, 10); - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 0; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 100; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout flex-end taking into account margin", root_node, root_layout); - } - - [Test] - public void TestCase48() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.ColumnReverse; - node_0.style.justifyContent = CSSJustify.FlexEnd; - node_0.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.setMargin(Spacing.TOP, 10); - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 0; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 10; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout flex-end taking into account margin in reverse", 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.alignItems = CSSAlign.FlexEnd; - addChildren(node_1, 2); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.setMargin(Spacing.LEFT, 10); - node_2.setMargin(Spacing.TOP, 10); - node_2.setMargin(Spacing.RIGHT, 10); - node_2.setMargin(Spacing.BOTTOM, 10); - node_2.setMargin(Spacing.START, 10); - node_2.setMargin(Spacing.END, 10); - node_2 = node_1.getChildAt(1); - node_2.style.dimensions[DIMENSION_HEIGHT] = 100; - } - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 20; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 120; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 20; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 120; - addChildren(node_1, 2); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 10; - node_2.layout.position[POSITION_LEFT] = 10; - node_2.layout.dimensions[DIMENSION_WIDTH] = 0; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 0; - node_2 = node_1.getChildAt(1); - node_2.layout.position[POSITION_TOP] = 20; - node_2.layout.position[POSITION_LEFT] = 20; - node_2.layout.dimensions[DIMENSION_WIDTH] = 0; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - } - - test("should layout alignItems with margin", root_node, root_layout); - } - - [Test] - public void TestCase50() - { - 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.ColumnReverse; - node_1.style.alignItems = CSSAlign.FlexEnd; - addChildren(node_1, 2); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.setMargin(Spacing.LEFT, 10); - node_2.setMargin(Spacing.TOP, 10); - node_2.setMargin(Spacing.RIGHT, 10); - node_2.setMargin(Spacing.BOTTOM, 10); - node_2.setMargin(Spacing.START, 10); - node_2.setMargin(Spacing.END, 10); - node_2 = node_1.getChildAt(1); - node_2.style.dimensions[DIMENSION_HEIGHT] = 100; - } - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 20; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 120; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 20; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 120; - addChildren(node_1, 2); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 110; - node_2.layout.position[POSITION_LEFT] = 10; - node_2.layout.dimensions[DIMENSION_WIDTH] = 0; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 0; - node_2 = node_1.getChildAt(1); - node_2.layout.position[POSITION_TOP] = 0; - node_2.layout.position[POSITION_LEFT] = 20; - node_2.layout.dimensions[DIMENSION_WIDTH] = 0; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - } - - test("should layout alignItems with margin in reverse", root_node, root_layout); - } - - [Test] - public void TestCase51() - { - 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.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 0; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 0; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout flex inside of an empty element", root_node, root_layout); - } - - [Test] - public void TestCase52() - { - 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.setMargin(Spacing.LEFT, 10); - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 10; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 0; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 10; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout alignItems stretch and margin", root_node, root_layout); - } - - [Test] - public void TestCase53() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.ColumnReverse; - node_0.style.alignItems = CSSAlign.Stretch; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.setMargin(Spacing.LEFT, 10); - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 10; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 0; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 10; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout alignItems stretch and margin in reverse", root_node, root_layout); - } - - [Test] - public void TestCase54() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.setPadding(Spacing.LEFT, 5); - node_0.setPadding(Spacing.TOP, 5); - node_0.setPadding(Spacing.RIGHT, 5); - node_0.setPadding(Spacing.BOTTOM, 5); - node_0.setPadding(Spacing.START, 5); - node_0.setPadding(Spacing.END, 5); - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 10; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 10; - } - - test("should layout node with padding", root_node, root_layout); - } - - [Test] - public void TestCase55() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.setPadding(Spacing.LEFT, 5); - node_0.setPadding(Spacing.TOP, 5); - node_0.setPadding(Spacing.RIGHT, 5); - node_0.setPadding(Spacing.BOTTOM, 5); - node_0.setPadding(Spacing.START, 5); - node_0.setPadding(Spacing.END, 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.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 10; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 10; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 5; - node_1.layout.position[POSITION_LEFT] = 5; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout node with padding and a child", root_node, root_layout); - } - - [Test] - public void TestCase56() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.setPadding(Spacing.LEFT, 5); - node_0.setPadding(Spacing.TOP, 5); - node_0.setPadding(Spacing.RIGHT, 5); - node_0.setPadding(Spacing.BOTTOM, 5); - node_0.setPadding(Spacing.START, 5); - node_0.setPadding(Spacing.END, 5); - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.setMargin(Spacing.LEFT, 5); - node_1.setMargin(Spacing.TOP, 5); - node_1.setMargin(Spacing.RIGHT, 5); - node_1.setMargin(Spacing.BOTTOM, 5); - node_1.setMargin(Spacing.START, 5); - node_1.setMargin(Spacing.END, 5); - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 20; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 20; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 10; - node_1.layout.position[POSITION_LEFT] = 10; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout node with padding and a child with margin", root_node, root_layout); - } - - [Test] - public void TestCase57() - { - 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.setPadding(Spacing.LEFT, 10); - node_1.setPadding(Spacing.TOP, 10); - node_1.setPadding(Spacing.RIGHT, 10); - node_1.setPadding(Spacing.BOTTOM, 10); - node_1.setPadding(Spacing.START, 10); - node_1.setPadding(Spacing.END, 10); - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 20; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 20; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 20; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 20; - } - } - - test("should layout node with padding and stretch", root_node, root_layout); - } - - [Test] - public void TestCase58() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.setPadding(Spacing.LEFT, 50); - node_0.setPadding(Spacing.TOP, 50); - node_0.setPadding(Spacing.RIGHT, 50); - node_0.setPadding(Spacing.BOTTOM, 50); - node_0.setPadding(Spacing.START, 50); - node_0.setPadding(Spacing.END, 50); - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.alignSelf = CSSAlign.Stretch; - node_1.setPadding(Spacing.LEFT, 10); - node_1.setPadding(Spacing.TOP, 10); - node_1.setPadding(Spacing.RIGHT, 10); - node_1.setPadding(Spacing.BOTTOM, 10); - node_1.setPadding(Spacing.START, 10); - node_1.setPadding(Spacing.END, 10); - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 120; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 120; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 50; - node_1.layout.position[POSITION_LEFT] = 50; - node_1.layout.dimensions[DIMENSION_WIDTH] = 20; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 20; - } - } - - test("should layout node with inner & outer padding and stretch", root_node, root_layout); - } - - [Test] - public void TestCase59() - { - 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.setMargin(Spacing.LEFT, 16); - node_2.setMargin(Spacing.TOP, 16); - node_2.setMargin(Spacing.RIGHT, 16); - node_2.setMargin(Spacing.BOTTOM, 16); - node_2.setMargin(Spacing.START, 16); - node_2.setMargin(Spacing.END, 16); - } - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 32; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 32; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 32; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 32; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 16; - node_2.layout.position[POSITION_LEFT] = 16; - node_2.layout.dimensions[DIMENSION_WIDTH] = 0; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - } - - test("should layout node with stretch and child with margin", root_node, root_layout); - } - - [Test] - public void TestCase60() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.position[POSITION_LEFT] = 5; - node_0.style.position[POSITION_TOP] = 5; - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 5; - node_0.layout.position[POSITION_LEFT] = 5; - node_0.layout.dimensions[DIMENSION_WIDTH] = 0; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - - test("should layout node with top and left", root_node, root_layout); - } - - [Test] - public void TestCase61() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.justifyContent = CSSJustify.SpaceAround; - node_0.style.dimensions[DIMENSION_HEIGHT] = 10; - node_0.setPadding(Spacing.TOP, 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.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 0; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 10; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 7.5f; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout node with height, padding and space-around", root_node, root_layout); - } - - [Test] - public void TestCase62() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.position[POSITION_BOTTOM] = 5; - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = -5; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 0; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - - test("should layout node with bottom", root_node, root_layout); - } - - [Test] - public void TestCase63() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.position[POSITION_TOP] = 10; - node_0.style.position[POSITION_BOTTOM] = 5; - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 10; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 0; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - - test("should layout node with both top and bottom", root_node, root_layout); - } - - [Test] - public void TestCase64() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.dimensions[DIMENSION_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.dimensions[DIMENSION_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.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 500; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 0; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 250; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 250; - node_1.layout.dimensions[DIMENSION_WIDTH] = 50; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - node_1 = node_0.getChildAt(2); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 250; - node_1.layout.dimensions[DIMENSION_WIDTH] = 250; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout node with position: absolute", root_node, root_layout); - } - - [Test] - public void TestCase65() - { - 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.setMargin(Spacing.RIGHT, 15); - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 0; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 0; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout node with child with position: absolute and margin", root_node, root_layout); - } - - [Test] - public void TestCase66() - { - 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.setPadding(Spacing.RIGHT, 12); - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 0; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 0; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 12; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout node with position: absolute, padding and alignSelf: center", root_node, root_layout); - } - - [Test] - public void TestCase67() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_HEIGHT] = 5; - node_0.setPadding(Spacing.BOTTOM, 20); - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 0; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 20; - } - - test("should work with height smaller than paddingBottom", root_node, root_layout); - } - - [Test] - public void TestCase68() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 5; - node_0.setPadding(Spacing.LEFT, 20); - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 20; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - - test("should work with width smaller than paddingLeft", root_node, root_layout); - } - - [Test] - public void TestCase69() - { - 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.dimensions[DIMENSION_WIDTH] = 400; - } - node_1 = node_0.getChildAt(1); - node_1.style.alignSelf = CSSAlign.Stretch; - node_1.style.dimensions[DIMENSION_WIDTH] = 200; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 400; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 0; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 400; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 0; - node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 400; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 200; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout node with specified width and stretch", root_node, root_layout); - } - - [Test] - public void TestCase70() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.setPadding(Spacing.LEFT, 5); - node_0.setPadding(Spacing.TOP, 5); - node_0.setPadding(Spacing.RIGHT, 5); - node_0.setPadding(Spacing.BOTTOM, 5); - node_0.setPadding(Spacing.START, 5); - node_0.setPadding(Spacing.END, 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.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 10; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 10; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 5; - node_1.layout.position[POSITION_LEFT] = 5; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout node with padding and child with position absolute", root_node, root_layout); - } - - [Test] - public void TestCase71() - { - 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.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.style.positionType = CSSPositionType.Absolute; - node_1.style.position[POSITION_LEFT] = 10; - node_1.style.position[POSITION_TOP] = 10; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 0; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 10; - node_1.layout.position[POSITION_LEFT] = 10; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout node with position absolute, top and left", root_node, root_layout); - } - - [Test] - public void TestCase72() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.setPadding(Spacing.LEFT, 20); - node_0.setPadding(Spacing.TOP, 20); - node_0.setPadding(Spacing.RIGHT, 20); - node_0.setPadding(Spacing.BOTTOM, 20); - node_0.setPadding(Spacing.START, 20); - node_0.setPadding(Spacing.END, 20); - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.positionType = CSSPositionType.Absolute; - node_1.style.position[POSITION_LEFT] = 5; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 40; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 40; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 20; - node_1.layout.position[POSITION_LEFT] = 5; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout node with padding and child position absolute, left", root_node, root_layout); - } - - [Test] - public void TestCase73() - { - 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.setMargin(Spacing.TOP, 5); - node_1.style.position[POSITION_TOP] = 5; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 0; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 0; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 10; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout node with position: absolute, top and marginTop", 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.positionType = CSSPositionType.Absolute; - node_1.setMargin(Spacing.LEFT, 5); - node_1.style.position[POSITION_LEFT] = 5; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 0; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 0; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 10; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout node with position: absolute, left and marginLeft", root_node, root_layout); - } - - [Test] - public void TestCase75() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.justifyContent = CSSJustify.SpaceAround; - node_0.style.dimensions[DIMENSION_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.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 0; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 200; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 100; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 100; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout node with space-around and child position absolute", root_node, root_layout); - } - - [Test] - public void TestCase76() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.ColumnReverse; - node_0.style.justifyContent = CSSJustify.SpaceAround; - node_0.style.dimensions[DIMENSION_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.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 0; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 200; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 100; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 100; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout node with space-around and child position absolute in reverse", root_node, root_layout); - } - - [Test] - public void TestCase77() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.dimensions[DIMENSION_WIDTH] = 700; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.flex = 1; - node_1.setMargin(Spacing.LEFT, 5); - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 700; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 0; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 5; - node_1.layout.dimensions[DIMENSION_WIDTH] = 695; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout node with flex and main margin", root_node, root_layout); - } - - [Test] - public void TestCase78() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.direction = CSSDirection.RTL; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.dimensions[DIMENSION_WIDTH] = 700; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.flex = 1; - node_1.setMargin(Spacing.RIGHT, 5); - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 700; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 0; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 695; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout node with flex and main margin in rtl", root_node, root_layout); - } - - [Test] - public void TestCase79() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.dimensions[DIMENSION_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.setPadding(Spacing.RIGHT, 5); - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 700; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 0; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 347.5f; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 347.5f; - node_1.layout.dimensions[DIMENSION_WIDTH] = 352.5f; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout node with multiple flex and padding", root_node, root_layout); - } - - [Test] - public void TestCase80() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.direction = CSSDirection.RTL; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.dimensions[DIMENSION_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.setPadding(Spacing.LEFT, 5); - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 700; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 0; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 352.5f; - node_1.layout.dimensions[DIMENSION_WIDTH] = 347.5f; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 352.5f; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout node with multiple flex and padding in rtl", root_node, root_layout); - } - - [Test] - public void TestCase81() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.dimensions[DIMENSION_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.setMargin(Spacing.LEFT, 5); - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 700; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 0; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 347.5f; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 352.5f; - node_1.layout.dimensions[DIMENSION_WIDTH] = 347.5f; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout node with multiple flex and margin", root_node, root_layout); - } - - [Test] - public void TestCase82() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.direction = CSSDirection.RTL; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.dimensions[DIMENSION_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.setMargin(Spacing.RIGHT, 5); - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 700; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 0; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 352.5f; - node_1.layout.dimensions[DIMENSION_WIDTH] = 347.5f; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 347.5f; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout node with multiple flex and margin in rtl", root_node, root_layout); - } - - [Test] - public void TestCase83() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_HEIGHT] = 300; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_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.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 0; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 300; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 600; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 600; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout node with flex and overflow", root_node, root_layout); - } - - [Test] - public void TestCase84() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.dimensions[DIMENSION_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.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 600; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 0; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout node with flex and position absolute", root_node, root_layout); - } - - [Test] - public void TestCase85() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.direction = CSSDirection.RTL; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.dimensions[DIMENSION_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.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 600; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 0; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 600; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout node with flex and position absolute in rtl", root_node, root_layout); - } - - [Test] - public void TestCase86() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_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.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 0; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 500; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 500; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 500; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout node with double flex and position absolute", root_node, root_layout); - } - - [Test] - public void TestCase87() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.setBorder(Spacing.LEFT, 5); - node_0.setBorder(Spacing.TOP, 5); - node_0.setBorder(Spacing.RIGHT, 5); - node_0.setBorder(Spacing.BOTTOM, 5); - node_0.setBorder(Spacing.START, 5); - node_0.setBorder(Spacing.END, 5); - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 10; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 10; - } - - test("should layout node with borderWidth", root_node, root_layout); - } - - [Test] - public void TestCase88() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.setBorder(Spacing.TOP, 1); - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.positionType = CSSPositionType.Absolute; - node_1.style.position[POSITION_TOP] = -1; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 0; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout node with borderWidth and position: absolute, top", root_node, root_layout); - } - - [Test] - public void TestCase89() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.setBorder(Spacing.LEFT, 1); - node_0.setBorder(Spacing.TOP, 1); - node_0.setBorder(Spacing.RIGHT, 1); - node_0.setBorder(Spacing.BOTTOM, 1); - node_0.setBorder(Spacing.START, 1); - node_0.setBorder(Spacing.END, 1); - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.positionType = CSSPositionType.Absolute; - node_1.style.position[POSITION_LEFT] = 5; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 2; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 2; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 1; - node_1.layout.position[POSITION_LEFT] = 6; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout node with borderWidth and position: absolute, top. cross axis", root_node, root_layout); - } - - [Test] - public void TestCase90() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 50; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.alignSelf = CSSAlign.Stretch; - node_1.setMargin(Spacing.LEFT, 20); - node_1.setPadding(Spacing.LEFT, 20); - node_1.setPadding(Spacing.TOP, 20); - node_1.setPadding(Spacing.RIGHT, 20); - node_1.setPadding(Spacing.BOTTOM, 20); - node_1.setPadding(Spacing.START, 20); - node_1.setPadding(Spacing.END, 20); - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 50; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 40; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 20; - node_1.layout.dimensions[DIMENSION_WIDTH] = 40; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 40; - } - } - - test("should correctly take into account min padding for stretch", root_node, root_layout); - } - - [Test] - public void TestCase91() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = -31; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.setBorder(Spacing.RIGHT, 5); - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 5; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 0; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 5; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout node with negative width", root_node, root_layout); - } - - [Test] - public void TestCase92() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.setBorder(Spacing.RIGHT, 1); - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.setMargin(Spacing.RIGHT, -8); - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 0; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should handle negative margin and min padding correctly", root_node, root_layout); - } - - [Test] - public void TestCase93() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.direction = CSSDirection.RTL; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.setBorder(Spacing.LEFT, 1); - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.setMargin(Spacing.LEFT, -8); - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 0; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 1; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should handle negative margin and min padding correctly in rtl", root_node, root_layout); - } - - [Test] - public void TestCase94() - { - 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.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 35; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 18; - } - - test("should layout node with just text", root_node, root_layout); - } - - [Test] - public void TestCase95() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 100; - node_0.setMeasureFunction(sTestMeasureFunction); - node_0.context = "measureWithRatio2"; - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 100; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 200; - } - - test("should layout node with fixed width and custom measure function", root_node, root_layout); - } - - [Test] - public void TestCase96() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_HEIGHT] = 100; - node_0.setMeasureFunction(sTestMeasureFunction); - node_0.context = "measureWithRatio2"; - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 200; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - - test("should layout node with fixed height and custom measure function", root_node, root_layout); - } - - [Test] - public void TestCase97() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 100; - node_0.style.dimensions[DIMENSION_HEIGHT] = 100; - node_0.setMeasureFunction(sTestMeasureFunction); - node_0.context = "measureWithRatio2"; - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 100; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - - test("should layout node with fixed height and fixed width, ignoring custom measure function", root_node, root_layout); - } - - [Test] - public void TestCase98() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.setMeasureFunction(sTestMeasureFunction); - node_0.context = "measureWithRatio2"; - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 99999; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 99999; - } - - test("should layout node with no fixed dimension and custom measure function", root_node, root_layout); - } - - [Test] - public void TestCase99() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.Column; - node_0.style.dimensions[DIMENSION_WIDTH] = 320; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.setMeasureFunction(sTestMeasureFunction); - node_1.context = "measureWithRatio2"; - node_1 = node_0.getChildAt(1); - node_1.style.flexDirection = CSSFlexDirection.Row; - node_1.style.overflow = CSSOverflow.Hidden; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_1, 2); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.setMeasureFunction(sTestMeasureFunction); - node_2.context = "measureWithRatio2"; - node_2 = node_1.getChildAt(1); - node_2.setMeasureFunction(sTestMeasureFunction); - node_2.context = "measureWithRatio2"; - } - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 320; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 740; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 320; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 640; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 640; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 320; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_1, 2); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 0; - node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 200; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_2 = node_1.getChildAt(1); - node_2.layout.position[POSITION_TOP] = 0; - node_2.layout.position[POSITION_LEFT] = 200; - node_2.layout.dimensions[DIMENSION_WIDTH] = 200; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - } - - test("should layout node with nested stacks and custom measure function", root_node, root_layout); - } - - [Test] - public void TestCase100() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 10; - node_0.setMeasureFunction(sTestMeasureFunction); - node_0.context = "small"; - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 10; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 18; - } - - test("should layout node with text and width", root_node, root_layout); - } - - [Test] - public void TestCase101() - { - 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.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 172; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 18; - } - - test("should layout node with text, padding and margin", root_node, root_layout); - } - - [Test] - public void TestCase102() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_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.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 300; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 0; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 300; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 0; - node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 300; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - } - - test("should layout node with nested alignSelf: stretch", root_node, root_layout); - } - - [Test] - public void TestCase103() - { - 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.dimensions[DIMENSION_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.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 500; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 18; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 500; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 18; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 0; - node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 500; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 18; - } - } - } - - test("should layout node with text and flex", root_node, root_layout); - } - - [Test] - public void TestCase104() - { - 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.direction = CSSDirection.RTL; - node_1.style.flexDirection = CSSFlexDirection.Row; - node_1.style.dimensions[DIMENSION_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.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 500; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 18; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 500; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 18; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 0; - node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 500; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 18; - } - } - } - - test("should layout node with text and flex in rtl", root_node, root_layout); - } - - [Test] - public void TestCase105() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_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.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 130; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 36; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 130; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 36; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 0; - node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 130; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 36; - } - } - } - - test("should layout node with text and stretch", root_node, root_layout); - } - - [Test] - public void TestCase106() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_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.dimensions[DIMENSION_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.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 200; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 36; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 200; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 36; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 0; - node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 130; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 36; - } - } - } - - test("should layout node with text stretch and width", root_node, root_layout); - } - - [Test] - public void TestCase107() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.alignSelf = CSSAlign.FlexStart; - node_0.style.dimensions[DIMENSION_WIDTH] = 100; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.alignSelf = CSSAlign.FlexStart; - node_1.setMeasureFunction(sTestMeasureFunction); - node_1.context = "loooooooooong with space"; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 100; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 36; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 36; - } - } - - test("should layout node with text bounded by parent", root_node, root_layout); - } - - [Test] - public void TestCase108() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.alignSelf = CSSAlign.FlexStart; - node_0.style.dimensions[DIMENSION_WIDTH] = 100; - node_0.setPadding(Spacing.LEFT, 10); - node_0.setPadding(Spacing.TOP, 10); - node_0.setPadding(Spacing.RIGHT, 10); - node_0.setPadding(Spacing.BOTTOM, 10); - node_0.setPadding(Spacing.START, 10); - node_0.setPadding(Spacing.END, 10); - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.alignSelf = CSSAlign.FlexStart; - node_1.setMargin(Spacing.LEFT, 10); - node_1.setMargin(Spacing.TOP, 10); - node_1.setMargin(Spacing.RIGHT, 10); - node_1.setMargin(Spacing.BOTTOM, 10); - node_1.setMargin(Spacing.START, 10); - node_1.setMargin(Spacing.END, 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.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 100; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 76; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 20; - node_1.layout.position[POSITION_LEFT] = 20; - node_1.layout.dimensions[DIMENSION_WIDTH] = 60; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 36; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 0; - node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 100; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 36; - } - } - } - - test("should layout node with text bounded by grand-parent", root_node, root_layout); - } - - [Test] - public void TestCase109() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.justifyContent = CSSJustify.SpaceBetween; - node_0.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_HEIGHT] = 900; - node_1 = node_0.getChildAt(1); - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 0; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 900; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 900; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout space-between when remaining space is negative", root_node, root_layout); - } - - [Test] - public void TestCase110() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.ColumnReverse; - node_0.style.justifyContent = CSSJustify.SpaceBetween; - node_0.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_HEIGHT] = 900; - node_1 = node_0.getChildAt(1); - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 0; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = -800; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 900; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = -800; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout space-between when remaining space is negative in reverse", root_node, root_layout); - } - - [Test] - public void TestCase111() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.justifyContent = CSSJustify.FlexEnd; - node_0.style.dimensions[DIMENSION_WIDTH] = 200; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 900; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 200; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 0; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = -700; - node_1.layout.dimensions[DIMENSION_WIDTH] = 900; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout flex-end when remaining space is negative", root_node, root_layout); - } - - [Test] - public void TestCase112() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.direction = CSSDirection.RTL; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.justifyContent = CSSJustify.FlexEnd; - node_0.style.dimensions[DIMENSION_WIDTH] = 200; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 900; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 200; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 0; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 900; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout flex-end when remaining space is negative in rtl", root_node, root_layout); - } - - [Test] - public void TestCase113() - { - 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.dimensions[DIMENSION_WIDTH] = 200; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.setMargin(Spacing.LEFT, 20); - node_2.setMargin(Spacing.TOP, 20); - node_2.setMargin(Spacing.RIGHT, 20); - node_2.setMargin(Spacing.BOTTOM, 20); - node_2.setMargin(Spacing.START, 20); - node_2.setMargin(Spacing.END, 20); - node_2.setMeasureFunction(sTestMeasureFunction); - node_2.context = "loooooooooong with space"; - } - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 200; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 58; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 200; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 58; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 20; - node_2.layout.position[POSITION_LEFT] = 20; - node_2.layout.dimensions[DIMENSION_WIDTH] = 172; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 18; - } - } - } - - test("should layout text with flexDirection row", root_node, root_layout); - } - - [Test] - public void TestCase114() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.direction = CSSDirection.RTL; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.flexDirection = CSSFlexDirection.Row; - node_1.style.dimensions[DIMENSION_WIDTH] = 200; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.setMargin(Spacing.LEFT, 20); - node_2.setMargin(Spacing.TOP, 20); - node_2.setMargin(Spacing.RIGHT, 20); - node_2.setMargin(Spacing.BOTTOM, 20); - node_2.setMargin(Spacing.START, 20); - node_2.setMargin(Spacing.END, 20); - node_2.setMeasureFunction(sTestMeasureFunction); - node_2.context = "loooooooooong with space"; - } - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 200; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 58; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 200; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 58; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 20; - node_2.layout.position[POSITION_LEFT] = 8; - node_2.layout.dimensions[DIMENSION_WIDTH] = 172; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 18; - } - } - } - - test("should layout text with flexDirection row in rtl", root_node, root_layout); - } - - [Test] - public void TestCase115() - { - 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.dimensions[DIMENSION_WIDTH] = 200; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.setMargin(Spacing.LEFT, 20); - node_2.setMargin(Spacing.TOP, 20); - node_2.setMargin(Spacing.RIGHT, 20); - node_2.setMargin(Spacing.BOTTOM, 20); - node_2.setMargin(Spacing.START, 20); - node_2.setMargin(Spacing.END, 20); - node_2.setMeasureFunction(sTestMeasureFunction); - node_2.context = "loooooooooong with space"; - } - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 200; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 76; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 200; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 76; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 20; - node_2.layout.position[POSITION_LEFT] = 20; - node_2.layout.dimensions[DIMENSION_WIDTH] = 160; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 36; - } - } - } - - test("should layout with text and margin", root_node, root_layout); - } - - [Test] - public void TestCase116() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 100; - node_0.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.positionType = CSSPositionType.Absolute; - node_1.style.position[POSITION_LEFT] = 0; - node_1.style.position[POSITION_TOP] = 0; - node_1.style.position[POSITION_RIGHT] = 0; - node_1.style.position[POSITION_BOTTOM] = 0; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 100; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - test("should layout with position absolute, top, left, bottom, right", root_node, root_layout); - } - - [Test] - public void TestCase117() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.alignSelf = CSSAlign.FlexStart; - node_0.style.dimensions[DIMENSION_WIDTH] = 100; - node_0.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.alignSelf = CSSAlign.FlexStart; - node_1.style.flex = 2.5f; - node_1 = node_0.getChildAt(1); - node_1.style.alignSelf = CSSAlign.FlexStart; - node_1.style.flex = 7.5f; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 100; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 25; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 25; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 75; - } - } - - test("should layout with arbitrary flex", root_node, root_layout); - } - - [Test] - public void TestCase118() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.ColumnReverse; - node_0.style.alignSelf = CSSAlign.FlexStart; - node_0.style.dimensions[DIMENSION_WIDTH] = 100; - node_0.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.alignSelf = CSSAlign.FlexStart; - node_1.style.flex = 2.5f; - node_1 = node_0.getChildAt(1); - node_1.style.alignSelf = CSSAlign.FlexStart; - node_1.style.flex = 7.5f; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 100; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 75; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 25; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 75; - } - } - - test("should layout with arbitrary flex in reverse", root_node, root_layout); - } - - [Test] - public void TestCase119() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.ColumnReverse; - node_0.style.alignSelf = CSSAlign.FlexStart; - node_0.style.dimensions[DIMENSION_WIDTH] = 100; - node_0.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.alignSelf = CSSAlign.FlexStart; - node_1.style.flex = -2.5f; - node_1 = node_0.getChildAt(1); - node_1.style.alignSelf = CSSAlign.FlexStart; - node_1.style.flex = 0; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 100; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 100; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 100; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout with negative flex in reverse", root_node, root_layout); - } - - [Test] - public void TestCase120() - { - 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.dimensions[DIMENSION_WIDTH] = 50; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.style.positionType = CSSPositionType.Absolute; - node_1.style.position[POSITION_LEFT] = 0; - node_1.style.position[POSITION_RIGHT] = 0; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 50; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 50; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 100; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 50; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout with position: absolute and another sibling", root_node, root_layout); - } - - [Test] - public void TestCase121() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.positionType = CSSPositionType.Absolute; - node_1.style.position[POSITION_TOP] = 0; - node_1.style.position[POSITION_BOTTOM] = 20; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 0; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 80; - } - } - - test("should calculate height properly with position: absolute top and bottom", root_node, root_layout); - } - - [Test] - public void TestCase122() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 200; - node_0.style.dimensions[DIMENSION_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.position[POSITION_LEFT] = 0; - node_1.style.position[POSITION_TOP] = 0; - node_1.style.position[POSITION_RIGHT] = 0; - node_1.style.position[POSITION_BOTTOM] = 0; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.style.dimensions[DIMENSION_WIDTH] = 100; - node_2.style.dimensions[DIMENSION_HEIGHT] = 100; - } - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 200; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 200; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 200; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 50; - node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 100; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - } - - test("should layout with complicated position: absolute and justifyContent: center combo", root_node, root_layout); - } - - [Test] - public void TestCase123() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.positionType = CSSPositionType.Absolute; - node_1.style.position[POSITION_BOTTOM] = 0; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 0; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 100; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should calculate top properly with position: absolute bottom", root_node, root_layout); - } - - [Test] - public void TestCase124() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 100; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.positionType = CSSPositionType.Absolute; - node_1.style.position[POSITION_RIGHT] = 0; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 100; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 0; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 100; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should calculate left properly with position: absolute right", root_node, root_layout); - } - - [Test] - public void TestCase125() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.positionType = CSSPositionType.Absolute; - node_1.style.dimensions[DIMENSION_HEIGHT] = 10; - node_1.style.position[POSITION_BOTTOM] = 0; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 0; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 90; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 10; - } - } - - test("should calculate top properly with position: absolute bottom and height", root_node, root_layout); - } - - [Test] - public void TestCase126() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 100; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.positionType = CSSPositionType.Absolute; - node_1.style.dimensions[DIMENSION_WIDTH] = 10; - node_1.style.position[POSITION_RIGHT] = 0; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 100; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 0; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 90; - node_1.layout.dimensions[DIMENSION_WIDTH] = 10; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should calculate left properly with position: absolute right and width", root_node, root_layout); - } - - [Test] - public void TestCase127() - { - 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.dimensions[DIMENSION_HEIGHT] = 10; - node_1.style.position[POSITION_BOTTOM] = 0; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 0; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 0; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = -10; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 10; - } - } - - test("should calculate top properly with position: absolute right, width, and no parent dimensions", root_node, root_layout); - } - - [Test] - public void TestCase128() - { - 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.dimensions[DIMENSION_WIDTH] = 10; - node_1.style.position[POSITION_RIGHT] = 0; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 0; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 0; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = -10; - node_1.layout.dimensions[DIMENSION_WIDTH] = 10; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should calculate left properly with position: absolute right, width, and no parent dimensions", root_node, root_layout); - } - - [Test] - public void TestCase129() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.justifyContent = CSSJustify.SpaceBetween; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.setBorder(Spacing.BOTTOM, 1); - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 0; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 1; - } - } - - test("should layout border bottom inside of justify content space between container", root_node, root_layout); - } - - [Test] - public void TestCase130() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.justifyContent = CSSJustify.Center; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.setMargin(Spacing.TOP, -6); - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 0; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 0; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = -3; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout negative margin top inside of justify content center container", root_node, root_layout); - } - - [Test] - public void TestCase131() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.justifyContent = CSSJustify.Center; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.setMargin(Spacing.TOP, 20); - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 0; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 20; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 20; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout positive margin top inside of justify content center container", root_node, root_layout); - } - - [Test] - public void TestCase132() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.justifyContent = CSSJustify.FlexEnd; - node_0.setBorder(Spacing.BOTTOM, 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.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 0; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 5; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout border bottom and flex end with an empty child", root_node, root_layout); - } - - [Test] - public void TestCase133() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 800; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.position[POSITION_LEFT] = 5; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - } - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 800; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 0; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 5; - node_1.layout.dimensions[DIMENSION_WIDTH] = 800; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 0; - node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 800; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - } - - test("should layout with children of a contain with left", root_node, root_layout); - } - - [Test] - public void TestCase134() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.flexWrap = CSSWrap.Wrap; - node_0.style.dimensions[DIMENSION_WIDTH] = 100; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 40; - node_1.style.dimensions[DIMENSION_HEIGHT] = 10; - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_WIDTH] = 40; - node_1.style.dimensions[DIMENSION_HEIGHT] = 10; - node_1 = node_0.getChildAt(2); - node_1.style.dimensions[DIMENSION_WIDTH] = 40; - node_1.style.dimensions[DIMENSION_HEIGHT] = 10; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 100; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 20; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 40; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 10; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 40; - node_1.layout.dimensions[DIMENSION_WIDTH] = 40; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 10; - node_1 = node_0.getChildAt(2); - node_1.layout.position[POSITION_TOP] = 10; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 40; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 10; - } - } - - test("should layout flex-wrap", root_node, root_layout); - } - - [Test] - public void TestCase135() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.direction = CSSDirection.RTL; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.flexWrap = CSSWrap.Wrap; - node_0.style.dimensions[DIMENSION_WIDTH] = 100; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 40; - node_1.style.dimensions[DIMENSION_HEIGHT] = 10; - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_WIDTH] = 40; - node_1.style.dimensions[DIMENSION_HEIGHT] = 10; - node_1 = node_0.getChildAt(2); - node_1.style.dimensions[DIMENSION_WIDTH] = 40; - node_1.style.dimensions[DIMENSION_HEIGHT] = 10; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 100; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 20; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 60; - node_1.layout.dimensions[DIMENSION_WIDTH] = 40; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 10; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 20; - node_1.layout.dimensions[DIMENSION_WIDTH] = 40; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 10; - node_1 = node_0.getChildAt(2); - node_1.layout.position[POSITION_TOP] = 10; - node_1.layout.position[POSITION_LEFT] = 60; - node_1.layout.dimensions[DIMENSION_WIDTH] = 40; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 10; - } - } - - test("should layout flex-wrap in rtl", root_node, root_layout); - } - - [Test] - public void TestCase136() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexWrap = CSSWrap.Wrap; - node_0.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_HEIGHT] = 200; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 0; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - } - } - - test("should layout flex wrap with a line bigger than container", root_node, root_layout); - } - - [Test] - public void TestCase137() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 100; - node_0.style.dimensions[DIMENSION_HEIGHT] = 200; - node_0.style.maxWidth = 90; - node_0.style.maxHeight = 190; - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 90; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 190; - } - - test("should use max bounds", root_node, root_layout); - } - - [Test] - public void TestCase138() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 100; - node_0.style.dimensions[DIMENSION_HEIGHT] = 200; - node_0.style.minWidth = 110; - node_0.style.minHeight = 210; - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 110; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 210; - } - - test("should use min bounds", root_node, root_layout); - } - - [Test] - public void TestCase139() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 100; - node_0.style.dimensions[DIMENSION_HEIGHT] = 200; - node_0.style.maxWidth = 90; - node_0.style.maxHeight = 190; - node_0.style.minWidth = 110; - node_0.style.minHeight = 210; - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 110; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 210; - } - - test("should use min bounds over max bounds", root_node, root_layout); - } - - [Test] - public void TestCase140() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 100; - node_0.style.dimensions[DIMENSION_HEIGHT] = 200; - node_0.style.maxWidth = 80; - node_0.style.maxHeight = 180; - node_0.style.minWidth = 90; - node_0.style.minHeight = 190; - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 90; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 190; - } - - test("should use min bounds over max bounds and natural width", root_node, root_layout); - } - - [Test] - public void TestCase141() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 100; - node_0.style.dimensions[DIMENSION_HEIGHT] = 200; - node_0.style.minWidth = -10; - node_0.style.minHeight = -20; - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 100; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 200; - } - - test("should ignore negative min bounds", root_node, root_layout); - } - - [Test] - public void TestCase142() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 100; - node_0.style.dimensions[DIMENSION_HEIGHT] = 200; - node_0.style.maxWidth = -10; - node_0.style.maxHeight = -20; - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 100; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 200; - } - - test("should ignore negative max bounds", root_node, root_layout); - } - - [Test] - public void TestCase143() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.maxWidth = 30; - node_0.style.maxHeight = 10; - node_0.setPadding(Spacing.LEFT, 20); - node_0.setPadding(Spacing.TOP, 15); - node_0.setPadding(Spacing.RIGHT, 20); - node_0.setPadding(Spacing.BOTTOM, 15); - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 40; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 30; - } - - test("should use padded size over max bounds", root_node, root_layout); - } - - [Test] - public void TestCase144() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.minWidth = 50; - node_0.style.minHeight = 40; - node_0.setPadding(Spacing.LEFT, 20); - node_0.setPadding(Spacing.TOP, 15); - node_0.setPadding(Spacing.RIGHT, 20); - node_0.setPadding(Spacing.BOTTOM, 15); - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 50; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 40; - } - - test("should use min size over padded size", root_node, root_layout); - } - - [Test] - public void TestCase145() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.dimensions[DIMENSION_WIDTH] = 300; - node_0.style.dimensions[DIMENSION_HEIGHT] = 200; - 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.flex = 1; - node_1.style.minWidth = 200; - node_1 = node_0.getChildAt(2); - node_1.style.flex = 1; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 300; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 200; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 50; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 50; - node_1.layout.dimensions[DIMENSION_WIDTH] = 200; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - node_1 = node_0.getChildAt(2); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 250; - node_1.layout.dimensions[DIMENSION_WIDTH] = 50; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - } - } - - test("should override flex direction size with min bounds", root_node, root_layout); - } - - [Test] - public void TestCase146() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.direction = CSSDirection.RTL; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.dimensions[DIMENSION_WIDTH] = 300; - node_0.style.dimensions[DIMENSION_HEIGHT] = 200; - 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.flex = 1; - node_1.style.minWidth = 200; - node_1 = node_0.getChildAt(2); - node_1.style.flex = 1; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 300; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 200; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 250; - node_1.layout.dimensions[DIMENSION_WIDTH] = 50; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 50; - node_1.layout.dimensions[DIMENSION_WIDTH] = 200; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - node_1 = node_0.getChildAt(2); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 50; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - } - } - - test("should override flex direction size with min bounds in rtl", root_node, root_layout); - } - - [Test] - public void TestCase147() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.dimensions[DIMENSION_WIDTH] = 300; - node_0.style.dimensions[DIMENSION_HEIGHT] = 200; - 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.flex = 1; - node_1.style.maxWidth = 110; - node_1.style.minWidth = 90; - node_1 = node_0.getChildAt(2); - node_1.style.flex = 1; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 300; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 200; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 100; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - node_1 = node_0.getChildAt(2); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 200; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - } - } - - test("should not override flex direction size within bounds", root_node, root_layout); - } - - [Test] - public void TestCase148() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.direction = CSSDirection.RTL; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.dimensions[DIMENSION_WIDTH] = 300; - node_0.style.dimensions[DIMENSION_HEIGHT] = 200; - 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.flex = 1; - node_1.style.maxWidth = 110; - node_1.style.minWidth = 90; - node_1 = node_0.getChildAt(2); - node_1.style.flex = 1; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 300; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 200; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 200; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 100; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - node_1 = node_0.getChildAt(2); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - } - } - - test("should not override flex direction size within bounds in rtl", root_node, root_layout); - } - - [Test] - public void TestCase149() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.dimensions[DIMENSION_WIDTH] = 300; - node_0.style.dimensions[DIMENSION_HEIGHT] = 200; - 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.flex = 1; - node_1.style.maxWidth = 60; - node_1 = node_0.getChildAt(2); - node_1.style.flex = 1; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 300; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 200; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 120; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 120; - node_1.layout.dimensions[DIMENSION_WIDTH] = 60; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - node_1 = node_0.getChildAt(2); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 180; - node_1.layout.dimensions[DIMENSION_WIDTH] = 120; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - } - } - - test("should override flex direction size with max bounds", root_node, root_layout); - } - - [Test] - public void TestCase150() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.direction = CSSDirection.RTL; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.dimensions[DIMENSION_WIDTH] = 300; - node_0.style.dimensions[DIMENSION_HEIGHT] = 200; - 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.flex = 1; - node_1.style.maxWidth = 60; - node_1 = node_0.getChildAt(2); - node_1.style.flex = 1; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 300; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 200; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 180; - node_1.layout.dimensions[DIMENSION_WIDTH] = 120; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 120; - node_1.layout.dimensions[DIMENSION_WIDTH] = 60; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - node_1 = node_0.getChildAt(2); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 120; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - } - } - - test("should override flex direction size with max bounds in rtl", root_node, root_layout); - } - - [Test] - public void TestCase151() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.dimensions[DIMENSION_WIDTH] = 300; - node_0.style.dimensions[DIMENSION_HEIGHT] = 200; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.flex = 1; - node_1.style.maxWidth = 60; - node_1 = node_0.getChildAt(1); - node_1.style.flex = 1; - node_1.style.maxWidth = 60; - node_1 = node_0.getChildAt(2); - node_1.style.flex = 1; - node_1.style.maxWidth = 60; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 300; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 200; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 60; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 60; - node_1.layout.dimensions[DIMENSION_WIDTH] = 60; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - node_1 = node_0.getChildAt(2); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 120; - node_1.layout.dimensions[DIMENSION_WIDTH] = 60; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - } - } - - test("should ignore flex size if fully max bound", root_node, root_layout); - } - - [Test] - public void TestCase152() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.direction = CSSDirection.RTL; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.dimensions[DIMENSION_WIDTH] = 300; - node_0.style.dimensions[DIMENSION_HEIGHT] = 200; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.flex = 1; - node_1.style.maxWidth = 60; - node_1 = node_0.getChildAt(1); - node_1.style.flex = 1; - node_1.style.maxWidth = 60; - node_1 = node_0.getChildAt(2); - node_1.style.flex = 1; - node_1.style.maxWidth = 60; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 300; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 200; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 240; - node_1.layout.dimensions[DIMENSION_WIDTH] = 60; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 180; - node_1.layout.dimensions[DIMENSION_WIDTH] = 60; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - node_1 = node_0.getChildAt(2); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 120; - node_1.layout.dimensions[DIMENSION_WIDTH] = 60; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - } - } - - test("should ignore flex size if fully max bound in rtl", root_node, root_layout); - } - - [Test] - public void TestCase153() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.dimensions[DIMENSION_WIDTH] = 300; - node_0.style.dimensions[DIMENSION_HEIGHT] = 200; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.flex = 1; - node_1.style.minWidth = 120; - node_1 = node_0.getChildAt(1); - node_1.style.flex = 1; - node_1.style.minWidth = 120; - node_1 = node_0.getChildAt(2); - node_1.style.flex = 1; - node_1.style.minWidth = 120; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 300; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 200; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 120; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 120; - node_1.layout.dimensions[DIMENSION_WIDTH] = 120; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - node_1 = node_0.getChildAt(2); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 240; - node_1.layout.dimensions[DIMENSION_WIDTH] = 120; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - } - } - - test("should ignore flex size if fully min bound", root_node, root_layout); - } - - [Test] - public void TestCase154() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.direction = CSSDirection.RTL; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.dimensions[DIMENSION_WIDTH] = 300; - node_0.style.dimensions[DIMENSION_HEIGHT] = 200; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.flex = 1; - node_1.style.minWidth = 120; - node_1 = node_0.getChildAt(1); - node_1.style.flex = 1; - node_1.style.minWidth = 120; - node_1 = node_0.getChildAt(2); - node_1.style.flex = 1; - node_1.style.minWidth = 120; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 300; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 200; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 180; - node_1.layout.dimensions[DIMENSION_WIDTH] = 120; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 60; - node_1.layout.dimensions[DIMENSION_WIDTH] = 120; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - node_1 = node_0.getChildAt(2); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = -60; - node_1.layout.dimensions[DIMENSION_WIDTH] = 120; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - } - } - - test("should ignore flex size if fully min bound in rtl", root_node, root_layout); - } - - [Test] - public void TestCase155() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 300; - node_0.style.dimensions[DIMENSION_HEIGHT] = 200; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.flex = 1; - node_1.style.maxWidth = 310; - node_1.style.minWidth = 290; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 300; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 200; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 300; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - } - } - - test("should pre-fill child size within bounds", root_node, root_layout); - } - - [Test] - public void TestCase156() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 300; - node_0.style.dimensions[DIMENSION_HEIGHT] = 200; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.flex = 1; - node_1.style.maxWidth = 290; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 300; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 200; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 290; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - } - } - - test("should pre-fill child size within max bound", root_node, root_layout); - } - - [Test] - public void TestCase157() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 300; - node_0.style.dimensions[DIMENSION_HEIGHT] = 200; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.flex = 1; - node_1.style.minWidth = 310; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 300; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 200; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 310; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - } - } - - test("should pre-fill child size within min bounds", root_node, root_layout); - } - - [Test] - public void TestCase158() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.maxWidth = 300; - node_0.style.maxHeight = 700; - node_0.style.minWidth = 100; - node_0.style.minHeight = 500; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 200; - node_1.style.dimensions[DIMENSION_HEIGHT] = 300; - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_WIDTH] = 200; - node_1.style.dimensions[DIMENSION_HEIGHT] = 300; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 200; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 600; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 200; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 300; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 300; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 200; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 300; - } - } - - test("should set parents size based on bounded children", root_node, root_layout); - } - - [Test] - public void TestCase159() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.maxWidth = 100; - node_0.style.maxHeight = 500; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 200; - node_1.style.dimensions[DIMENSION_HEIGHT] = 300; - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_WIDTH] = 200; - node_1.style.dimensions[DIMENSION_HEIGHT] = 300; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 100; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 500; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 200; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 300; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 300; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 200; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 300; - } - } - - test("should set parents size based on max bounded children", root_node, root_layout); - } - - [Test] - public void TestCase160() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.minWidth = 300; - node_0.style.minHeight = 700; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 200; - node_1.style.dimensions[DIMENSION_HEIGHT] = 300; - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_WIDTH] = 200; - node_1.style.dimensions[DIMENSION_HEIGHT] = 300; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 300; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 700; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 200; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 300; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 300; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 200; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 300; - } - } - - test("should set parents size based on min bounded children", root_node, root_layout); - } - - [Test] - public void TestCase161() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.alignItems = CSSAlign.Stretch; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1.style.maxWidth = 1100; - node_1.style.maxHeight = 110; - node_1.style.minWidth = 900; - node_1.style.minHeight = 90; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - test("should keep stretched size within bounds", root_node, root_layout); - } - - [Test] - public void TestCase162() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.alignItems = CSSAlign.Stretch; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1.style.maxWidth = 900; - node_1.style.maxHeight = 90; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 90; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 900; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 90; - } - } - - test("should keep stretched size within max bounds", root_node, root_layout); - } - - [Test] - public void TestCase163() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.alignItems = CSSAlign.Stretch; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1.style.minWidth = 1100; - node_1.style.minHeight = 110; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 110; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 1100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 110; - } - } - - test("should keep stretched size within min bounds", root_node, root_layout); - } - - [Test] - public void TestCase164() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1.style.minWidth = 100; - node_1.style.minHeight = 110; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 110; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 110; - } - } - - test("should keep cross axis size within min bounds", root_node, root_layout); - } - - [Test] - public void TestCase165() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.direction = CSSDirection.RTL; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1.style.minWidth = 100; - node_1.style.minHeight = 110; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 110; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 900; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 110; - } - } - - test("should keep cross axis size within min bounds in rtl", root_node, root_layout); - } - - [Test] - public void TestCase166() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.positionType = CSSPositionType.Absolute; - node_1.style.maxWidth = 500; - node_1.style.maxHeight = 600; - node_1.style.position[POSITION_LEFT] = 100; - node_1.style.position[POSITION_TOP] = 100; - node_1.style.position[POSITION_RIGHT] = 100; - node_1.style.position[POSITION_BOTTOM] = 100; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 100; - node_1.layout.position[POSITION_LEFT] = 100; - node_1.layout.dimensions[DIMENSION_WIDTH] = 500; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 600; - } - } - - test("should layout node with position absolute, top and left and max bounds", root_node, root_layout); - } - - [Test] - public void TestCase167() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.positionType = CSSPositionType.Absolute; - node_1.style.minWidth = 900; - node_1.style.minHeight = 1000; - node_1.style.position[POSITION_LEFT] = 100; - node_1.style.position[POSITION_TOP] = 100; - node_1.style.position[POSITION_RIGHT] = 100; - node_1.style.position[POSITION_BOTTOM] = 100; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 100; - node_1.layout.position[POSITION_LEFT] = 100; - node_1.layout.dimensions[DIMENSION_WIDTH] = 900; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 1000; - } - } - - test("should layout node with position absolute, top and left and min bounds", root_node, root_layout); - } - - [Test] - public void TestCase168() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.justifyContent = CSSJustify.Center; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.flex = 1; - node_1.style.dimensions[DIMENSION_HEIGHT] = 1000; - node_1.style.maxWidth = 600; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 200; - node_1.layout.dimensions[DIMENSION_WIDTH] = 600; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 1000; - } - } - - test("should center flexible item with max size", root_node, root_layout); - } - - [Test] - public void TestCase169() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.dimensions[DIMENSION_WIDTH] = 1000; - node_0.style.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.flex = 1; - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 1000; - node_1 = node_0.getChildAt(1); - node_1.style.flex = 1; - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 1000; - node_1.style.maxWidth = 200; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 1000; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 1000; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 800; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 1000; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 800; - node_1.layout.dimensions[DIMENSION_WIDTH] = 200; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 1000; - } - } - - test("should correctly size flexible items with flex basis and a max width", root_node, root_layout); - } - - [Test] - public void TestCase170() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 400; - node_0.style.dimensions[DIMENSION_HEIGHT] = 400; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.positionType = CSSPositionType.Absolute; - node_1.setPadding(Spacing.LEFT, 10); - node_1.setPadding(Spacing.TOP, 10); - node_1.setPadding(Spacing.RIGHT, 10); - node_1.setPadding(Spacing.BOTTOM, 10); - node_1.setPadding(Spacing.START, 10); - node_1.setPadding(Spacing.END, 10); - node_1.style.position[POSITION_LEFT] = 100; - node_1.style.position[POSITION_TOP] = 100; - node_1.style.position[POSITION_RIGHT] = 100; - node_1.style.position[POSITION_BOTTOM] = 100; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.style.positionType = CSSPositionType.Absolute; - node_2.style.position[POSITION_LEFT] = 10; - node_2.style.position[POSITION_TOP] = 10; - node_2.style.position[POSITION_RIGHT] = 10; - node_2.style.position[POSITION_BOTTOM] = 10; - } - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 400; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 400; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 100; - node_1.layout.position[POSITION_LEFT] = 100; - node_1.layout.dimensions[DIMENSION_WIDTH] = 200; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 10; - node_2.layout.position[POSITION_LEFT] = 10; - node_2.layout.dimensions[DIMENSION_WIDTH] = 180; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 180; - } - } - } - - test("should layout absolutely positioned node with absolutely positioned padded parent", root_node, root_layout); - } - - [Test] - public void TestCase171() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 400; - node_0.style.dimensions[DIMENSION_HEIGHT] = 400; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.positionType = CSSPositionType.Absolute; - node_1.setPadding(Spacing.LEFT, 10); - node_1.setPadding(Spacing.TOP, 10); - node_1.setPadding(Spacing.RIGHT, 10); - node_1.setPadding(Spacing.BOTTOM, 10); - node_1.setPadding(Spacing.START, 10); - node_1.setPadding(Spacing.END, 10); - node_1.setBorder(Spacing.LEFT, 1); - node_1.setBorder(Spacing.TOP, 1); - node_1.setBorder(Spacing.RIGHT, 1); - node_1.setBorder(Spacing.BOTTOM, 1); - node_1.setBorder(Spacing.START, 1); - node_1.setBorder(Spacing.END, 1); - node_1.style.position[POSITION_LEFT] = 100; - node_1.style.position[POSITION_TOP] = 100; - node_1.style.position[POSITION_RIGHT] = 100; - node_1.style.position[POSITION_BOTTOM] = 100; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.style.positionType = CSSPositionType.Absolute; - node_2.style.position[POSITION_LEFT] = 10; - node_2.style.position[POSITION_TOP] = 10; - node_2.style.position[POSITION_RIGHT] = 10; - node_2.style.position[POSITION_BOTTOM] = 10; - } - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 400; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 400; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 100; - node_1.layout.position[POSITION_LEFT] = 100; - node_1.layout.dimensions[DIMENSION_WIDTH] = 200; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 11; - node_2.layout.position[POSITION_LEFT] = 11; - node_2.layout.dimensions[DIMENSION_WIDTH] = 178; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 178; - } - } - } - - test("should layout absolutely positioned node with absolutely positioned padded and bordered parent", root_node, root_layout); - } - - [Test] - public void TestCase172() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 400; - node_0.style.dimensions[DIMENSION_HEIGHT] = 400; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.flex = 1; - node_1.setPadding(Spacing.LEFT, 10); - node_1.setPadding(Spacing.TOP, 10); - node_1.setPadding(Spacing.RIGHT, 10); - node_1.setPadding(Spacing.BOTTOM, 10); - node_1.setPadding(Spacing.START, 10); - node_1.setPadding(Spacing.END, 10); - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.style.positionType = CSSPositionType.Absolute; - node_2.style.position[POSITION_LEFT] = 10; - node_2.style.position[POSITION_TOP] = 10; - node_2.style.position[POSITION_RIGHT] = 10; - node_2.style.position[POSITION_BOTTOM] = 10; - } - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 400; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 400; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 400; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 400; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 10; - node_2.layout.position[POSITION_LEFT] = 10; - node_2.layout.dimensions[DIMENSION_WIDTH] = 380; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 380; - } - } - } - - test("should layout absolutely positioned node with padded flex 1 parent", root_node, root_layout); - } - - [Test] - public void TestCase173() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.direction = CSSDirection.RTL; - node_0.style.dimensions[DIMENSION_WIDTH] = 200; - node_0.style.dimensions[DIMENSION_HEIGHT] = 200; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.flexDirection = CSSFlexDirection.Row; - addChildren(node_1, 2); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.style.dimensions[DIMENSION_WIDTH] = 50; - node_2.style.dimensions[DIMENSION_HEIGHT] = 50; - node_2 = node_1.getChildAt(1); - node_2.style.dimensions[DIMENSION_WIDTH] = 50; - node_2.style.dimensions[DIMENSION_HEIGHT] = 50; - } - node_1 = node_0.getChildAt(1); - node_1.style.direction = CSSDirection.LTR; - node_1.style.flexDirection = CSSFlexDirection.Row; - addChildren(node_1, 2); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.style.dimensions[DIMENSION_WIDTH] = 50; - node_2.style.dimensions[DIMENSION_HEIGHT] = 50; - node_2 = node_1.getChildAt(1); - node_2.style.dimensions[DIMENSION_WIDTH] = 50; - node_2.style.dimensions[DIMENSION_HEIGHT] = 50; - } - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 200; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 200; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 200; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 50; - addChildren(node_1, 2); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 0; - node_2.layout.position[POSITION_LEFT] = 150; - node_2.layout.dimensions[DIMENSION_WIDTH] = 50; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 50; - node_2 = node_1.getChildAt(1); - node_2.layout.position[POSITION_TOP] = 0; - node_2.layout.position[POSITION_LEFT] = 100; - node_2.layout.dimensions[DIMENSION_WIDTH] = 50; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 50; - } - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 50; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 200; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 50; - addChildren(node_1, 2); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 0; - node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 50; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 50; - node_2 = node_1.getChildAt(1); - node_2.layout.position[POSITION_TOP] = 0; - node_2.layout.position[POSITION_LEFT] = 50; - node_2.layout.dimensions[DIMENSION_WIDTH] = 50; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 50; - } - } - } - - test("should layout nested nodes with mixed directions", root_node, root_layout); - } - - [Test] - public void TestCase174() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.justifyContent = CSSJustify.SpaceBetween; - node_0.style.flexWrap = CSSWrap.Wrap; - node_0.style.dimensions[DIMENSION_WIDTH] = 320; - node_0.style.dimensions[DIMENSION_HEIGHT] = 200; - addChildren(node_0, 6); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(2); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(3); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(4); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(5); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 320; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 200; - addChildren(node_0, 6); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 110; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(2); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 220; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(3); - node_1.layout.position[POSITION_TOP] = 100; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(4); - node_1.layout.position[POSITION_TOP] = 100; - node_1.layout.position[POSITION_LEFT] = 110; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(5); - node_1.layout.position[POSITION_TOP] = 100; - node_1.layout.position[POSITION_LEFT] = 220; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - test("should correctly space wrapped nodes", root_node, root_layout); - } - - [Test] - public void TestCase175() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 200; - node_0.setPadding(Spacing.LEFT, 5); - node_0.setPadding(Spacing.RIGHT, 5); - node_0.setPadding(Spacing.START, 15); - node_0.setPadding(Spacing.END, 15); - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_HEIGHT] = 50; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 200; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 50; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 15; - node_1.layout.dimensions[DIMENSION_WIDTH] = 170; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 50; - } - } - - test("should give start/end padding precedence over left/right padding", root_node, root_layout); - } - - [Test] - public void TestCase176() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 200; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_HEIGHT] = 50; - node_1.setMargin(Spacing.LEFT, 5); - node_1.setMargin(Spacing.RIGHT, 5); - node_1.setMargin(Spacing.START, 15); - node_1.setMargin(Spacing.END, 15); - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 200; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 50; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 15; - node_1.layout.dimensions[DIMENSION_WIDTH] = 170; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 50; - } - } - - test("should give start/end margin precedence over left/right margin", root_node, root_layout); - } - - [Test] - public void TestCase177() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 200; - node_0.setBorder(Spacing.LEFT, 5); - node_0.setBorder(Spacing.RIGHT, 5); - node_0.setBorder(Spacing.START, 15); - node_0.setBorder(Spacing.END, 15); - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_HEIGHT] = 50; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 200; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 50; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 15; - node_1.layout.dimensions[DIMENSION_WIDTH] = 170; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 50; - } - } - - test("should give start/end border precedence over left/right border", root_node, root_layout); - } - - [Test] - public void TestCase178() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 200; - node_0.setPadding(Spacing.START, 15); - node_0.setPadding(Spacing.END, 5); - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_HEIGHT] = 50; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 200; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 50; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 15; - node_1.layout.dimensions[DIMENSION_WIDTH] = 180; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 50; - } - } - - test("should layout node with correct start/end padding", root_node, root_layout); - } - - [Test] - public void TestCase179() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.direction = CSSDirection.RTL; - node_0.style.dimensions[DIMENSION_WIDTH] = 200; - node_0.setPadding(Spacing.START, 15); - node_0.setPadding(Spacing.END, 5); - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_HEIGHT] = 50; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 200; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 50; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 5; - node_1.layout.dimensions[DIMENSION_WIDTH] = 180; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 50; - } - } - - test("should layout node with correct start/end padding in rtl", root_node, root_layout); - } - - [Test] - public void TestCase180() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 200; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_HEIGHT] = 50; - node_1.setMargin(Spacing.START, 15); - node_1.setMargin(Spacing.END, 5); - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 200; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 50; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 15; - node_1.layout.dimensions[DIMENSION_WIDTH] = 180; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 50; - } - } - - test("should layout node with correct start/end margin", root_node, root_layout); - } - - [Test] - public void TestCase181() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 200; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.direction = CSSDirection.RTL; - node_1.style.dimensions[DIMENSION_HEIGHT] = 50; - node_1.setMargin(Spacing.START, 15); - node_1.setMargin(Spacing.END, 5); - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 200; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 50; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 5; - node_1.layout.dimensions[DIMENSION_WIDTH] = 180; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 50; - } - } - - test("should layout node with correct start/end margin in rtl", root_node, root_layout); - } - - [Test] - public void TestCase182() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 200; - node_0.setBorder(Spacing.START, 15); - node_0.setBorder(Spacing.END, 5); - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_HEIGHT] = 50; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 200; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 50; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 15; - node_1.layout.dimensions[DIMENSION_WIDTH] = 180; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 50; - } - } - - test("should layout node with correct start/end border", root_node, root_layout); - } - - [Test] - public void TestCase183() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.direction = CSSDirection.RTL; - node_0.style.dimensions[DIMENSION_WIDTH] = 200; - node_0.setBorder(Spacing.START, 15); - node_0.setBorder(Spacing.END, 5); - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_HEIGHT] = 50; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 200; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 50; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 5; - node_1.layout.dimensions[DIMENSION_WIDTH] = 180; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 50; - } - } - - test("should layout node with correct start/end border in rtl", root_node, root_layout); - } - - [Test] - public void TestCase184() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 200; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 0; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 200; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 0; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - - test("should layout node with a 0 width", root_node, root_layout); - } - - [Test] - public void TestCase185() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.alignItems = CSSAlign.FlexStart; - node_0.style.dimensions[DIMENSION_WIDTH] = 100; - node_0.style.dimensions[DIMENSION_HEIGHT] = 10; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 50; - node_1.style.dimensions[DIMENSION_HEIGHT] = 10; - node_1 = node_0.getChildAt(1); - node_1.style.flexDirection = CSSFlexDirection.Column; - node_1.style.alignItems = CSSAlign.FlexStart; - node_1.style.flex = 1; - node_1.style.dimensions[DIMENSION_HEIGHT] = 10; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.style.flex = 1; - node_2.style.dimensions[DIMENSION_HEIGHT] = 10; - node_2.setMeasureFunction(sTestMeasureFunction); - node_2.context = "measureWithMatchParent"; - } - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 100; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 10; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 50; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 10; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 50; - node_1.layout.dimensions[DIMENSION_WIDTH] = 50; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 10; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 0; - node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 50; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 10; - } - } - } - - test("should correctly progagate size contraints from flexible parents", root_node, root_layout); - } - - [Test] - public void TestCase186() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.alignItems = CSSAlign.Stretch; - node_0.style.dimensions[DIMENSION_WIDTH] = 150; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.flexDirection = CSSFlexDirection.Row; - node_1.setMargin(Spacing.LEFT, 10); - node_1.setMargin(Spacing.TOP, 10); - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.style.flexDirection = CSSFlexDirection.Row; - addChildren(node_2, 1); - { - TestCSSNode node_3; - node_3 = node_2.getChildAt(0); - node_3.style.alignSelf = CSSAlign.Center; - } - } - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_HEIGHT] = 150; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 150; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 150; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 10; - node_1.layout.position[POSITION_LEFT] = 10; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 140; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 0; - node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 0; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 140; - addChildren(node_2, 1); - { - TestCSSNode node_3; - node_3 = node_2.getChildAt(0); - node_3.layout.position[POSITION_TOP] = 70; - node_3.layout.position[POSITION_LEFT] = 0; - node_3.layout.dimensions[DIMENSION_WIDTH] = 0; - node_3.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 10; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 150; - } - } - - test("should layout content of an item which is stretched late", root_node, root_layout); - } - - [Test] - public void TestCase187() - { - 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.dimensions[DIMENSION_WIDTH] = 200; - node_2.style.dimensions[DIMENSION_HEIGHT] = 200; - } - node_1 = node_0.getChildAt(1); - node_1.setMargin(Spacing.LEFT, 10); - node_1.setMargin(Spacing.TOP, 10); - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - } - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 200; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 210; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 200; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 200; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 0; - node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 200; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 200; - } - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 210; - node_1.layout.position[POSITION_LEFT] = 10; - node_1.layout.dimensions[DIMENSION_WIDTH] = 190; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 0; - node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 190; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 0; - } - } - } - - test("should layout items whose positioning is determined by sibling tree branches", root_node, root_layout); - } - - [Test] - public void TestCase188() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.Row; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.alignSelf = CSSAlign.FlexStart; - node_1.setMargin(Spacing.LEFT, 10); - node_1.setMargin(Spacing.TOP, 10); - node_1 = node_0.getChildAt(1); - node_1.style.alignSelf = CSSAlign.Stretch; - node_1.style.dimensions[DIMENSION_WIDTH] = 1; - node_1 = node_0.getChildAt(2); - node_1.style.dimensions[DIMENSION_HEIGHT] = 150; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 11; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 150; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 10; - node_1.layout.position[POSITION_LEFT] = 10; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 0; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 10; - node_1.layout.dimensions[DIMENSION_WIDTH] = 1; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 150; - node_1 = node_0.getChildAt(2); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 11; - node_1.layout.dimensions[DIMENSION_WIDTH] = 0; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 150; - } - } - - test("should layout child whose cross axis is null and whose alignSelf is stretch", root_node, root_layout); - } - - [Test] - public void TestCase189() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.Row; - 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.dimensions[DIMENSION_WIDTH] = 100; - node_2.style.dimensions[DIMENSION_HEIGHT] = 100; - } - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.style.flexDirection = CSSFlexDirection.Column; - node_2.style.alignItems = CSSAlign.Center; - addChildren(node_2, 1); - { - TestCSSNode node_3; - node_3 = node_2.getChildAt(0); - node_3.style.dimensions[DIMENSION_WIDTH] = 50; - node_3.style.dimensions[DIMENSION_HEIGHT] = 50; - } - } - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 200; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 2); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 0; - node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 100; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 100; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 0; - node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 100; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 50; - addChildren(node_2, 1); - { - TestCSSNode node_3; - node_3 = node_2.getChildAt(0); - node_3.layout.position[POSITION_TOP] = 0; - node_3.layout.position[POSITION_LEFT] = 25; - node_3.layout.dimensions[DIMENSION_WIDTH] = 50; - node_3.layout.dimensions[DIMENSION_HEIGHT] = 50; - } - } - } - } - - test("should center items correctly inside a stretched layout", root_node, root_layout); - } - - [Test] - public void TestCase190() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 100; - node_0.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.flex = -1; - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.style.dimensions[DIMENSION_WIDTH] = 100; - node_2.style.dimensions[DIMENSION_HEIGHT] = 25; - } - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 100; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 25; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 0; - node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 100; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 25; - } - } - } - - test("should not shrink column node when there is space left over", root_node, root_layout); - } - - [Test] - public void TestCase191() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 100; - node_0.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.flex = -1; - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.style.dimensions[DIMENSION_WIDTH] = 100; - node_2.style.dimensions[DIMENSION_HEIGHT] = 200; - } - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 100; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 0; - node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 100; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 200; - } - } - } - - test("should shrink column node when there is not any space left over", root_node, root_layout); - } - - [Test] - public void TestCase192() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 100; - node_0.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 25; - node_1 = node_0.getChildAt(1); - node_1.style.flex = -1; - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.style.dimensions[DIMENSION_WIDTH] = 100; - node_2.style.dimensions[DIMENSION_HEIGHT] = 30; - } - node_1 = node_0.getChildAt(2); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 15; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 100; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 25; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 25; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 30; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 0; - node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 100; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 30; - } - node_1 = node_0.getChildAt(2); - node_1.layout.position[POSITION_TOP] = 55; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 15; - } - } - - test("should not shrink column node with siblings when there is space left over", root_node, root_layout); - } - - [Test] - public void TestCase193() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 100; - node_0.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 25; - node_1 = node_0.getChildAt(1); - node_1.style.flex = -1; - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.style.dimensions[DIMENSION_WIDTH] = 100; - node_2.style.dimensions[DIMENSION_HEIGHT] = 80; - } - node_1 = node_0.getChildAt(2); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 15; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 100; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 25; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 25; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 60; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 0; - node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 100; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 80; - } - node_1 = node_0.getChildAt(2); - node_1.layout.position[POSITION_TOP] = 85; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 15; - } - } - - test("should shrink column node with siblings when there is not any space left over", root_node, root_layout); - } - - [Test] - public void TestCase194() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.dimensions[DIMENSION_WIDTH] = 100; - node_0.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.flex = -1; - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 30; - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 40; - node_1 = node_0.getChildAt(2); - node_1.style.flex = -1; - node_1.style.dimensions[DIMENSION_WIDTH] = 100; - node_1.style.dimensions[DIMENSION_HEIGHT] = 50; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 100; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 22.5f; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 22.5f; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 40; - node_1 = node_0.getChildAt(2); - node_1.layout.position[POSITION_TOP] = 62.5f; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 37.5f; - } - } - - test("should shrink column nodes proportional to their main size when there is not any space left over", root_node, root_layout); - } - - [Test] - public void TestCase195() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.dimensions[DIMENSION_WIDTH] = 100; - node_0.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.flex = -1; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.style.dimensions[DIMENSION_WIDTH] = 25; - node_2.style.dimensions[DIMENSION_HEIGHT] = 100; - } - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 100; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 25; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 0; - node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 25; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - } - - test("should not shrink visible row node when there is space left over", root_node, root_layout); - } - - [Test] - public void TestCase196() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.dimensions[DIMENSION_WIDTH] = 100; - node_0.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.flex = -1; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.style.dimensions[DIMENSION_WIDTH] = 200; - node_2.style.dimensions[DIMENSION_HEIGHT] = 100; - } - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 100; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 0; - node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 200; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - } - - test("should shrink visible row node when there is not any space left over", root_node, root_layout); - } - - [Test] - public void TestCase197() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.dimensions[DIMENSION_WIDTH] = 100; - node_0.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 25; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.style.flex = -1; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.style.dimensions[DIMENSION_WIDTH] = 30; - node_2.style.dimensions[DIMENSION_HEIGHT] = 100; - } - node_1 = node_0.getChildAt(2); - node_1.style.dimensions[DIMENSION_WIDTH] = 15; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 100; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 25; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 25; - node_1.layout.dimensions[DIMENSION_WIDTH] = 30; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 0; - node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 30; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - node_1 = node_0.getChildAt(2); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 55; - node_1.layout.dimensions[DIMENSION_WIDTH] = 15; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - test("should not shrink visible row node with siblings when there is space left over", root_node, root_layout); - } - - [Test] - public void TestCase198() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.dimensions[DIMENSION_WIDTH] = 100; - node_0.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 25; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.style.flex = -1; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.style.dimensions[DIMENSION_WIDTH] = 80; - node_2.style.dimensions[DIMENSION_HEIGHT] = 100; - } - node_1 = node_0.getChildAt(2); - node_1.style.dimensions[DIMENSION_WIDTH] = 15; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 100; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 25; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 25; - node_1.layout.dimensions[DIMENSION_WIDTH] = 60; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 0; - node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 80; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - node_1 = node_0.getChildAt(2); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 85; - node_1.layout.dimensions[DIMENSION_WIDTH] = 15; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - test("should shrink visible row node with siblings when there is not any space left over", root_node, root_layout); - } - - [Test] - public void TestCase199() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.dimensions[DIMENSION_WIDTH] = 100; - node_0.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.flex = -1; - node_1.style.dimensions[DIMENSION_WIDTH] = 30; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_WIDTH] = 40; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(2); - node_1.style.flex = -1; - node_1.style.dimensions[DIMENSION_WIDTH] = 50; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 100; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 22.5f; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 22.5f; - node_1.layout.dimensions[DIMENSION_WIDTH] = 40; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(2); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 62.5f; - node_1.layout.dimensions[DIMENSION_WIDTH] = 37.5f; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - test("should shrink visible row nodes when there is not any space left over", root_node, root_layout); - } - - [Test] - public void TestCase200() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.dimensions[DIMENSION_WIDTH] = 100; - node_0.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.overflow = CSSOverflow.Hidden; - node_1.style.flex = -1; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.style.dimensions[DIMENSION_WIDTH] = 25; - node_2.style.dimensions[DIMENSION_HEIGHT] = 100; - } - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 100; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 25; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 0; - node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 25; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - } - - test("should not shrink hidden row node when there is space left over", root_node, root_layout); - } - - [Test] - public void TestCase201() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.dimensions[DIMENSION_WIDTH] = 100; - node_0.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.overflow = CSSOverflow.Hidden; - node_1.style.flex = -1; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.style.dimensions[DIMENSION_WIDTH] = 200; - node_2.style.dimensions[DIMENSION_HEIGHT] = 100; - } - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 100; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 1); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 0; - node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 200; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - } - - test("should shrink hidden row node when there is not any space left over", root_node, root_layout); - } - - [Test] - public void TestCase202() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.dimensions[DIMENSION_WIDTH] = 100; - node_0.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 25; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.style.overflow = CSSOverflow.Hidden; - node_1.style.flex = -1; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.style.dimensions[DIMENSION_WIDTH] = 30; - node_2.style.dimensions[DIMENSION_HEIGHT] = 100; - } - node_1 = node_0.getChildAt(2); - node_1.style.dimensions[DIMENSION_WIDTH] = 15; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 100; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 25; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 25; - node_1.layout.dimensions[DIMENSION_WIDTH] = 30; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 0; - node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 30; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - node_1 = node_0.getChildAt(2); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 55; - node_1.layout.dimensions[DIMENSION_WIDTH] = 15; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - test("should not shrink hidden row node with siblings when there is space left over", root_node, root_layout); - } - - [Test] - public void TestCase203() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.dimensions[DIMENSION_WIDTH] = 100; - node_0.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 25; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.style.overflow = CSSOverflow.Hidden; - node_1.style.flex = -1; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.style.dimensions[DIMENSION_WIDTH] = 80; - node_2.style.dimensions[DIMENSION_HEIGHT] = 100; - } - node_1 = node_0.getChildAt(2); - node_1.style.dimensions[DIMENSION_WIDTH] = 15; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 100; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 25; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 25; - node_1.layout.dimensions[DIMENSION_WIDTH] = 60; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 0; - node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 80; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - node_1 = node_0.getChildAt(2); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 85; - node_1.layout.dimensions[DIMENSION_WIDTH] = 15; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - test("should shrink hidden row node with siblings when there is not any space left over", root_node, root_layout); - } - - [Test] - public void TestCase204() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.dimensions[DIMENSION_WIDTH] = 100; - node_0.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.overflow = CSSOverflow.Hidden; - node_1.style.flex = -1; - node_1.style.dimensions[DIMENSION_WIDTH] = 30; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_WIDTH] = 40; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(2); - node_1.style.overflow = CSSOverflow.Hidden; - node_1.style.flex = -1; - node_1.style.dimensions[DIMENSION_WIDTH] = 50; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 100; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 22.5f; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 22.5f; - node_1.layout.dimensions[DIMENSION_WIDTH] = 40; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(2); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 62.5f; - node_1.layout.dimensions[DIMENSION_WIDTH] = 37.5f; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - test("should shrink hidden row nodes proportional to their main size when there is not any space left over", root_node, root_layout); - } - - [Test] - public void TestCase205() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.dimensions[DIMENSION_WIDTH] = 213; - node_0.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 25; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.style.flexDirection = CSSFlexDirection.Row; - node_1.style.alignItems = CSSAlign.FlexStart; - node_1.style.flex = -1; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.setMeasureFunction(sTestMeasureFunction); - node_2.context = "loooooooooong with space"; - } - node_1 = node_0.getChildAt(2); - node_1.style.dimensions[DIMENSION_WIDTH] = 15; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 213; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 25; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 25; - node_1.layout.dimensions[DIMENSION_WIDTH] = 172; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 0; - node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 172; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 18; - } - node_1 = node_0.getChildAt(2); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 197; - node_1.layout.dimensions[DIMENSION_WIDTH] = 15; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - test("should not shrink text node with siblings when there is space left over", root_node, root_layout); - } - - [Test] - public void TestCase206() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.dimensions[DIMENSION_WIDTH] = 140; - node_0.style.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 25; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.style.flexDirection = CSSFlexDirection.Row; - node_1.style.alignItems = CSSAlign.FlexStart; - node_1.style.flex = -1; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - 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"; - } - node_1 = node_0.getChildAt(2); - node_1.style.dimensions[DIMENSION_WIDTH] = 15; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 140; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_0, 3); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 0; - node_1.layout.dimensions[DIMENSION_WIDTH] = 25; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 25; - node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - addChildren(node_1, 1); - { - TestCSSNode node_2; - node_2 = node_1.getChildAt(0); - node_2.layout.position[POSITION_TOP] = 0; - node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 100; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 36; - } - node_1 = node_0.getChildAt(2); - node_1.layout.position[POSITION_TOP] = 0; - node_1.layout.position[POSITION_LEFT] = 125; - node_1.layout.dimensions[DIMENSION_WIDTH] = 15; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - } - } - - test("should shrink text node with siblings when there is not any space left over", root_node, root_layout); - } - - [Test] - public void TestCase207() - { - TestCSSNode root_node = new TestCSSNode(); - { - TestCSSNode node_0 = root_node; - node_0.style.flexDirection = CSSFlexDirection.Row; - node_0.style.alignContent = CSSAlign.Stretch; - node_0.style.alignItems = CSSAlign.FlexStart; - node_0.style.flexWrap = CSSWrap.Wrap; - node_0.style.dimensions[DIMENSION_WIDTH] = 300; - node_0.style.dimensions[DIMENSION_HEIGHT] = 380; - addChildren(node_0, 15); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.style.dimensions[DIMENSION_WIDTH] = 50; - node_1.style.dimensions[DIMENSION_HEIGHT] = 50; - node_1.setMargin(Spacing.LEFT, 10); - node_1.setMargin(Spacing.TOP, 10); - node_1.setMargin(Spacing.RIGHT, 10); - node_1.setMargin(Spacing.BOTTOM, 10); - node_1.setMargin(Spacing.START, 10); - node_1.setMargin(Spacing.END, 10); - node_1 = node_0.getChildAt(1); - node_1.style.dimensions[DIMENSION_WIDTH] = 50; - node_1.style.dimensions[DIMENSION_HEIGHT] = 50; - node_1.setMargin(Spacing.LEFT, 10); - node_1.setMargin(Spacing.TOP, 10); - node_1.setMargin(Spacing.RIGHT, 10); - node_1.setMargin(Spacing.BOTTOM, 10); - node_1.setMargin(Spacing.START, 10); - node_1.setMargin(Spacing.END, 10); - node_1 = node_0.getChildAt(2); - node_1.style.dimensions[DIMENSION_WIDTH] = 50; - node_1.style.dimensions[DIMENSION_HEIGHT] = 50; - node_1.setMargin(Spacing.LEFT, 10); - node_1.setMargin(Spacing.TOP, 10); - node_1.setMargin(Spacing.RIGHT, 10); - node_1.setMargin(Spacing.BOTTOM, 10); - node_1.setMargin(Spacing.START, 10); - node_1.setMargin(Spacing.END, 10); - node_1 = node_0.getChildAt(3); - node_1.style.dimensions[DIMENSION_WIDTH] = 50; - node_1.style.dimensions[DIMENSION_HEIGHT] = 50; - node_1.setMargin(Spacing.LEFT, 10); - node_1.setMargin(Spacing.TOP, 10); - node_1.setMargin(Spacing.RIGHT, 10); - node_1.setMargin(Spacing.BOTTOM, 10); - node_1.setMargin(Spacing.START, 10); - node_1.setMargin(Spacing.END, 10); - node_1 = node_0.getChildAt(4); - node_1.style.dimensions[DIMENSION_WIDTH] = 50; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1.setMargin(Spacing.LEFT, 10); - node_1.setMargin(Spacing.TOP, 10); - node_1.setMargin(Spacing.RIGHT, 10); - node_1.setMargin(Spacing.BOTTOM, 10); - node_1.setMargin(Spacing.START, 10); - node_1.setMargin(Spacing.END, 10); - node_1 = node_0.getChildAt(5); - node_1.style.alignSelf = CSSAlign.FlexStart; - node_1.style.dimensions[DIMENSION_WIDTH] = 50; - node_1.style.dimensions[DIMENSION_HEIGHT] = 50; - node_1.setMargin(Spacing.LEFT, 10); - node_1.setMargin(Spacing.TOP, 10); - node_1.setMargin(Spacing.RIGHT, 10); - node_1.setMargin(Spacing.BOTTOM, 10); - node_1.setMargin(Spacing.START, 10); - node_1.setMargin(Spacing.END, 10); - node_1 = node_0.getChildAt(6); - node_1.style.dimensions[DIMENSION_WIDTH] = 50; - node_1.style.dimensions[DIMENSION_HEIGHT] = 50; - node_1.setMargin(Spacing.LEFT, 10); - node_1.setMargin(Spacing.TOP, 10); - node_1.setMargin(Spacing.RIGHT, 10); - node_1.setMargin(Spacing.BOTTOM, 10); - node_1.setMargin(Spacing.START, 10); - node_1.setMargin(Spacing.END, 10); - node_1 = node_0.getChildAt(7); - node_1.style.dimensions[DIMENSION_WIDTH] = 50; - node_1.style.dimensions[DIMENSION_HEIGHT] = 100; - node_1.setMargin(Spacing.LEFT, 10); - node_1.setMargin(Spacing.TOP, 10); - node_1.setMargin(Spacing.RIGHT, 10); - node_1.setMargin(Spacing.BOTTOM, 10); - node_1.setMargin(Spacing.START, 10); - node_1.setMargin(Spacing.END, 10); - node_1 = node_0.getChildAt(8); - node_1.style.dimensions[DIMENSION_WIDTH] = 50; - node_1.style.dimensions[DIMENSION_HEIGHT] = 50; - node_1.setMargin(Spacing.LEFT, 10); - node_1.setMargin(Spacing.TOP, 10); - node_1.setMargin(Spacing.RIGHT, 10); - node_1.setMargin(Spacing.BOTTOM, 10); - node_1.setMargin(Spacing.START, 10); - node_1.setMargin(Spacing.END, 10); - node_1 = node_0.getChildAt(9); - node_1.style.dimensions[DIMENSION_WIDTH] = 50; - node_1.style.dimensions[DIMENSION_HEIGHT] = 50; - node_1.setMargin(Spacing.LEFT, 10); - node_1.setMargin(Spacing.TOP, 10); - node_1.setMargin(Spacing.RIGHT, 10); - node_1.setMargin(Spacing.BOTTOM, 10); - node_1.setMargin(Spacing.START, 10); - node_1.setMargin(Spacing.END, 10); - node_1 = node_0.getChildAt(10); - node_1.style.alignSelf = CSSAlign.FlexStart; - node_1.style.dimensions[DIMENSION_WIDTH] = 50; - node_1.style.dimensions[DIMENSION_HEIGHT] = 50; - node_1.setMargin(Spacing.LEFT, 10); - node_1.setMargin(Spacing.TOP, 10); - node_1.setMargin(Spacing.RIGHT, 10); - node_1.setMargin(Spacing.BOTTOM, 10); - node_1.setMargin(Spacing.START, 10); - node_1.setMargin(Spacing.END, 10); - node_1 = node_0.getChildAt(11); - node_1.style.dimensions[DIMENSION_WIDTH] = 50; - node_1.style.dimensions[DIMENSION_HEIGHT] = 50; - node_1.setMargin(Spacing.LEFT, 10); - node_1.setMargin(Spacing.TOP, 10); - node_1.setMargin(Spacing.RIGHT, 10); - node_1.setMargin(Spacing.BOTTOM, 10); - node_1.setMargin(Spacing.START, 10); - node_1.setMargin(Spacing.END, 10); - node_1 = node_0.getChildAt(12); - node_1.style.dimensions[DIMENSION_WIDTH] = 50; - node_1.style.dimensions[DIMENSION_HEIGHT] = 50; - node_1.setMargin(Spacing.LEFT, 10); - node_1.setMargin(Spacing.TOP, 10); - node_1.setMargin(Spacing.RIGHT, 10); - node_1.setMargin(Spacing.BOTTOM, 10); - node_1.setMargin(Spacing.START, 10); - node_1.setMargin(Spacing.END, 10); - node_1 = node_0.getChildAt(13); - node_1.style.alignSelf = CSSAlign.FlexStart; - node_1.style.dimensions[DIMENSION_WIDTH] = 50; - node_1.style.dimensions[DIMENSION_HEIGHT] = 50; - node_1.setMargin(Spacing.LEFT, 10); - node_1.setMargin(Spacing.TOP, 10); - node_1.setMargin(Spacing.RIGHT, 10); - node_1.setMargin(Spacing.BOTTOM, 10); - node_1.setMargin(Spacing.START, 10); - node_1.setMargin(Spacing.END, 10); - node_1 = node_0.getChildAt(14); - node_1.style.dimensions[DIMENSION_WIDTH] = 50; - node_1.style.dimensions[DIMENSION_HEIGHT] = 50; - node_1.setMargin(Spacing.LEFT, 10); - node_1.setMargin(Spacing.TOP, 10); - node_1.setMargin(Spacing.RIGHT, 10); - node_1.setMargin(Spacing.BOTTOM, 10); - node_1.setMargin(Spacing.START, 10); - node_1.setMargin(Spacing.END, 10); - } - } - - TestCSSNode root_layout = new TestCSSNode(); - { - TestCSSNode node_0 = root_layout; - node_0.layout.position[POSITION_TOP] = 0; - node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 300; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 380; - addChildren(node_0, 15); - { - TestCSSNode node_1; - node_1 = node_0.getChildAt(0); - node_1.layout.position[POSITION_TOP] = 10; - node_1.layout.position[POSITION_LEFT] = 10; - node_1.layout.dimensions[DIMENSION_WIDTH] = 50; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 50; - node_1 = node_0.getChildAt(1); - node_1.layout.position[POSITION_TOP] = 10; - node_1.layout.position[POSITION_LEFT] = 80; - node_1.layout.dimensions[DIMENSION_WIDTH] = 50; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 50; - node_1 = node_0.getChildAt(2); - node_1.layout.position[POSITION_TOP] = 10; - node_1.layout.position[POSITION_LEFT] = 150; - node_1.layout.dimensions[DIMENSION_WIDTH] = 50; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 50; - node_1 = node_0.getChildAt(3); - node_1.layout.position[POSITION_TOP] = 10; - node_1.layout.position[POSITION_LEFT] = 220; - node_1.layout.dimensions[DIMENSION_WIDTH] = 50; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 50; - node_1 = node_0.getChildAt(4); - node_1.layout.position[POSITION_TOP] = 92.5f; - node_1.layout.position[POSITION_LEFT] = 10; - node_1.layout.dimensions[DIMENSION_WIDTH] = 50; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(5); - node_1.layout.position[POSITION_TOP] = 92.5f; - node_1.layout.position[POSITION_LEFT] = 80; - node_1.layout.dimensions[DIMENSION_WIDTH] = 50; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 50; - node_1 = node_0.getChildAt(6); - node_1.layout.position[POSITION_TOP] = 92.5f; - node_1.layout.position[POSITION_LEFT] = 150; - node_1.layout.dimensions[DIMENSION_WIDTH] = 50; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 50; - node_1 = node_0.getChildAt(7); - node_1.layout.position[POSITION_TOP] = 92.5f; - node_1.layout.position[POSITION_LEFT] = 220; - node_1.layout.dimensions[DIMENSION_WIDTH] = 50; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; - node_1 = node_0.getChildAt(8); - node_1.layout.position[POSITION_TOP] = 225; - node_1.layout.position[POSITION_LEFT] = 10; - node_1.layout.dimensions[DIMENSION_WIDTH] = 50; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 50; - node_1 = node_0.getChildAt(9); - node_1.layout.position[POSITION_TOP] = 225; - node_1.layout.position[POSITION_LEFT] = 80; - node_1.layout.dimensions[DIMENSION_WIDTH] = 50; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 50; - node_1 = node_0.getChildAt(10); - node_1.layout.position[POSITION_TOP] = 225; - node_1.layout.position[POSITION_LEFT] = 150; - node_1.layout.dimensions[DIMENSION_WIDTH] = 50; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 50; - node_1 = node_0.getChildAt(11); - node_1.layout.position[POSITION_TOP] = 225; - node_1.layout.position[POSITION_LEFT] = 220; - node_1.layout.dimensions[DIMENSION_WIDTH] = 50; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 50; - node_1 = node_0.getChildAt(12); - node_1.layout.position[POSITION_TOP] = 307.5f; - node_1.layout.position[POSITION_LEFT] = 10; - node_1.layout.dimensions[DIMENSION_WIDTH] = 50; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 50; - node_1 = node_0.getChildAt(13); - node_1.layout.position[POSITION_TOP] = 307.5f; - node_1.layout.position[POSITION_LEFT] = 80; - node_1.layout.dimensions[DIMENSION_WIDTH] = 50; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 50; - node_1 = node_0.getChildAt(14); - node_1.layout.position[POSITION_TOP] = 307.5f; - node_1.layout.position[POSITION_LEFT] = 150; - node_1.layout.dimensions[DIMENSION_WIDTH] = 50; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 50; - } - } - - test("should layout with alignContent: stretch, and alignItems: flex-start", root_node, root_layout); - } - /** END_GENERATED **/ -} - -} diff --git a/java/csharp/Facebook.CSSLayout.Tests/Properties/AssemblyInfo.cs b/java/csharp/Facebook.CSSLayout.Tests/Properties/AssemblyInfo.cs deleted file mode 100755 index c82a6f1c..00000000 --- a/java/csharp/Facebook.CSSLayout.Tests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -using System.Reflection; -using System.Runtime.InteropServices; - -[assembly: AssemblyTitle("Facebook.CSSLayout.Tests")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Facebook.CSSLayout.Tests")] -[assembly: AssemblyCopyright("Copyright © Facebook 2015")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -[assembly: ComVisible(false)] - -[assembly: Guid("c186053a-741f-477d-b031-4d343fb20d1d")] - -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/java/csharp/Facebook.CSSLayout.Tests/TestConstants.cs b/java/csharp/Facebook.CSSLayout.Tests/TestConstants.cs deleted file mode 100644 index b139e02c..00000000 --- a/java/csharp/Facebook.CSSLayout.Tests/TestConstants.cs +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -namespace Facebook.CSSLayout.Tests -{ - /** - * Generated constants used in {@link LayoutEngineTest}. - */ - public class TestConstants - { - - /** START_GENERATED **/ - public static readonly float SMALL_WIDTH = 35f; - public static readonly float SMALL_HEIGHT = 18f; - public static readonly float BIG_WIDTH = 172f; - public static readonly float BIG_HEIGHT = 36f; - public static readonly float BIG_MIN_WIDTH = 100f; - public static readonly string SMALL_TEXT = "small"; - public static readonly string LONG_TEXT = "loooooooooong with space"; - public static readonly string MEASURE_WITH_RATIO_2 = "measureWithRatio2"; - public static readonly string MEASURE_WITH_MATCH_PARENT = "measureWithMatchParent"; - /** END_GENERATED **/ - } -} diff --git a/java/csharp/Facebook.CSSLayout.Tests/packages.config b/java/csharp/Facebook.CSSLayout.Tests/packages.config deleted file mode 100755 index aff9394f..00000000 --- a/java/csharp/Facebook.CSSLayout.Tests/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/java/csharp/Facebook.CSSLayout.sln b/java/csharp/Facebook.CSSLayout.sln deleted file mode 100755 index 5f7090f3..00000000 --- a/java/csharp/Facebook.CSSLayout.sln +++ /dev/null @@ -1,34 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.23107.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Facebook.CSSLayout", "Facebook.CSSLayout\Facebook.CSSLayout.csproj", "{D534FB4B-A7D4-4A29-96D3-F39A91A259BD}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Facebook.CSSLayout.Tests", "Facebook.CSSLayout.Tests\Facebook.CSSLayout.Tests.csproj", "{E687C8FD-0A0D-450F-853D-EC301BE1C038}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{29A6932B-FDDC-4E8A-8895-7FD64CC47B7F}" - ProjectSection(SolutionItems) = preProject - ..\CSharpTranspiler.js = ..\CSharpTranspiler.js - ..\JavaTranspiler.js = ..\JavaTranspiler.js - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {D534FB4B-A7D4-4A29-96D3-F39A91A259BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D534FB4B-A7D4-4A29-96D3-F39A91A259BD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D534FB4B-A7D4-4A29-96D3-F39A91A259BD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D534FB4B-A7D4-4A29-96D3-F39A91A259BD}.Release|Any CPU.Build.0 = Release|Any CPU - {E687C8FD-0A0D-450F-853D-EC301BE1C038}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E687C8FD-0A0D-450F-853D-EC301BE1C038}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E687C8FD-0A0D-450F-853D-EC301BE1C038}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E687C8FD-0A0D-450F-853D-EC301BE1C038}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/java/csharp/Facebook.CSSLayout/Assertions.cs b/java/csharp/Facebook.CSSLayout/Assertions.cs deleted file mode 100755 index d4ecb044..00000000 --- a/java/csharp/Facebook.CSSLayout/Assertions.cs +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -using System.Diagnostics; - -namespace Facebook.CSSLayout -{ - static class Assertions - { - public static T assertNotNull(T v) where T : class - { - Debug.Assert(v != null); - return v; - } - - public static void assertCondition(bool condition, string explanation) - { - Debug.Assert(condition, explanation); - } - } -} diff --git a/java/csharp/Facebook.CSSLayout/CSSCachedMeasurement.cs b/java/csharp/Facebook.CSSLayout/CSSCachedMeasurement.cs deleted file mode 100644 index 8eabe5d3..00000000 --- a/java/csharp/Facebook.CSSLayout/CSSCachedMeasurement.cs +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -namespace Facebook.CSSLayout -{ - sealed class CSSCachedMeasurement - { - public float availableWidth; - public float availableHeight; - public CSSMeasureMode? widthMeasureMode = null; - public CSSMeasureMode? heightMeasureMode = null; - - public float computedWidth; - public float computedHeight; - } -} diff --git a/java/csharp/Facebook.CSSLayout/CSSConstants.cs b/java/csharp/Facebook.CSSLayout/CSSConstants.cs deleted file mode 100644 index 83bee255..00000000 --- a/java/csharp/Facebook.CSSLayout/CSSConstants.cs +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -namespace Facebook.CSSLayout -{ - public static class CSSConstants - { - public const float Undefined = float.NaN; - - public static bool IsUndefined(float value) - { - return float.IsNaN(value); - } - } -} diff --git a/java/csharp/Facebook.CSSLayout/CSSDirection.cs b/java/csharp/Facebook.CSSLayout/CSSDirection.cs deleted file mode 100755 index af35f336..00000000 --- a/java/csharp/Facebook.CSSLayout/CSSDirection.cs +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -namespace Facebook.CSSLayout -{ - public enum CSSDirection - { - Inherit, - LTR, - RTL - } -} diff --git a/java/csharp/Facebook.CSSLayout/CSSFlexDirection.cs b/java/csharp/Facebook.CSSLayout/CSSFlexDirection.cs deleted file mode 100644 index 66fea292..00000000 --- a/java/csharp/Facebook.CSSLayout/CSSFlexDirection.cs +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -namespace Facebook.CSSLayout -{ - public enum CSSFlexDirection - { - Column, - ColumnReverse, - Row, - RowReverse - } -} diff --git a/java/csharp/Facebook.CSSLayout/CSSJustify.cs b/java/csharp/Facebook.CSSLayout/CSSJustify.cs deleted file mode 100644 index a0ba3c68..00000000 --- a/java/csharp/Facebook.CSSLayout/CSSJustify.cs +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -namespace Facebook.CSSLayout -{ - public enum CSSJustify - { - FlexStart, - Center, - FlexEnd, - SpaceBetween, - SpaceAround - } -} diff --git a/java/csharp/Facebook.CSSLayout/CSSLayout.cs b/java/csharp/Facebook.CSSLayout/CSSLayout.cs deleted file mode 100644 index e3b8f621..00000000 --- a/java/csharp/Facebook.CSSLayout/CSSLayout.cs +++ /dev/null @@ -1,89 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -namespace Facebook.CSSLayout -{ - - /** - * Where the output of {@link LayoutEngine#layoutNode(CSSNode, float)} will go in the CSSNode. - */ - - class CSSLayout - { - // This value was chosen based on empiracle data. Even the most complicated - // layouts should not require more than 16 entries to fit within the cache. - public const int MAX_CACHED_RESULT_COUNT = 16; - - public const int POSITION_LEFT = 0; - public const int POSITION_TOP = 1; - public const int POSITION_RIGHT = 2; - public const int POSITION_BOTTOM = 3; - - public const int DIMENSION_WIDTH = 0; - public const int DIMENSION_HEIGHT = 1; - - public float[] position = new float[4]; - public float[] dimensions = { - CSSConstants.Undefined, - CSSConstants.Undefined - }; - public CSSDirection direction = CSSDirection.LTR; - - public float flexBasis; - - public int generationCount; - public CSSDirection? lastParentDirection; - - public int nextCachedMeasurementsIndex; - public CSSCachedMeasurement[] cachedMeasurements = new CSSCachedMeasurement[MAX_CACHED_RESULT_COUNT]; - public float[] measuredDimensions = { - CSSConstants.Undefined, - CSSConstants.Undefined - }; - - public CSSCachedMeasurement cachedLayout = new CSSCachedMeasurement(); - - public void resetResult() - { - FillArray(position, 0); - FillArray(dimensions, CSSConstants.Undefined); - - direction = CSSDirection.LTR; - - flexBasis = 0; - - generationCount = 0; - lastParentDirection = null; - - nextCachedMeasurementsIndex = 0; - measuredDimensions[DIMENSION_WIDTH] = CSSConstants.Undefined; - measuredDimensions[DIMENSION_HEIGHT] = CSSConstants.Undefined; - - cachedLayout.widthMeasureMode = null; - cachedLayout.heightMeasureMode = null; - } - - public override string ToString() - { - return "layout: {" + - "left: " + position[POSITION_LEFT] + ", " + - "top: " + position[POSITION_TOP] + ", " + - "width: " + dimensions[DIMENSION_WIDTH] + ", " + - "height: " + dimensions[DIMENSION_HEIGHT] + ", " + - "direction: " + direction + - "}"; - } - - static void FillArray(T[] array, T value) - { - for (var i = 0; i != array.Length; ++i) - array[i] = value; - } - } -} diff --git a/java/csharp/Facebook.CSSLayout/CSSLayoutContext.cs b/java/csharp/Facebook.CSSLayout/CSSLayoutContext.cs deleted file mode 100755 index 91fd1bd3..00000000 --- a/java/csharp/Facebook.CSSLayout/CSSLayoutContext.cs +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -namespace Facebook.CSSLayout -{ - - /** - * A context for holding values local to a given instance of layout computation. - * - * This is necessary for making layout thread-safe. A separate instance should - * be used when {@link CSSNode#calculateLayout} is called concurrently on - * different node hierarchies. - */ - - sealed class CSSLayoutContext - { - /*package*/ - public MeasureOutput measureOutput = new MeasureOutput(); - public int currentGenerationCount; - } -} diff --git a/java/csharp/Facebook.CSSLayout/CSSMeasureMode.cs b/java/csharp/Facebook.CSSLayout/CSSMeasureMode.cs deleted file mode 100644 index 6f48f888..00000000 --- a/java/csharp/Facebook.CSSLayout/CSSMeasureMode.cs +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -namespace Facebook.CSSLayout -{ - public enum CSSMeasureMode - { - Undefined, - Exactly, - AtMost, - } -} diff --git a/java/csharp/Facebook.CSSLayout/CSSNode.cs b/java/csharp/Facebook.CSSLayout/CSSNode.cs deleted file mode 100644 index 09735bbf..00000000 --- a/java/csharp/Facebook.CSSLayout/CSSNode.cs +++ /dev/null @@ -1,558 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Facebook.CSSLayout -{ - /** - * Should measure the given node and put the result in the given MeasureOutput. - */ - - public delegate MeasureOutput MeasureFunction(CSSNode node, float width, CSSMeasureMode widthMode, float height, CSSMeasureMode heightMode); - - /** - * 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 - { - const int POSITION_LEFT = CSSLayout.POSITION_LEFT; - const int POSITION_TOP = CSSLayout.POSITION_TOP; - const int POSITION_RIGHT = CSSLayout.POSITION_RIGHT; - const int POSITION_BOTTOM = CSSLayout.POSITION_BOTTOM; - const int DIMENSION_WIDTH = CSSLayout.DIMENSION_WIDTH; - const int DIMENSION_HEIGHT = CSSLayout.DIMENSION_HEIGHT; - - 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 #MarkLayoutSeen()} was called. - */ - HAS_NEW_LAYOUT, - - /** - * {@link #layout} is valid for the node's properties and this layout has been marked as - * having been seen. - */ - UP_TO_DATE, - } - - internal readonly CSSStyle style = new CSSStyle(); - internal readonly CSSLayout layout = new CSSLayout(); - internal readonly CachedCSSLayout lastLayout = new CachedCSSLayout(); - - internal int lineIndex = 0; - internal /*package*/ CSSNode nextChild; - - // 4 is kinda arbitrary, but the default of 10 seems really high for an average View. - readonly List mChildren = new List(4); - [Nullable] CSSNode mParent; - [Nullable] MeasureFunction mMeasureFunction = null; - LayoutState mLayoutState = LayoutState.DIRTY; - bool mIsTextNode = false; - - public int ChildCount - { - get { return mChildren.Count; } - } - - public CSSNode this[int i] - { - get { return mChildren[i]; } - } - - public IEnumerable Children - { - get { return mChildren; } - } - - public void AddChild(CSSNode child) - { - InsertChild(ChildCount, child); - } - - public void InsertChild(int i, CSSNode child) - { - if (child.mParent != null) - { - throw new InvalidOperationException("Child already has a parent, it must be removed first."); - } - - mChildren.Insert(i, child); - child.mParent = this; - dirty(); - } - - public void RemoveChildAt(int i) - { - mChildren[i].mParent = null; - mChildren.RemoveAt(i); - dirty(); - } - - public CSSNode Parent - { - [return: Nullable] - get - { return mParent; } - } - - /** - * @return the index of the given child, or -1 if the child doesn't exist in this node. - */ - - public int IndexOf(CSSNode child) - { - return mChildren.IndexOf(child); - } - - public MeasureFunction MeasureFunction - { - get { return mMeasureFunction; } - set - { - if (!valuesEqual(mMeasureFunction, value)) - { - mMeasureFunction = value; - dirty(); - } - } - } - - public bool IsTextNode - { - get { return mIsTextNode; } - set { mIsTextNode = value; } - } - - public bool IsMeasureDefined - { - get { return mMeasureFunction != null; } - } - - internal MeasureOutput measure(MeasureOutput measureOutput, float width, CSSMeasureMode widthMode, float height, CSSMeasureMode heightMode) - { - if (!IsMeasureDefined) - { - throw new Exception("Measure function isn't defined!"); - } - return Assertions.assertNotNull(mMeasureFunction)(this, width, widthMode, height, heightMode); - } - - /** - * Performs the actual layout and saves the results in {@link #layout} - */ - - public void CalculateLayout() - { - LayoutEngine.layoutNode(DummyLayoutContext, this, CSSConstants.Undefined, CSSConstants.Undefined, null); - } - - static readonly CSSLayoutContext DummyLayoutContext = new CSSLayoutContext(); - - /** - * See {@link LayoutState#DIRTY}. - */ - - public bool IsDirty - { - get { return mLayoutState == LayoutState.DIRTY; } - } - - /** - * See {@link LayoutState#HAS_NEW_LAYOUT}. - */ - - public bool HasNewLayout - { - get { return mLayoutState == LayoutState.HAS_NEW_LAYOUT; } - } - - internal protected virtual void dirty() - { - if (mLayoutState == LayoutState.DIRTY) - { - return; - } - else if (mLayoutState == LayoutState.HAS_NEW_LAYOUT) - { - throw new InvalidOperationException("Previous layout was ignored! MarkLayoutSeen() never called"); - } - - mLayoutState = LayoutState.DIRTY; - - if (mParent != null) - { - mParent.dirty(); - } - } - - internal void markHasNewLayout() - { - mLayoutState = LayoutState.HAS_NEW_LAYOUT; - } - - /** - * Tells the node that the current values in {@link #layout} have been seen. 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 MarkLayoutSeen() - { - if (!HasNewLayout) - { - throw new InvalidOperationException("Expected node to have a new layout to be seen!"); - } - - mLayoutState = LayoutState.UP_TO_DATE; - } - - void toStringWithIndentation(StringBuilder result, int level) - { - // Spaces and tabs are dropped by IntelliJ logcat integration, so rely on __ instead. - StringBuilder indentation = new StringBuilder(); - for (int i = 0; i < level; ++i) - { - indentation.Append("__"); - } - - result.Append(indentation.ToString()); - result.Append(layout.ToString()); - - if (ChildCount == 0) - { - return; - } - - result.Append(", children: [\n"); - for (var i = 0; i < ChildCount; i++) - { - this[i].toStringWithIndentation(result, level + 1); - result.Append("\n"); - } - result.Append(indentation + "]"); - } - - public override string ToString() - { - StringBuilder sb = new StringBuilder(); - this.toStringWithIndentation(sb, 0); - return sb.ToString(); - } - - protected bool valuesEqual(float f1, float f2) - { - return FloatUtil.floatsEqual(f1, f2); - } - - protected bool valuesEqual([Nullable] T o1, [Nullable] T o2) - { - if (o1 == null) - { - return o2 == null; - } - return o1.Equals(o2); - } - - public CSSDirection Direction - { - get { return style.direction; } - set { updateDiscreteValue(ref style.direction, value); } - } - - public CSSFlexDirection FlexDirection - { - get { return style.flexDirection; } - set { updateDiscreteValue(ref style.flexDirection, value); } - } - - public CSSJustify JustifyContent - { - get { return style.justifyContent; } - set { updateDiscreteValue(ref style.justifyContent, value); } - } - - public CSSAlign AlignContent - { - get { return style.alignContent; } - set { updateDiscreteValue(ref style.alignContent, value); } - } - - public CSSAlign AlignItems - { - get { return style.alignItems; } - set { updateDiscreteValue(ref style.alignItems, value); } - } - - public CSSAlign AlignSelf - { - get { return style.alignSelf; } - set { updateDiscreteValue(ref style.alignSelf, value); } - } - - public CSSPositionType PositionType - { - get { return style.positionType; } - set { updateDiscreteValue(ref style.positionType, value); } - } - - public CSSWrap Wrap - { - get { return style.flexWrap; } - set { updateDiscreteValue(ref style.flexWrap, value); } - } - - public float Flex - { - get { return style.flex; } - set { updateFloatValue(ref style.flex, value); } - } - - public CSSOverflow Overflow - { - get { return style.overflow; } - set { updateDiscreteValue(ref style.overflow, value); } - } - - public void SetMargin(CSSSpacingType spacingType, float margin) - { - if (style.margin.set((int)spacingType, margin)) - dirty(); - } - - public float GetMargin(CSSSpacingType spacingType) - { - return style.margin.getRaw((int)spacingType); - } - - public void SetPadding(CSSSpacingType spacingType, float padding) - { - if (style.padding.set((int)spacingType, padding)) - dirty(); - } - - public float GetPadding(CSSSpacingType spacingType) - { - return style.padding.getRaw((int)spacingType); - } - - public void SetBorder(CSSSpacingType spacingType, float border) - { - if (style.border.set((int)spacingType, border)) - dirty(); - } - - public float GetBorder(CSSSpacingType spacingType) - { - return style.border.getRaw((int)spacingType); - } - - public float PositionTop - { - get { return style.position[POSITION_TOP]; } - set { updateFloatValue(ref style.position[POSITION_TOP], value); } - } - - public float PositionBottom - { - get { return style.position[POSITION_BOTTOM]; } - set { updateFloatValue(ref style.position[POSITION_BOTTOM], value); } - } - - public float PositionLeft - { - get { return style.position[POSITION_LEFT]; } - set { updateFloatValue(ref style.position[POSITION_LEFT], value); } - } - - public float PositionRight - { - get { return style.position[POSITION_RIGHT]; } - set { updateFloatValue(ref style.position[POSITION_RIGHT], value); } - } - - public float Width - { - get { return style.dimensions[DIMENSION_WIDTH]; } - set { updateFloatValue(ref style.dimensions[DIMENSION_WIDTH], value); } - } - - public float Height - { - get { return style.dimensions[DIMENSION_HEIGHT]; } - set { updateFloatValue(ref style.dimensions[DIMENSION_HEIGHT], value); } - } - - public float MinWidth - { - get { return style.minWidth; } - set { updateFloatValue(ref style.minWidth, value); } - } - - public float MinHeight - { - get { return style.minHeight; } - set { updateFloatValue(ref style.minHeight, value); } - } - - public float MaxWidth - { - get { return style.maxWidth; } - set { updateFloatValue(ref style.maxWidth, value); } - } - - public float MaxHeight - { - get { return style.maxHeight; } - set { updateFloatValue(ref style.maxHeight, value); } - } - - public float LayoutX - { - get { return layout.position[POSITION_LEFT]; } - } - - public float LayoutY - { - get { return layout.position[POSITION_TOP]; } - } - - public float LayoutWidth - { - get { return layout.dimensions[DIMENSION_WIDTH]; } - } - - public float LayoutHeight - { - get { return layout.dimensions[DIMENSION_HEIGHT]; } - } - - public CSSDirection LayoutDirection - { - get { return layout.direction; } - } - - /** - * Set a default padding (left/top/right/bottom) for this node. - */ - public void SetDefaultPadding(CSSSpacingType spacingType, float padding) - { - if (style.padding.setDefault((int)spacingType, padding)) - dirty(); - } - - void updateDiscreteValue(ref ValueT valueRef, ValueT newValue) - { - if (valuesEqual(valueRef, newValue)) - return; - - valueRef = newValue; - dirty(); - } - - void updateFloatValue(ref float valueRef, float newValue) - { - if (valuesEqual(valueRef, newValue)) - return; - valueRef = newValue; - dirty(); - } - } - - public static class CSSNodeExtensions - { - /* - Explicitly mark this node as dirty. - - Calling this function is required when the measure function points to the same instance, - but changes its behavior. - - For all other property changes, the node is automatically marked dirty. - */ - - public static void MarkDirty(this CSSNode node) - { - node.dirty(); - } - } - - internal static class CSSNodeExtensionsInternal - { - public static CSSNode getParent(this CSSNode node) - { - return node.Parent; - } - - public static int getChildCount(this CSSNode node) - { - return node.ChildCount; - } - - public static CSSNode getChildAt(this CSSNode node, int i) - { - return node[i]; - } - - public static void addChildAt(this CSSNode node, CSSNode child, int i) - { - node.InsertChild(i, child); - } - - public static void removeChildAt(this CSSNode node, int i) - { - node.RemoveChildAt(i); - } - - public static void setMeasureFunction(this CSSNode node, MeasureFunction measureFunction) - { - node.MeasureFunction = measureFunction; - } - - public static void setIsTextNode(this CSSNode node, bool isTextNode) - { - node.IsTextNode = isTextNode; - } - - public static void calculateLayout(this CSSNode node) - { - node.CalculateLayout(); - } - - public static bool isDirty(this CSSNode node) - { - return node.IsDirty; - } - - public static void setMargin(this CSSNode node, int spacingType, float margin) - { - node.SetMargin((CSSSpacingType)spacingType, margin); - } - - public static void setPadding(this CSSNode node, int spacingType, float padding) - { - node.SetPadding((CSSSpacingType)spacingType, padding); - } - - public static void setBorder(this CSSNode node, int spacingType, float border) - { - node.SetBorder((CSSSpacingType)spacingType, border); - } - } -} diff --git a/java/csharp/Facebook.CSSLayout/CSSOverflow.cs b/java/csharp/Facebook.CSSLayout/CSSOverflow.cs deleted file mode 100644 index 1a78f0cb..00000000 --- a/java/csharp/Facebook.CSSLayout/CSSOverflow.cs +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -namespace Facebook.CSSLayout -{ - public enum CSSOverflow - { - Visible, - Hidden - } -} diff --git a/java/csharp/Facebook.CSSLayout/CSSPositionType.cs b/java/csharp/Facebook.CSSLayout/CSSPositionType.cs deleted file mode 100644 index 0c11bc61..00000000 --- a/java/csharp/Facebook.CSSLayout/CSSPositionType.cs +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -namespace Facebook.CSSLayout -{ - public enum CSSPositionType - { - Relative, - Absolute - } -} diff --git a/java/csharp/Facebook.CSSLayout/CSSSpacingType.cs b/java/csharp/Facebook.CSSLayout/CSSSpacingType.cs deleted file mode 100755 index fd41fb61..00000000 --- a/java/csharp/Facebook.CSSLayout/CSSSpacingType.cs +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -namespace Facebook.CSSLayout -{ - public enum CSSSpacingType - { - Left = 0, - Top = 1, - Right = 2, - Bottom = 3, - Vertical = 4, - Horizontal = 5, - Start = 6, - End = 7, - All = 8 - } -} diff --git a/java/csharp/Facebook.CSSLayout/CSSStyle.cs b/java/csharp/Facebook.CSSLayout/CSSStyle.cs deleted file mode 100644 index d03f06bd..00000000 --- a/java/csharp/Facebook.CSSLayout/CSSStyle.cs +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -namespace Facebook.CSSLayout -{ - /** - * The CSS style definition for a {@link CSSNode}. - */ - sealed class CSSStyle - { - public CSSDirection direction = CSSDirection.Inherit; - public CSSFlexDirection flexDirection = CSSFlexDirection.Column; - public CSSJustify justifyContent = CSSJustify.FlexStart; - public CSSAlign alignContent = CSSAlign.FlexStart; - public CSSAlign alignItems = CSSAlign.Stretch; - public CSSAlign alignSelf = CSSAlign.Auto; - public CSSPositionType positionType = CSSPositionType.Relative; - public CSSWrap flexWrap = CSSWrap.NoWrap; - public CSSOverflow overflow = CSSOverflow.Visible; - public float flex; - - public Spacing margin = new Spacing(); - public Spacing padding = new Spacing(); - public Spacing border = new Spacing(); - - public float[] position = { - CSSConstants.Undefined, - CSSConstants.Undefined, - CSSConstants.Undefined, - CSSConstants.Undefined - }; - - public float[] dimensions = { - CSSConstants.Undefined, - CSSConstants.Undefined - }; - - public float minWidth = CSSConstants.Undefined; - public float minHeight = CSSConstants.Undefined; - - public float maxWidth = CSSConstants.Undefined; - public float maxHeight = CSSConstants.Undefined; - } -} diff --git a/java/csharp/Facebook.CSSLayout/CSSWrap.cs b/java/csharp/Facebook.CSSLayout/CSSWrap.cs deleted file mode 100644 index bab10818..00000000 --- a/java/csharp/Facebook.CSSLayout/CSSWrap.cs +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ -namespace Facebook.CSSLayout -{ - public enum CSSWrap - { - NoWrap, - Wrap - } -} diff --git a/java/csharp/Facebook.CSSLayout/CachedCSSLayout.cs b/java/csharp/Facebook.CSSLayout/CachedCSSLayout.cs deleted file mode 100644 index 511d9af6..00000000 --- a/java/csharp/Facebook.CSSLayout/CachedCSSLayout.cs +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -namespace 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. - */ - - class CachedCSSLayout : CSSLayout - { - public float requestedWidth = CSSConstants.Undefined; - public float requestedHeight = CSSConstants.Undefined; - public float parentMaxWidth = CSSConstants.Undefined; - public float parentMaxHeight = CSSConstants.Undefined; - } -} diff --git a/java/csharp/Facebook.CSSLayout/Facebook.CSSLayout.csproj b/java/csharp/Facebook.CSSLayout/Facebook.CSSLayout.csproj deleted file mode 100755 index 2016e4da..00000000 --- a/java/csharp/Facebook.CSSLayout/Facebook.CSSLayout.csproj +++ /dev/null @@ -1,73 +0,0 @@ - - - - - 10.0 - Debug - AnyCPU - {D534FB4B-A7D4-4A29-96D3-F39A91A259BD} - Library - Properties - Facebook.CSSLayout - Facebook.CSSLayout - en-US - 512 - {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - Profile259 - v4.5 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - 5 - - - none - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/java/csharp/Facebook.CSSLayout/Facebook.CSSLayout.nuspec b/java/csharp/Facebook.CSSLayout/Facebook.CSSLayout.nuspec deleted file mode 100755 index 1f10018c..00000000 --- a/java/csharp/Facebook.CSSLayout/Facebook.CSSLayout.nuspec +++ /dev/null @@ -1,17 +0,0 @@ - - - - $id$ - $version$ - $title$ - $author$ - $author$ - https://github.com/facebook/css-layout/blob/master/LICENSE - https://github.com/facebook/css-layout - false - $description$ - - Copyright 2015 Facebook - flexbox flex-box css layout css-layout facebook - - diff --git a/java/csharp/Facebook.CSSLayout/FloatUtil.cs b/java/csharp/Facebook.CSSLayout/FloatUtil.cs deleted file mode 100644 index bfea4f00..00000000 --- a/java/csharp/Facebook.CSSLayout/FloatUtil.cs +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -using System; - -namespace Facebook.CSSLayout -{ - static class FloatUtil - { - const float Epsilon = .00001f; - - public static bool floatsEqual(float f1, float f2) - { - if (float.IsNaN(f1) || float.IsNaN(f2)) - { - return float.IsNaN(f1) && float.IsNaN(f2); - } - return Math.Abs(f2 - f1) < Epsilon; - } - } -} diff --git a/java/csharp/Facebook.CSSLayout/LayoutEngine.cs b/java/csharp/Facebook.CSSLayout/LayoutEngine.cs deleted file mode 100644 index d50b20f1..00000000 --- a/java/csharp/Facebook.CSSLayout/LayoutEngine.cs +++ /dev/null @@ -1,1452 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -using System; -using boolean = System.Boolean; - -namespace Facebook.CSSLayout -{ - - /** - * Calculates layouts based on CSS style. See {@link #layoutNode(CSSNode, float, float)}. - */ - - static class LayoutEngine - { - const boolean POSITIVE_FLEX_IS_AUTO = false; - - const int POSITION_LEFT = CSSLayout.POSITION_LEFT; - const int POSITION_TOP = CSSLayout.POSITION_TOP; - const int POSITION_RIGHT = CSSLayout.POSITION_RIGHT; - const int POSITION_BOTTOM = CSSLayout.POSITION_BOTTOM; - const int DIMENSION_WIDTH = CSSLayout.DIMENSION_WIDTH; - const int DIMENSION_HEIGHT = CSSLayout.DIMENSION_HEIGHT; - - const int CSS_FLEX_DIRECTION_COLUMN = - (int)CSSFlexDirection.Column; - const int CSS_FLEX_DIRECTION_COLUMN_REVERSE = - (int)CSSFlexDirection.ColumnReverse; - const int CSS_FLEX_DIRECTION_ROW = - (int)CSSFlexDirection.Row; - const int CSS_FLEX_DIRECTION_ROW_REVERSE = - (int)CSSFlexDirection.RowReverse; - - const int CSS_POSITION_RELATIVE = (int)CSSPositionType.Relative; - const int CSS_POSITION_ABSOLUTE = (int)CSSPositionType.Absolute; - - private static readonly int[] leading = { - POSITION_TOP, - POSITION_BOTTOM, - POSITION_LEFT, - POSITION_RIGHT, - }; - - private static readonly int[] trailing = { - POSITION_BOTTOM, - POSITION_TOP, - POSITION_RIGHT, - POSITION_LEFT, - }; - - private static readonly int[] pos = { - POSITION_TOP, - POSITION_BOTTOM, - POSITION_LEFT, - POSITION_RIGHT, - }; - - private static readonly int[] dim = { - DIMENSION_HEIGHT, - DIMENSION_HEIGHT, - DIMENSION_WIDTH, - DIMENSION_WIDTH, - }; - - private static readonly int[] leadingSpacing = { - Spacing.TOP, - Spacing.BOTTOM, - Spacing.START, - Spacing.START - }; - - private static readonly int[] trailingSpacing = { - Spacing.BOTTOM, - Spacing.TOP, - Spacing.END, - Spacing.END - }; - - private static boolean isFlexBasisAuto(CSSNode node) - { - if (POSITIVE_FLEX_IS_AUTO) - { - // All flex values are auto. - return true; - } - else - { - // A flex value > 0 implies a basis of zero. - return node.style.flex <= 0; - } - } - - private static float getFlexGrowFactor(CSSNode node) - { - // Flex grow is implied by positive values for flex. - if (node.style.flex > 0) - { - return node.style.flex; - } - return 0; - } - - private static float getFlexShrinkFactor(CSSNode node) - { - if (POSITIVE_FLEX_IS_AUTO) - { - // A flex shrink factor of 1 is implied by non-zero values for flex. - if (node.style.flex != 0) - { - return 1; - } - } - else - { - // A flex shrink factor of 1 is implied by negative values for flex. - if (node.style.flex < 0) - { - return 1; - } - } - return 0; - } - - private static float boundAxisWithinMinAndMax(CSSNode node, int axis, float value) - { - float min = CSSConstants.Undefined; - float max = CSSConstants.Undefined; - - if (axis == CSS_FLEX_DIRECTION_COLUMN || axis == CSS_FLEX_DIRECTION_COLUMN_REVERSE) - { - min = node.style.minHeight; - max = node.style.maxHeight; - } - else if (axis == CSS_FLEX_DIRECTION_ROW || axis == CSS_FLEX_DIRECTION_ROW_REVERSE) - { - min = node.style.minWidth; - max = node.style.maxWidth; - } - - float boundValue = value; - - if (!float.IsNaN(max) && max >= 0.0 && boundValue > max) - { - boundValue = max; - } - if (!float.IsNaN(min) && min >= 0.0 && boundValue < min) - { - boundValue = min; - } - - return boundValue; - } - - private static float boundAxis(CSSNode node, int axis, float value) - { - float paddingAndBorderAxis = - node.style.padding.getWithFallback(leadingSpacing[axis], leading[axis]) + - node.style.border.getWithFallback(leadingSpacing[axis], leading[axis]) + - node.style.padding.getWithFallback(trailingSpacing[axis], trailing[axis]) + - node.style.border.getWithFallback(trailingSpacing[axis], trailing[axis]); - return Math.Max(boundAxisWithinMinAndMax(node, axis, value), paddingAndBorderAxis); - } - - private static float getRelativePosition(CSSNode node, int axis) - { - float lead = node.style.position[leading[axis]]; - if (!float.IsNaN(lead)) - { - return lead; - } - - float trailingPos = node.style.position[trailing[axis]]; - return float.IsNaN(trailingPos) ? 0 : -trailingPos; - } - - private static void setPosition(CSSNode node, CSSDirection direction) - { - int mainAxis = resolveAxis(getFlexDirection(node), direction); - int crossAxis = getCrossFlexDirection(mainAxis, direction); - - node.layout.position[leading[mainAxis]] = node.style.margin.getWithFallback(leadingSpacing[mainAxis], leading[mainAxis]) + - getRelativePosition(node, mainAxis); - node.layout.position[trailing[mainAxis]] = node.style.margin.getWithFallback(trailingSpacing[mainAxis], trailing[mainAxis]) + - getRelativePosition(node, mainAxis); - node.layout.position[leading[crossAxis]] = node.style.margin.getWithFallback(leadingSpacing[crossAxis], leading[crossAxis]) + - getRelativePosition(node, crossAxis); - node.layout.position[trailing[crossAxis]] = node.style.margin.getWithFallback(trailingSpacing[crossAxis], trailing[crossAxis]) + - getRelativePosition(node, crossAxis); - } - - static int resolveAxis(int axis, CSSDirection direction) - { - if (direction == CSSDirection.RTL) - { - if (axis == CSS_FLEX_DIRECTION_ROW) - { - return CSS_FLEX_DIRECTION_ROW_REVERSE; - } - else if (axis == CSS_FLEX_DIRECTION_ROW_REVERSE) - { - return CSS_FLEX_DIRECTION_ROW; - } - } - - return axis; - } - - static CSSDirection resolveDirection(CSSNode node, CSSDirection? parentDirection) - { - CSSDirection direction = node.style.direction; - if (direction == CSSDirection.Inherit) - { - direction = (parentDirection == null ? CSSDirection.LTR : parentDirection.Value); - } - - return direction; - } - - static int getFlexDirection(CSSNode node) - { - return (int)node.style.flexDirection; - } - - private static int getCrossFlexDirection(int axis, CSSDirection direction) - { - if (axis == CSS_FLEX_DIRECTION_COLUMN || axis == CSS_FLEX_DIRECTION_COLUMN_REVERSE) - { - return resolveAxis(CSS_FLEX_DIRECTION_ROW, direction); - } - else - { - return CSS_FLEX_DIRECTION_COLUMN; - } - } - - static CSSAlign getAlignItem(CSSNode node, CSSNode child) - { - if (child.style.alignSelf != CSSAlign.Auto) - { - return child.style.alignSelf; - } - return node.style.alignItems; - } - - static boolean isMeasureDefined(CSSNode node) - { - return node.IsMeasureDefined; - } - - internal static void layoutNode(CSSLayoutContext layoutContext, CSSNode node, float availableWidth, float availableHeight, CSSDirection? parentDirection) - { - // Increment the generation count. This will force the recursive routine to visit - // all dirty nodes at least once. Subsequent visits will be skipped if the input - // parameters don't change. - layoutContext.currentGenerationCount++; - - CSSMeasureMode widthMeasureMode = CSSMeasureMode.Undefined; - CSSMeasureMode heightMeasureMode = CSSMeasureMode.Undefined; - - if (!float.IsNaN(availableWidth)) { - widthMeasureMode = CSSMeasureMode.Exactly; - } else if (node.style.dimensions[DIMENSION_WIDTH] >= 0.0) { - float marginAxisRow = (node.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_ROW], leading[CSS_FLEX_DIRECTION_ROW]) + node.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_ROW], trailing[CSS_FLEX_DIRECTION_ROW])); - availableWidth = node.style.dimensions[DIMENSION_WIDTH] + marginAxisRow; - widthMeasureMode = CSSMeasureMode.Exactly; - } else if (node.style.maxWidth >= 0.0) { - availableWidth = node.style.maxWidth; - widthMeasureMode = CSSMeasureMode.AtMost; - } - - if (!float.IsNaN(availableHeight)) { - heightMeasureMode = CSSMeasureMode.Exactly; - } else if (node.style.dimensions[DIMENSION_HEIGHT] >= 0.0) { - float marginAxisColumn = (node.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + node.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN])); - availableHeight = node.style.dimensions[DIMENSION_HEIGHT] + marginAxisColumn; - heightMeasureMode = CSSMeasureMode.Exactly; - } else if (node.style.maxHeight >= 0.0) { - availableHeight = node.style.maxHeight; - heightMeasureMode = CSSMeasureMode.AtMost; - } - - if (layoutNodeInternal(layoutContext, node, availableWidth, availableHeight, parentDirection, widthMeasureMode, heightMeasureMode, true, "initial")) - { - setPosition(node, node.layout.direction); - } - } - - internal static boolean canUseCachedMeasurement( - boolean isTextNode, - float availableWidth, - float availableHeight, - float marginRow, - float marginColumn, - CSSMeasureMode widthMeasureMode, - CSSMeasureMode heightMeasureMode, - CSSCachedMeasurement cachedLayout) - { - - boolean isHeightSame = - (cachedLayout.heightMeasureMode == CSSMeasureMode.Undefined && heightMeasureMode == CSSMeasureMode.Undefined) || - (cachedLayout.heightMeasureMode == heightMeasureMode && FloatUtil.floatsEqual(cachedLayout.availableHeight, availableHeight)); - - boolean isWidthSame = - (cachedLayout.widthMeasureMode == CSSMeasureMode.Undefined && widthMeasureMode == CSSMeasureMode.Undefined) || - (cachedLayout.widthMeasureMode == widthMeasureMode && FloatUtil.floatsEqual(cachedLayout.availableWidth, availableWidth)); - - if (isHeightSame && isWidthSame) { - return true; - } - - boolean isHeightValid = - (cachedLayout.heightMeasureMode == CSSMeasureMode.Undefined && heightMeasureMode == CSSMeasureMode.AtMost && cachedLayout.computedHeight <= (availableHeight - marginColumn)) || - (heightMeasureMode == CSSMeasureMode.Exactly && FloatUtil.floatsEqual(cachedLayout.computedHeight, availableHeight - marginColumn)); - - if (isWidthSame && isHeightValid) { - return true; - } - - boolean isWidthValid = - (cachedLayout.widthMeasureMode == CSSMeasureMode.Undefined && widthMeasureMode == CSSMeasureMode.AtMost && cachedLayout.computedWidth <= (availableWidth - marginRow)) || - (widthMeasureMode == CSSMeasureMode.Exactly && FloatUtil.floatsEqual(cachedLayout.computedWidth, availableWidth - marginRow)); - - if (isHeightSame && isWidthValid) { - return true; - } - - if (isHeightValid && isWidthValid) { - return true; - } - - // We know this to be text so we can apply some more specialized heuristics. - if (isTextNode) { - if (isWidthSame) { - if (heightMeasureMode == CSSMeasureMode.Undefined) { - // Width is the same and height is not restricted. Re-use cahced value. - return true; - } - - if (heightMeasureMode == CSSMeasureMode.AtMost && - cachedLayout.computedHeight < (availableHeight - marginColumn)) { - // Width is the same and height restriction is greater than the cached height. Re-use cached value. - return true; - } - - // Width is the same but height restriction imposes smaller height than previously measured. - // Update the cached value to respect the new height restriction. - cachedLayout.computedHeight = availableHeight - marginColumn; - return true; - } - - if (cachedLayout.widthMeasureMode == CSSMeasureMode.Undefined) { - if (widthMeasureMode == CSSMeasureMode.Undefined || - (widthMeasureMode == CSSMeasureMode.AtMost && - cachedLayout.computedWidth <= (availableWidth - marginRow))) { - // Previsouly this text was measured with no width restriction, if width is now restricted - // but to a larger value than the previsouly measured width we can re-use the measurement - // as we know it will fit. - return true; - } - } - } - - return false; - } - - // - // This is a wrapper around the layoutNodeImpl function. It determines - // whether the layout request is redundant and can be skipped. - // - // Parameters: - // Input parameters are the same as layoutNodeImpl (see below) - // Return parameter is true if layout was performed, false if skipped - // - internal static boolean layoutNodeInternal(CSSLayoutContext layoutContext, CSSNode node, float availableWidth, float availableHeight, CSSDirection? parentDirection, CSSMeasureMode widthMeasureMode, CSSMeasureMode heightMeasureMode, boolean performLayout, string reason) - { - CSSLayout layout = node.layout; - - boolean needToVisitNode = (node.isDirty() && layout.generationCount != layoutContext.currentGenerationCount) || - layout.lastParentDirection != parentDirection; - - if (needToVisitNode) - { - // Invalidate the cached results. - layout.nextCachedMeasurementsIndex = 0; - layout.cachedLayout.widthMeasureMode = null; - layout.cachedLayout.heightMeasureMode = null; - } - - CSSCachedMeasurement cachedResults = null; - - // Determine whether the results are already cached. We maintain a separate - // cache for layouts and measurements. A layout operation modifies the positions - // and dimensions for nodes in the subtree. The algorithm assumes that each node - // gets layed out a maximum of one time per tree layout, but multiple measurements - // may be required to resolve all of the flex dimensions. - // We handle nodes with measure functions specially here because they are the most - // expensive to measure, so it's worth avoiding redundant measurements if at all possible. - if (isMeasureDefined(node)) - { - float marginAxisRow = - node.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_ROW], leading[CSS_FLEX_DIRECTION_ROW]) + - node.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_ROW], trailing[CSS_FLEX_DIRECTION_ROW]); - float marginAxisColumn = - node.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + - node.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN]); - - // First, try to use the layout cache. - if (canUseCachedMeasurement(node.IsTextNode, availableWidth, availableHeight, marginAxisRow, marginAxisColumn, - widthMeasureMode, heightMeasureMode, layout.cachedLayout)) - { - cachedResults = layout.cachedLayout; - } - else - { - // Try to use the measurement cache. - for (int i = 0; i < layout.nextCachedMeasurementsIndex; i++) - { - if (canUseCachedMeasurement(node.IsTextNode, availableWidth, availableHeight, marginAxisRow, marginAxisColumn, - widthMeasureMode, heightMeasureMode, layout.cachedMeasurements[i])) - { - cachedResults = layout.cachedMeasurements[i]; - break; - } - } - } - } - else if (performLayout) - { - if (FloatUtil.floatsEqual(layout.cachedLayout.availableWidth, availableWidth) && - FloatUtil.floatsEqual(layout.cachedLayout.availableHeight, availableHeight) && - layout.cachedLayout.widthMeasureMode == widthMeasureMode && - layout.cachedLayout.heightMeasureMode == heightMeasureMode) - { - - cachedResults = layout.cachedLayout; - } - } - else - { - for (int i = 0; i < layout.nextCachedMeasurementsIndex; i++) - { - if (FloatUtil.floatsEqual(layout.cachedMeasurements[i].availableWidth, availableWidth) && - FloatUtil.floatsEqual(layout.cachedMeasurements[i].availableHeight, availableHeight) && - layout.cachedMeasurements[i].widthMeasureMode == widthMeasureMode && - layout.cachedMeasurements[i].heightMeasureMode == heightMeasureMode) - { - - cachedResults = layout.cachedMeasurements[i]; - break; - } - } - } - - if (!needToVisitNode && cachedResults != null) - { - layout.measuredDimensions[DIMENSION_WIDTH] = cachedResults.computedWidth; - layout.measuredDimensions[DIMENSION_HEIGHT] = cachedResults.computedHeight; - } - else - { - layoutNodeImpl(layoutContext, node, availableWidth, availableHeight, parentDirection, widthMeasureMode, heightMeasureMode, performLayout); - - layout.lastParentDirection = parentDirection; - - if (cachedResults == null) - { - if (layout.nextCachedMeasurementsIndex == CSSLayout.MAX_CACHED_RESULT_COUNT) - { - layout.nextCachedMeasurementsIndex = 0; - } - - CSSCachedMeasurement newCacheEntry = null; - if (performLayout) - { - // Use the single layout cache entry. - newCacheEntry = layout.cachedLayout; - } - else - { - // Allocate a new measurement cache entry. - newCacheEntry = layout.cachedMeasurements[layout.nextCachedMeasurementsIndex]; - if (newCacheEntry == null) - { - newCacheEntry = new CSSCachedMeasurement(); - layout.cachedMeasurements[layout.nextCachedMeasurementsIndex] = newCacheEntry; - } - layout.nextCachedMeasurementsIndex++; - } - - newCacheEntry.availableWidth = availableWidth; - newCacheEntry.availableHeight = availableHeight; - newCacheEntry.widthMeasureMode = widthMeasureMode; - newCacheEntry.heightMeasureMode = heightMeasureMode; - newCacheEntry.computedWidth = layout.measuredDimensions[DIMENSION_WIDTH]; - newCacheEntry.computedHeight = layout.measuredDimensions[DIMENSION_HEIGHT]; - } - } - - if (performLayout) - { - node.layout.dimensions[DIMENSION_WIDTH] = node.layout.measuredDimensions[DIMENSION_WIDTH]; - node.layout.dimensions[DIMENSION_HEIGHT] = node.layout.measuredDimensions[DIMENSION_HEIGHT]; - node.markHasNewLayout(); - } - - layout.generationCount = layoutContext.currentGenerationCount; - return (needToVisitNode || cachedResults == null); - } - - // - // This is the main routine that implements a subset of the flexbox layout algorithm - // described in the W3C CSS documentation: https://www.w3.org/TR/css3-flexbox/. - // - // Limitations of this algorithm, compared to the full standard: - // * Display property is always assumed to be 'flex' except for Text nodes, which - // are assumed to be 'inline-flex'. - // * The 'zIndex' property (or any form of z ordering) is not supported. Nodes are - // stacked in document order. - // * The 'order' property is not supported. The order of flex items is always defined - // by document order. - // * The 'visibility' property is always assumed to be 'visible'. Values of 'collapse' - // and 'hidden' are not supported. - // * The 'wrap' property supports only 'nowrap' (which is the default) or 'wrap'. The - // rarely-used 'wrap-reverse' is not supported. - // * Rather than allowing arbitrary combinations of flexGrow, flexShrink and - // flexBasis, this algorithm supports only the three most common combinations: - // flex: 0 is equiavlent to flex: 0 0 auto - // flex: n (where n is a positive value) is equivalent to flex: n 1 auto - // If POSITIVE_FLEX_IS_AUTO is 0, then it is equivalent to flex: n 0 0 - // This is faster because the content doesn't need to be measured, but it's - // less flexible because the basis is always 0 and can't be overriden with - // the width/height attributes. - // flex: -1 (or any negative value) is equivalent to flex: 0 1 auto - // * Margins cannot be specified as 'auto'. They must be specified in terms of pixel - // values, and the default value is 0. - // * The 'baseline' value is not supported for alignItems and alignSelf properties. - // * Values of width, maxWidth, minWidth, height, maxHeight and minHeight must be - // specified as pixel values, not as percentages. - // * There is no support for calculation of dimensions based on intrinsic aspect ratios - // (e.g. images). - // * There is no support for forced breaks. - // * It does not support vertical inline directions (top-to-bottom or bottom-to-top text). - // - // Deviations from standard: - // * Section 4.5 of the spec indicates that all flex items have a default minimum - // main size. For text blocks, for example, this is the width of the widest word. - // Calculating the minimum width is expensive, so we forego it and assume a default - // minimum main size of 0. - // * Min/Max sizes in the main axis are not honored when resolving flexible lengths. - // * The spec indicates that the default value for 'flexDirection' is 'row', but - // the algorithm below assumes a default of 'column'. - // - // Input parameters: - // - node: current node to be sized and layed out - // - availableWidth & availableHeight: available size to be used for sizing the node - // or CSS_UNDEFINED if the size is not available; interpretation depends on layout - // flags - // - parentDirection: the inline (text) direction within the parent (left-to-right or - // right-to-left) - // - widthMeasureMode: indicates the sizing rules for the width (see below for explanation) - // - heightMeasureMode: indicates the sizing rules for the height (see below for explanation) - // - performLayout: specifies whether the caller is interested in just the dimensions - // of the node or it requires the entire node and its subtree to be layed out - // (with final positions) - // - // Details: - // This routine is called recursively to lay out subtrees of flexbox elements. It uses the - // information in node.style, which is treated as a read-only input. It is responsible for - // setting the layout.direction and layout.measured_dimensions fields for the input node as well - // as the layout.position and layout.line_index fields for its child nodes. The - // layout.measured_dimensions field includes any border or padding for the node but does - // not include margins. - // - // The spec describes four different layout modes: "fill available", "max content", "min content", - // and "fit content". Of these, we don't use "min content" because we don't support default - // minimum main sizes (see above for details). Each of our measure modes maps to a layout mode - // from the spec (https://www.w3.org/TR/css3-sizing/#terms): - // - CSS_MEASURE_MODE_UNDEFINED: max content - // - CSS_MEASURE_MODE_EXACTLY: fill available - // - CSS_MEASURE_MODE_AT_MOST: fit content - // - // When calling layoutNodeImpl and layoutNodeInternal, if the caller passes an available size of - // undefined then it must also pass a measure mode of CSS_MEASURE_MODE_UNDEFINED in that dimension. - // - static void layoutNodeImpl(CSSLayoutContext layoutContext, CSSNode node, float availableWidth, float availableHeight, CSSDirection? parentDirection, CSSMeasureMode widthMeasureMode, CSSMeasureMode heightMeasureMode, boolean performLayout) - { - /** START_GENERATED **/ - - Assertions.assertCondition(float.IsNaN(availableWidth) ? widthMeasureMode == CSSMeasureMode.Undefined : true, "availableWidth is indefinite so widthMeasureMode must be CSSMeasureMode.Undefined"); - Assertions.assertCondition(float.IsNaN(availableHeight) ? heightMeasureMode == CSSMeasureMode.Undefined : true, "availableHeight is indefinite so heightMeasureMode must be CSSMeasureMode.Undefined"); - - float paddingAndBorderAxisRow = ((node.style.padding.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_ROW], leading[CSS_FLEX_DIRECTION_ROW]) + node.style.border.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_ROW], leading[CSS_FLEX_DIRECTION_ROW])) + (node.style.padding.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_ROW], trailing[CSS_FLEX_DIRECTION_ROW]) + node.style.border.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_ROW], trailing[CSS_FLEX_DIRECTION_ROW]))); - float paddingAndBorderAxisColumn = ((node.style.padding.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + node.style.border.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN])) + (node.style.padding.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN]) + node.style.border.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN]))); - float marginAxisRow = (node.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_ROW], leading[CSS_FLEX_DIRECTION_ROW]) + node.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_ROW], trailing[CSS_FLEX_DIRECTION_ROW])); - float marginAxisColumn = (node.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + node.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN])); - - // Set the resolved resolution in the node's layout. - CSSDirection direction = resolveDirection(node, parentDirection); - node.layout.direction = direction; - - // For content (text) nodes, determine the dimensions based on the text contents. - if (isMeasureDefined(node)) { - float innerWidth = availableWidth - marginAxisRow - paddingAndBorderAxisRow; - float innerHeight = availableHeight - marginAxisColumn - paddingAndBorderAxisColumn; - - if (widthMeasureMode == CSSMeasureMode.Exactly && heightMeasureMode == CSSMeasureMode.Exactly) { - - // Don't bother sizing the text if both dimensions are already defined. - node.layout.measuredDimensions[DIMENSION_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, availableWidth - marginAxisRow); - node.layout.measuredDimensions[DIMENSION_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, availableHeight - marginAxisColumn); - } else if (innerWidth <= 0 || innerHeight <= 0) { - - // Don't bother sizing the text if there's no horizontal or vertical space. - node.layout.measuredDimensions[DIMENSION_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, 0); - node.layout.measuredDimensions[DIMENSION_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, 0); - } else { - - // Measure the text under the current constraints. - MeasureOutput measureDim = node.measure( - - layoutContext.measureOutput, - innerWidth, - widthMeasureMode, - innerHeight, - heightMeasureMode - ); - - node.layout.measuredDimensions[DIMENSION_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, - (widthMeasureMode == CSSMeasureMode.Undefined || widthMeasureMode == CSSMeasureMode.AtMost) ? - measureDim.width + paddingAndBorderAxisRow : - availableWidth - marginAxisRow); - node.layout.measuredDimensions[DIMENSION_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, - (heightMeasureMode == CSSMeasureMode.Undefined || heightMeasureMode == CSSMeasureMode.AtMost) ? - measureDim.height + paddingAndBorderAxisColumn : - availableHeight - marginAxisColumn); - } - - return; - } - - // For nodes with no children, use the available values if they were provided, or - // the minimum size as indicated by the padding and border sizes. - int childCount = node.getChildCount(); - if (childCount == 0) { - node.layout.measuredDimensions[DIMENSION_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, - (widthMeasureMode == CSSMeasureMode.Undefined || widthMeasureMode == CSSMeasureMode.AtMost) ? - paddingAndBorderAxisRow : - availableWidth - marginAxisRow); - node.layout.measuredDimensions[DIMENSION_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, - (heightMeasureMode == CSSMeasureMode.Undefined || heightMeasureMode == CSSMeasureMode.AtMost) ? - paddingAndBorderAxisColumn : - availableHeight - marginAxisColumn); - return; - } - - // If we're not being asked to perform a full layout, we can handle a number of common - // cases here without incurring the cost of the remaining function. - if (!performLayout) { - // If we're being asked to size the content with an at most constraint but there is no available width, - // the measurement will always be zero. - if (widthMeasureMode == CSSMeasureMode.AtMost && availableWidth <= 0 && - heightMeasureMode == CSSMeasureMode.AtMost && availableHeight <= 0) { - node.layout.measuredDimensions[DIMENSION_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, 0); - node.layout.measuredDimensions[DIMENSION_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, 0); - return; - } - - if (widthMeasureMode == CSSMeasureMode.AtMost && availableWidth <= 0) { - node.layout.measuredDimensions[DIMENSION_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, 0); - node.layout.measuredDimensions[DIMENSION_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, float.IsNaN(availableHeight) ? 0 : (availableHeight - marginAxisColumn)); - return; - } - - if (heightMeasureMode == CSSMeasureMode.AtMost && availableHeight <= 0) { - node.layout.measuredDimensions[DIMENSION_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, float.IsNaN(availableWidth) ? 0 : (availableWidth - marginAxisRow)); - node.layout.measuredDimensions[DIMENSION_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, 0); - return; - } - - // If we're being asked to use an exact width/height, there's no need to measure the children. - if (widthMeasureMode == CSSMeasureMode.Exactly && heightMeasureMode == CSSMeasureMode.Exactly) { - node.layout.measuredDimensions[DIMENSION_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, availableWidth - marginAxisRow); - node.layout.measuredDimensions[DIMENSION_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, availableHeight - marginAxisColumn); - return; - } - } - - // STEP 1: CALCULATE VALUES FOR REMAINDER OF ALGORITHM - int mainAxis = resolveAxis(getFlexDirection(node), direction); - int crossAxis = getCrossFlexDirection(mainAxis, direction); - boolean isMainAxisRow = (mainAxis == CSS_FLEX_DIRECTION_ROW || mainAxis == CSS_FLEX_DIRECTION_ROW_REVERSE); - CSSJustify justifyContent = node.style.justifyContent; - boolean isNodeFlexWrap = (node.style.flexWrap == CSSWrap.Wrap); - - CSSNode firstAbsoluteChild = null; - CSSNode currentAbsoluteChild = null; - - float leadingPaddingAndBorderMain = (node.style.padding.getWithFallback(leadingSpacing[mainAxis], leading[mainAxis]) + node.style.border.getWithFallback(leadingSpacing[mainAxis], leading[mainAxis])); - float trailingPaddingAndBorderMain = (node.style.padding.getWithFallback(trailingSpacing[mainAxis], trailing[mainAxis]) + node.style.border.getWithFallback(trailingSpacing[mainAxis], trailing[mainAxis])); - float leadingPaddingAndBorderCross = (node.style.padding.getWithFallback(leadingSpacing[crossAxis], leading[crossAxis]) + node.style.border.getWithFallback(leadingSpacing[crossAxis], leading[crossAxis])); - float paddingAndBorderAxisMain = ((node.style.padding.getWithFallback(leadingSpacing[mainAxis], leading[mainAxis]) + node.style.border.getWithFallback(leadingSpacing[mainAxis], leading[mainAxis])) + (node.style.padding.getWithFallback(trailingSpacing[mainAxis], trailing[mainAxis]) + node.style.border.getWithFallback(trailingSpacing[mainAxis], trailing[mainAxis]))); - float paddingAndBorderAxisCross = ((node.style.padding.getWithFallback(leadingSpacing[crossAxis], leading[crossAxis]) + node.style.border.getWithFallback(leadingSpacing[crossAxis], leading[crossAxis])) + (node.style.padding.getWithFallback(trailingSpacing[crossAxis], trailing[crossAxis]) + node.style.border.getWithFallback(trailingSpacing[crossAxis], trailing[crossAxis]))); - - CSSMeasureMode measureModeMainDim = isMainAxisRow ? widthMeasureMode : heightMeasureMode; - CSSMeasureMode measureModeCrossDim = isMainAxisRow ? heightMeasureMode : widthMeasureMode; - - // STEP 2: DETERMINE AVAILABLE SIZE IN MAIN AND CROSS DIRECTIONS - float availableInnerWidth = availableWidth - marginAxisRow - paddingAndBorderAxisRow; - float availableInnerHeight = availableHeight - marginAxisColumn - paddingAndBorderAxisColumn; - float availableInnerMainDim = isMainAxisRow ? availableInnerWidth : availableInnerHeight; - float availableInnerCrossDim = isMainAxisRow ? availableInnerHeight : availableInnerWidth; - - // STEP 3: DETERMINE FLEX BASIS FOR EACH ITEM - CSSNode child; - int i; - float childWidth; - float childHeight; - CSSMeasureMode childWidthMeasureMode; - CSSMeasureMode childHeightMeasureMode; - for (i = 0; i < childCount; i++) { - child = node.getChildAt(i); - - if (performLayout) { - // Set the initial position (relative to the parent). - CSSDirection childDirection = resolveDirection(child, direction); - setPosition(child, childDirection); - } - - // Absolute-positioned children don't participate in flex layout. Add them - // to a list that we can process later. - if (child.style.positionType == CSSPositionType.Absolute) { - - // Store a private linked list of absolutely positioned children - // so that we can efficiently traverse them later. - if (firstAbsoluteChild == null) { - firstAbsoluteChild = child; - } - if (currentAbsoluteChild != null) { - currentAbsoluteChild.nextChild = child; - } - currentAbsoluteChild = child; - child.nextChild = null; - } else { - - if (isMainAxisRow && (child.style.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] >= 0.0)) { - - // The width is definite, so use that as the flex basis. - child.layout.flexBasis = Math.Max(child.style.dimensions[DIMENSION_WIDTH], ((child.style.padding.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_ROW], leading[CSS_FLEX_DIRECTION_ROW]) + child.style.border.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_ROW], leading[CSS_FLEX_DIRECTION_ROW])) + (child.style.padding.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_ROW], trailing[CSS_FLEX_DIRECTION_ROW]) + child.style.border.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_ROW], trailing[CSS_FLEX_DIRECTION_ROW])))); - } else if (!isMainAxisRow && (child.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0)) { - - // The height is definite, so use that as the flex basis. - child.layout.flexBasis = Math.Max(child.style.dimensions[DIMENSION_HEIGHT], ((child.style.padding.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + child.style.border.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN])) + (child.style.padding.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN]) + child.style.border.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN])))); - } else if (!isFlexBasisAuto(child) && !float.IsNaN(availableInnerMainDim)) { - - // If the basis isn't 'auto', it is assumed to be zero. - child.layout.flexBasis = Math.Max(0, ((child.style.padding.getWithFallback(leadingSpacing[mainAxis], leading[mainAxis]) + child.style.border.getWithFallback(leadingSpacing[mainAxis], leading[mainAxis])) + (child.style.padding.getWithFallback(trailingSpacing[mainAxis], trailing[mainAxis]) + child.style.border.getWithFallback(trailingSpacing[mainAxis], trailing[mainAxis])))); - } else { - - // Compute the flex basis and hypothetical main size (i.e. the clamped flex basis). - childWidth = CSSConstants.Undefined; - childHeight = CSSConstants.Undefined; - childWidthMeasureMode = CSSMeasureMode.Undefined; - childHeightMeasureMode = CSSMeasureMode.Undefined; - - if ((child.style.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] >= 0.0)) { - childWidth = child.style.dimensions[DIMENSION_WIDTH] + (child.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_ROW], leading[CSS_FLEX_DIRECTION_ROW]) + child.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_ROW], trailing[CSS_FLEX_DIRECTION_ROW])); - childWidthMeasureMode = CSSMeasureMode.Exactly; - } - if ((child.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0)) { - childHeight = child.style.dimensions[DIMENSION_HEIGHT] + (child.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + child.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN])); - childHeightMeasureMode = CSSMeasureMode.Exactly; - } - - // According to the spec, if the main size is not definite and the - // child's inline axis is parallel to the main axis (i.e. it's - // horizontal), the child should be sized using "UNDEFINED" in - // the main size. Otherwise use "AT_MOST" in the cross axis. - if (!isMainAxisRow && float.IsNaN(childWidth) && !float.IsNaN(availableInnerWidth)) { - childWidth = availableInnerWidth; - childWidthMeasureMode = CSSMeasureMode.AtMost; - } - - // The W3C spec doesn't say anything about the 'overflow' property, - // but all major browsers appear to implement the following logic. - if (node.style.overflow == CSSOverflow.Hidden) { - if (isMainAxisRow && float.IsNaN(childHeight) && !float.IsNaN(availableInnerHeight)) { - childHeight = availableInnerHeight; - childHeightMeasureMode = CSSMeasureMode.AtMost; - } - } - - // If child has no defined size in the cross axis and is set to stretch, set the cross - // axis to be measured exactly with the available inner width - if (!isMainAxisRow && - !float.IsNaN(availableInnerWidth) && - !(child.style.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] >= 0.0) && - widthMeasureMode == CSSMeasureMode.Exactly && - getAlignItem(node, child) == CSSAlign.Stretch) { - childWidth = availableInnerWidth; - childWidthMeasureMode = CSSMeasureMode.Exactly; - } - if (isMainAxisRow && - !float.IsNaN(availableInnerHeight) && - !(child.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0) && - heightMeasureMode == CSSMeasureMode.Exactly && - getAlignItem(node, child) == CSSAlign.Stretch) { - childHeight = availableInnerHeight; - childHeightMeasureMode = CSSMeasureMode.Exactly; - } - - // Measure the child - layoutNodeInternal(layoutContext, child, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, false, "measure"); - - child.layout.flexBasis = Math.Max(isMainAxisRow ? child.layout.measuredDimensions[DIMENSION_WIDTH] : child.layout.measuredDimensions[DIMENSION_HEIGHT], ((child.style.padding.getWithFallback(leadingSpacing[mainAxis], leading[mainAxis]) + child.style.border.getWithFallback(leadingSpacing[mainAxis], leading[mainAxis])) + (child.style.padding.getWithFallback(trailingSpacing[mainAxis], trailing[mainAxis]) + child.style.border.getWithFallback(trailingSpacing[mainAxis], trailing[mainAxis])))); - } - } - } - - // STEP 4: COLLECT FLEX ITEMS INTO FLEX LINES - - // Indexes of children that represent the first and last items in the line. - int startOfLineIndex = 0; - int endOfLineIndex = 0; - - // Number of lines. - int lineCount = 0; - - // Accumulated cross dimensions of all lines so far. - float totalLineCrossDim = 0; - - // Max main dimension of all the lines. - float maxLineMainDim = 0; - - while (endOfLineIndex < childCount) { - - // Number of items on the currently line. May be different than the difference - // between start and end indicates because we skip over absolute-positioned items. - int itemsOnLine = 0; - - // sizeConsumedOnCurrentLine is accumulation of the dimensions and margin - // of all the children on the current line. 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 sizeConsumedOnCurrentLine = 0; - - float totalFlexGrowFactors = 0; - float totalFlexShrinkScaledFactors = 0; - - i = startOfLineIndex; - - // Maintain a linked list of the child nodes that can shrink and/or grow. - CSSNode firstRelativeChild = null; - CSSNode currentRelativeChild = null; - - // Add items to the current line until it's full or we run out of items. - while (i < childCount) { - child = node.getChildAt(i); - child.lineIndex = lineCount; - - if (child.style.positionType != CSSPositionType.Absolute) { - float outerFlexBasis = child.layout.flexBasis + (child.style.margin.getWithFallback(leadingSpacing[mainAxis], leading[mainAxis]) + child.style.margin.getWithFallback(trailingSpacing[mainAxis], trailing[mainAxis])); - - // If this is a multi-line flow and this item pushes us over the available size, we've - // hit the end of the current line. Break out of the loop and lay out the current line. - if (sizeConsumedOnCurrentLine + outerFlexBasis > availableInnerMainDim && isNodeFlexWrap && itemsOnLine > 0) { - break; - } - - sizeConsumedOnCurrentLine += outerFlexBasis; - itemsOnLine++; - - if ((child.style.positionType == CSSPositionType.Relative && child.style.flex != 0)) { - totalFlexGrowFactors += getFlexGrowFactor(child); - - // Unlike the grow factor, the shrink factor is scaled relative to the child - // dimension. - totalFlexShrinkScaledFactors += getFlexShrinkFactor(child) * child.layout.flexBasis; - } - - // Store a private linked list of children that need to be layed out. - if (firstRelativeChild == null) { - firstRelativeChild = child; - } - if (currentRelativeChild != null) { - currentRelativeChild.nextChild = child; - } - currentRelativeChild = child; - child.nextChild = null; - } - - i++; - endOfLineIndex++; - } - - // If we don't need to measure the cross axis, we can skip the entire flex step. - boolean canSkipFlex = !performLayout && measureModeCrossDim == CSSMeasureMode.Exactly; - - // 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; - - // STEP 5: RESOLVING FLEXIBLE LENGTHS ON MAIN AXIS - // Calculate the remaining available space that needs to be allocated. - // If the main dimension size isn't known, it is computed based on - // the line length, so there's no more space left to distribute. - float remainingFreeSpace = 0; - if (!float.IsNaN(availableInnerMainDim)) { - remainingFreeSpace = availableInnerMainDim - sizeConsumedOnCurrentLine; - } else if (sizeConsumedOnCurrentLine < 0) { - // availableInnerMainDim is indefinite which means the node is being sized based on its content. - // sizeConsumedOnCurrentLine is negative which means the node will allocate 0 pixels for - // its content. Consequently, remainingFreeSpace is 0 - sizeConsumedOnCurrentLine. - remainingFreeSpace = -sizeConsumedOnCurrentLine; - } - - float originalRemainingFreeSpace = remainingFreeSpace; - float deltaFreeSpace = 0; - - if (!canSkipFlex) { - float childFlexBasis; - float flexShrinkScaledFactor; - float flexGrowFactor; - float baseMainSize; - float boundMainSize; - - // Do two passes over the flex items to figure out how to distribute the remaining space. - // The first pass finds the items whose min/max constraints trigger, freezes them at those - // sizes, and excludes those sizes from the remaining space. The second pass sets the size - // of each flexible item. It distributes the remaining space amongst the items whose min/max - // constraints didn't trigger in pass 1. For the other items, it sets their sizes by forcing - // their min/max constraints to trigger again. - // - // This two pass approach for resolving min/max constraints deviates from the spec. The - // spec (https://www.w3.org/TR/css-flexbox-1/#resolve-flexible-lengths) describes a process - // that needs to be repeated a variable number of times. The algorithm implemented here - // won't handle all cases but it was simpler to implement and it mitigates performance - // concerns because we know exactly how many passes it'll do. - - // First pass: detect the flex items whose min/max constraints trigger - float deltaFlexShrinkScaledFactors = 0; - float deltaFlexGrowFactors = 0; - currentRelativeChild = firstRelativeChild; - while (currentRelativeChild != null) { - childFlexBasis = currentRelativeChild.layout.flexBasis; - - if (remainingFreeSpace < 0) { - flexShrinkScaledFactor = getFlexShrinkFactor(currentRelativeChild) * childFlexBasis; - - // Is this child able to shrink? - if (flexShrinkScaledFactor != 0) { - baseMainSize = childFlexBasis + - remainingFreeSpace / totalFlexShrinkScaledFactors * flexShrinkScaledFactor; - boundMainSize = boundAxis(currentRelativeChild, mainAxis, baseMainSize); - if (baseMainSize != boundMainSize) { - // By excluding this item's size and flex factor from remaining, this item's - // min/max constraints should also trigger in the second pass resulting in the - // item's size calculation being identical in the first and second passes. - deltaFreeSpace -= boundMainSize - childFlexBasis; - deltaFlexShrinkScaledFactors -= flexShrinkScaledFactor; - } - } - } else if (remainingFreeSpace > 0) { - flexGrowFactor = getFlexGrowFactor(currentRelativeChild); - - // Is this child able to grow? - if (flexGrowFactor != 0) { - baseMainSize = childFlexBasis + - remainingFreeSpace / totalFlexGrowFactors * flexGrowFactor; - boundMainSize = boundAxis(currentRelativeChild, mainAxis, baseMainSize); - if (baseMainSize != boundMainSize) { - // By excluding this item's size and flex factor from remaining, this item's - // min/max constraints should also trigger in the second pass resulting in the - // item's size calculation being identical in the first and second passes. - deltaFreeSpace -= boundMainSize - childFlexBasis; - deltaFlexGrowFactors -= flexGrowFactor; - } - } - } - - currentRelativeChild = currentRelativeChild.nextChild; - } - - totalFlexShrinkScaledFactors += deltaFlexShrinkScaledFactors; - totalFlexGrowFactors += deltaFlexGrowFactors; - remainingFreeSpace += deltaFreeSpace; - - // Second pass: resolve the sizes of the flexible items - deltaFreeSpace = 0; - currentRelativeChild = firstRelativeChild; - while (currentRelativeChild != null) { - childFlexBasis = currentRelativeChild.layout.flexBasis; - float updatedMainSize = childFlexBasis; - - if (remainingFreeSpace < 0) { - flexShrinkScaledFactor = getFlexShrinkFactor(currentRelativeChild) * childFlexBasis; - - // Is this child able to shrink? - if (flexShrinkScaledFactor != 0) { - updatedMainSize = boundAxis(currentRelativeChild, mainAxis, childFlexBasis + - remainingFreeSpace / totalFlexShrinkScaledFactors * flexShrinkScaledFactor); - } - } else if (remainingFreeSpace > 0) { - flexGrowFactor = getFlexGrowFactor(currentRelativeChild); - - // Is this child able to grow? - if (flexGrowFactor != 0) { - updatedMainSize = boundAxis(currentRelativeChild, mainAxis, childFlexBasis + - remainingFreeSpace / totalFlexGrowFactors * flexGrowFactor); - } - } - - deltaFreeSpace -= updatedMainSize - childFlexBasis; - - if (isMainAxisRow) { - childWidth = updatedMainSize + (currentRelativeChild.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_ROW], leading[CSS_FLEX_DIRECTION_ROW]) + currentRelativeChild.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_ROW], trailing[CSS_FLEX_DIRECTION_ROW])); - childWidthMeasureMode = CSSMeasureMode.Exactly; - - if (!float.IsNaN(availableInnerCrossDim) && - !(currentRelativeChild.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0) && - heightMeasureMode == CSSMeasureMode.Exactly && - getAlignItem(node, currentRelativeChild) == CSSAlign.Stretch) { - childHeight = availableInnerCrossDim; - childHeightMeasureMode = CSSMeasureMode.Exactly; - } else if (!(currentRelativeChild.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0)) { - childHeight = availableInnerCrossDim; - childHeightMeasureMode = float.IsNaN(childHeight) ? CSSMeasureMode.Undefined : CSSMeasureMode.AtMost; - } else { - childHeight = currentRelativeChild.style.dimensions[DIMENSION_HEIGHT] + (currentRelativeChild.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + currentRelativeChild.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN])); - childHeightMeasureMode = CSSMeasureMode.Exactly; - } - } else { - childHeight = updatedMainSize + (currentRelativeChild.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + currentRelativeChild.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN])); - childHeightMeasureMode = CSSMeasureMode.Exactly; - - if (!float.IsNaN(availableInnerCrossDim) && - !(currentRelativeChild.style.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] >= 0.0) && - widthMeasureMode == CSSMeasureMode.Exactly && - getAlignItem(node, currentRelativeChild) == CSSAlign.Stretch) { - childWidth = availableInnerCrossDim; - childWidthMeasureMode = CSSMeasureMode.Exactly; - } else if (!(currentRelativeChild.style.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] >= 0.0)) { - childWidth = availableInnerCrossDim; - childWidthMeasureMode = float.IsNaN(childWidth) ? CSSMeasureMode.Undefined : CSSMeasureMode.AtMost; - } else { - childWidth = currentRelativeChild.style.dimensions[DIMENSION_WIDTH] + (currentRelativeChild.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_ROW], leading[CSS_FLEX_DIRECTION_ROW]) + currentRelativeChild.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_ROW], trailing[CSS_FLEX_DIRECTION_ROW])); - childWidthMeasureMode = CSSMeasureMode.Exactly; - } - } - - boolean requiresStretchLayout = !(currentRelativeChild.style.dimensions[dim[crossAxis]] >= 0.0) && - getAlignItem(node, currentRelativeChild) == CSSAlign.Stretch; - - // Recursively call the layout algorithm for this child with the updated main size. - layoutNodeInternal(layoutContext, currentRelativeChild, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, performLayout && !requiresStretchLayout, "flex"); - - currentRelativeChild = currentRelativeChild.nextChild; - } - } - - remainingFreeSpace = originalRemainingFreeSpace + deltaFreeSpace; - - // STEP 6: MAIN-AXIS JUSTIFICATION & CROSS-AXIS SIZE DETERMINATION - - // At this point, all the children have their dimensions set in the main axis. - // Their dimensions are also set in the cross axis with the exception of items - // that are aligned "stretch". We need to compute these stretch values and - // set the final positions. - - // If we are using "at most" rules in the main axis, we won't distribute - // any remaining space at this point. - if (measureModeMainDim == CSSMeasureMode.AtMost) { - remainingFreeSpace = 0; - } - - // Use justifyContent to figure out how to allocate the remaining space - // available in the main axis. - if (justifyContent != CSSJustify.FlexStart) { - if (justifyContent == CSSJustify.Center) { - leadingMainDim = remainingFreeSpace / 2; - } else if (justifyContent == CSSJustify.FlexEnd) { - leadingMainDim = remainingFreeSpace; - } else if (justifyContent == CSSJustify.SpaceBetween) { - remainingFreeSpace = Math.Max(remainingFreeSpace, 0); - if (itemsOnLine > 1) { - betweenMainDim = remainingFreeSpace / (itemsOnLine - 1); - } else { - betweenMainDim = 0; - } - } else if (justifyContent == CSSJustify.SpaceAround) { - // Space on the edges is half of the space between elements - betweenMainDim = remainingFreeSpace / itemsOnLine; - leadingMainDim = betweenMainDim / 2; - } - } - - float mainDim = leadingPaddingAndBorderMain + leadingMainDim; - float crossDim = 0; - - for (i = startOfLineIndex; i < endOfLineIndex; ++i) { - child = node.getChildAt(i); - - if (child.style.positionType == CSSPositionType.Absolute && - !float.IsNaN(child.style.position[leading[mainAxis]])) { - if (performLayout) { - // 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). - child.layout.position[pos[mainAxis]] = (float.IsNaN(child.style.position[leading[mainAxis]]) ? 0 : child.style.position[leading[mainAxis]]) + - node.style.border.getWithFallback(leadingSpacing[mainAxis], leading[mainAxis]) + - child.style.margin.getWithFallback(leadingSpacing[mainAxis], leading[mainAxis]); - } - } else { - if (performLayout) { - // If the child is position absolute (without top/left) or relative, - // we put it at the current accumulated offset. - child.layout.position[pos[mainAxis]] += mainDim; - } - - // Now that we placed the element, we need to update the variables. - // We need to do that only for relative elements. Absolute elements - // do not take part in that phase. - if (child.style.positionType == CSSPositionType.Relative) { - if (canSkipFlex) { - // If we skipped the flex step, then we can't rely on the measuredDims because - // they weren't computed. This means we can't call getDimWithMargin. - mainDim += betweenMainDim + (child.style.margin.getWithFallback(leadingSpacing[mainAxis], leading[mainAxis]) + child.style.margin.getWithFallback(trailingSpacing[mainAxis], trailing[mainAxis])) + child.layout.flexBasis; - crossDim = availableInnerCrossDim; - } else { - // The main dimension is the sum of all the elements dimension plus - // the spacing. - mainDim += betweenMainDim + (child.layout.measuredDimensions[dim[mainAxis]] + child.style.margin.getWithFallback(leadingSpacing[mainAxis], leading[mainAxis]) + child.style.margin.getWithFallback(trailingSpacing[mainAxis], trailing[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, (child.layout.measuredDimensions[dim[crossAxis]] + child.style.margin.getWithFallback(leadingSpacing[crossAxis], leading[crossAxis]) + child.style.margin.getWithFallback(trailingSpacing[crossAxis], trailing[crossAxis]))); - } - } - } - } - - mainDim += trailingPaddingAndBorderMain; - - float containerCrossAxis = availableInnerCrossDim; - if (measureModeCrossDim == CSSMeasureMode.Undefined || measureModeCrossDim == CSSMeasureMode.AtMost) { - // Compute the cross axis from the max cross dimension of the children. - containerCrossAxis = boundAxis(node, crossAxis, crossDim + paddingAndBorderAxisCross) - paddingAndBorderAxisCross; - - if (measureModeCrossDim == CSSMeasureMode.AtMost) { - containerCrossAxis = Math.Min(containerCrossAxis, availableInnerCrossDim); - } - } - - // If there's no flex wrap, the cross dimension is defined by the container. - if (!isNodeFlexWrap && measureModeCrossDim == CSSMeasureMode.Exactly) { - crossDim = availableInnerCrossDim; - } - - // Clamp to the min/max size specified on the container. - crossDim = boundAxis(node, crossAxis, crossDim + paddingAndBorderAxisCross) - paddingAndBorderAxisCross; - - // STEP 7: CROSS-AXIS ALIGNMENT - // We can skip child alignment if we're just measuring the container. - if (performLayout) { - for (i = startOfLineIndex; i < endOfLineIndex; ++i) { - child = node.getChildAt(i); - - if (child.style.positionType == CSSPositionType.Absolute) { - // If the child is absolutely positioned and has a top/left/bottom/right - // set, override all the previously computed positions to set it correctly. - if (!float.IsNaN(child.style.position[leading[crossAxis]])) { - child.layout.position[pos[crossAxis]] = (float.IsNaN(child.style.position[leading[crossAxis]]) ? 0 : child.style.position[leading[crossAxis]]) + - node.style.border.getWithFallback(leadingSpacing[crossAxis], leading[crossAxis]) + - child.style.margin.getWithFallback(leadingSpacing[crossAxis], leading[crossAxis]); - } else { - child.layout.position[pos[crossAxis]] = leadingPaddingAndBorderCross + - child.style.margin.getWithFallback(leadingSpacing[crossAxis], leading[crossAxis]); - } - } else { - float leadingCrossDim = leadingPaddingAndBorderCross; - - // For a relative children, we're either using alignItems (parent) or - // alignSelf (child) in order to determine the position in the cross axis - CSSAlign alignItem = getAlignItem(node, child); - - // If the child uses align stretch, we need to lay it out one more time, this time - // forcing the cross-axis size to be the computed cross size for the current line. - if (alignItem == CSSAlign.Stretch) { - childWidth = child.layout.measuredDimensions[DIMENSION_WIDTH] + (child.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_ROW], leading[CSS_FLEX_DIRECTION_ROW]) + child.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_ROW], trailing[CSS_FLEX_DIRECTION_ROW])); - childHeight = child.layout.measuredDimensions[DIMENSION_HEIGHT] + (child.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + child.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN])); - boolean isCrossSizeDefinite = false; - - if (isMainAxisRow) { - isCrossSizeDefinite = (child.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0); - childHeight = crossDim; - } else { - isCrossSizeDefinite = (child.style.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] >= 0.0); - childWidth = crossDim; - } - - // If the child defines a definite size for its cross axis, there's no need to stretch. - if (!isCrossSizeDefinite) { - childWidthMeasureMode = float.IsNaN(childWidth) ? CSSMeasureMode.Undefined : CSSMeasureMode.Exactly; - childHeightMeasureMode = float.IsNaN(childHeight) ? CSSMeasureMode.Undefined : CSSMeasureMode.Exactly; - layoutNodeInternal(layoutContext, child, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, true, "stretch"); - } - } else if (alignItem != CSSAlign.FlexStart) { - float remainingCrossDim = containerCrossAxis - (child.layout.measuredDimensions[dim[crossAxis]] + child.style.margin.getWithFallback(leadingSpacing[crossAxis], leading[crossAxis]) + child.style.margin.getWithFallback(trailingSpacing[crossAxis], trailing[crossAxis])); - - if (alignItem == CSSAlign.Center) { - leadingCrossDim += remainingCrossDim / 2; - } else { // CSSAlign.FlexEnd - leadingCrossDim += remainingCrossDim; - } - } - - // And we apply the position - child.layout.position[pos[crossAxis]] += totalLineCrossDim + leadingCrossDim; - } - } - } - - totalLineCrossDim += crossDim; - maxLineMainDim = Math.Max(maxLineMainDim, mainDim); - - // Reset variables for new line. - lineCount++; - startOfLineIndex = endOfLineIndex; - endOfLineIndex = startOfLineIndex; - } - - // STEP 8: MULTI-LINE CONTENT ALIGNMENT - if (lineCount > 1 && performLayout && !float.IsNaN(availableInnerCrossDim)) { - float remainingAlignContentDim = availableInnerCrossDim - totalLineCrossDim; - - float crossDimLead = 0; - float currentLead = leadingPaddingAndBorderCross; - - CSSAlign alignContent = node.style.alignContent; - if (alignContent == CSSAlign.FlexEnd) { - currentLead += remainingAlignContentDim; - } else if (alignContent == CSSAlign.Center) { - currentLead += remainingAlignContentDim / 2; - } else if (alignContent == CSSAlign.Stretch) { - if (availableInnerCrossDim > totalLineCrossDim) { - crossDimLead = (remainingAlignContentDim / lineCount); - } - } - - int endIndex = 0; - for (i = 0; i < lineCount; ++i) { - int startIndex = endIndex; - int j; - - // compute the line's height and find the endIndex - float lineHeight = 0; - for (j = startIndex; j < childCount; ++j) { - child = node.getChildAt(j); - if (child.style.positionType != CSSPositionType.Relative) { - continue; - } - if (child.lineIndex != i) { - break; - } - if ((child.layout.measuredDimensions[dim[crossAxis]] >= 0.0)) { - lineHeight = Math.Max(lineHeight, - child.layout.measuredDimensions[dim[crossAxis]] + (child.style.margin.getWithFallback(leadingSpacing[crossAxis], leading[crossAxis]) + child.style.margin.getWithFallback(trailingSpacing[crossAxis], trailing[crossAxis]))); - } - } - endIndex = j; - lineHeight += crossDimLead; - - if (performLayout) { - for (j = startIndex; j < endIndex; ++j) { - child = node.getChildAt(j); - if (child.style.positionType != CSSPositionType.Relative) { - continue; - } - - CSSAlign alignContentAlignItem = getAlignItem(node, child); - if (alignContentAlignItem == CSSAlign.FlexStart) { - child.layout.position[pos[crossAxis]] = currentLead + child.style.margin.getWithFallback(leadingSpacing[crossAxis], leading[crossAxis]); - } else if (alignContentAlignItem == CSSAlign.FlexEnd) { - child.layout.position[pos[crossAxis]] = currentLead + lineHeight - child.style.margin.getWithFallback(trailingSpacing[crossAxis], trailing[crossAxis]) - child.layout.measuredDimensions[dim[crossAxis]]; - } else if (alignContentAlignItem == CSSAlign.Center) { - childHeight = child.layout.measuredDimensions[dim[crossAxis]]; - child.layout.position[pos[crossAxis]] = currentLead + (lineHeight - childHeight) / 2; - } else if (alignContentAlignItem == CSSAlign.Stretch) { - child.layout.position[pos[crossAxis]] = currentLead + child.style.margin.getWithFallback(leadingSpacing[crossAxis], leading[crossAxis]); - // TODO(prenaux): Correctly set the height of items with indefinite - // (auto) crossAxis dimension. - } - } - } - - currentLead += lineHeight; - } - } - - // STEP 9: COMPUTING FINAL DIMENSIONS - node.layout.measuredDimensions[DIMENSION_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, availableWidth - marginAxisRow); - node.layout.measuredDimensions[DIMENSION_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, availableHeight - marginAxisColumn); - - // If the user didn't specify a width or height for the node, set the - // dimensions based on the children. - if (measureModeMainDim == CSSMeasureMode.Undefined) { - // Clamp the size to the min/max size, if specified, and make sure it - // doesn't go below the padding and border amount. - node.layout.measuredDimensions[dim[mainAxis]] = boundAxis(node, mainAxis, maxLineMainDim); - } else if (measureModeMainDim == CSSMeasureMode.AtMost) { - node.layout.measuredDimensions[dim[mainAxis]] = Math.Max( - Math.Min(availableInnerMainDim + paddingAndBorderAxisMain, - boundAxisWithinMinAndMax(node, mainAxis, maxLineMainDim)), - paddingAndBorderAxisMain); - } - - if (measureModeCrossDim == CSSMeasureMode.Undefined) { - // Clamp the size to the min/max size, if specified, and make sure it - // doesn't go below the padding and border amount. - node.layout.measuredDimensions[dim[crossAxis]] = boundAxis(node, crossAxis, totalLineCrossDim + paddingAndBorderAxisCross); - } else if (measureModeCrossDim == CSSMeasureMode.AtMost) { - node.layout.measuredDimensions[dim[crossAxis]] = Math.Max( - Math.Min(availableInnerCrossDim + paddingAndBorderAxisCross, - boundAxisWithinMinAndMax(node, crossAxis, totalLineCrossDim + paddingAndBorderAxisCross)), - paddingAndBorderAxisCross); - } - - // STEP 10: SETTING TRAILING POSITIONS FOR CHILDREN - if (performLayout) { - boolean needsMainTrailingPos = false; - boolean needsCrossTrailingPos = false; - - if (mainAxis == CSS_FLEX_DIRECTION_ROW_REVERSE || - mainAxis == CSS_FLEX_DIRECTION_COLUMN_REVERSE) { - needsMainTrailingPos = true; - } - - if (crossAxis == CSS_FLEX_DIRECTION_ROW_REVERSE || - crossAxis == CSS_FLEX_DIRECTION_COLUMN_REVERSE) { - needsCrossTrailingPos = true; - } - - // Set trailing position if necessary. - if (needsMainTrailingPos || needsCrossTrailingPos) { - for (i = 0; i < childCount; ++i) { - child = node.getChildAt(i); - - if (needsMainTrailingPos) { - child.layout.position[trailing[mainAxis]] = node.layout.measuredDimensions[dim[mainAxis]] - (child.style.positionType == CSSPositionType.Absolute ? 0 : child.layout.measuredDimensions[dim[mainAxis]]) - child.layout.position[pos[mainAxis]]; - } - - if (needsCrossTrailingPos) { - child.layout.position[trailing[crossAxis]] = node.layout.measuredDimensions[dim[crossAxis]] - (child.style.positionType == CSSPositionType.Absolute ? 0 : child.layout.measuredDimensions[dim[crossAxis]]) - child.layout.position[pos[crossAxis]]; - } - } - } - } - - // STEP 11: SIZING AND POSITIONING ABSOLUTE CHILDREN - currentAbsoluteChild = firstAbsoluteChild; - while (currentAbsoluteChild != null) { - // Now that we know the bounds of the container, perform layout again on the - // absolutely-positioned children. - if (performLayout) { - - childWidth = CSSConstants.Undefined; - childHeight = CSSConstants.Undefined; - - if ((currentAbsoluteChild.style.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] >= 0.0)) { - childWidth = currentAbsoluteChild.style.dimensions[DIMENSION_WIDTH] + (currentAbsoluteChild.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_ROW], leading[CSS_FLEX_DIRECTION_ROW]) + currentAbsoluteChild.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_ROW], trailing[CSS_FLEX_DIRECTION_ROW])); - } else { - // If the child doesn't have a specified width, compute the width based on the left/right offsets if they're defined. - if (!float.IsNaN(currentAbsoluteChild.style.position[POSITION_LEFT]) && !float.IsNaN(currentAbsoluteChild.style.position[POSITION_RIGHT])) { - childWidth = node.layout.measuredDimensions[DIMENSION_WIDTH] - - (node.style.border.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_ROW], leading[CSS_FLEX_DIRECTION_ROW]) + node.style.border.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_ROW], trailing[CSS_FLEX_DIRECTION_ROW])) - - (currentAbsoluteChild.style.position[POSITION_LEFT] + currentAbsoluteChild.style.position[POSITION_RIGHT]); - childWidth = boundAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_ROW, childWidth); - } - } - - if ((currentAbsoluteChild.style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] >= 0.0)) { - childHeight = currentAbsoluteChild.style.dimensions[DIMENSION_HEIGHT] + (currentAbsoluteChild.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + currentAbsoluteChild.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN])); - } else { - // If the child doesn't have a specified height, compute the height based on the top/bottom offsets if they're defined. - if (!float.IsNaN(currentAbsoluteChild.style.position[POSITION_TOP]) && !float.IsNaN(currentAbsoluteChild.style.position[POSITION_BOTTOM])) { - childHeight = node.layout.measuredDimensions[DIMENSION_HEIGHT] - - (node.style.border.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + node.style.border.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN])) - - (currentAbsoluteChild.style.position[POSITION_TOP] + currentAbsoluteChild.style.position[POSITION_BOTTOM]); - childHeight = boundAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_COLUMN, childHeight); - } - } - - // If we're still missing one or the other dimension, measure the content. - if (float.IsNaN(childWidth) || float.IsNaN(childHeight)) { - childWidthMeasureMode = float.IsNaN(childWidth) ? CSSMeasureMode.Undefined : CSSMeasureMode.Exactly; - childHeightMeasureMode = float.IsNaN(childHeight) ? CSSMeasureMode.Undefined : CSSMeasureMode.Exactly; - - // According to the spec, if the main size is not definite and the - // child's inline axis is parallel to the main axis (i.e. it's - // horizontal), the child should be sized using "UNDEFINED" in - // the main size. Otherwise use "AT_MOST" in the cross axis. - if (!isMainAxisRow && float.IsNaN(childWidth) && !float.IsNaN(availableInnerWidth)) { - childWidth = availableInnerWidth; - childWidthMeasureMode = CSSMeasureMode.AtMost; - } - - // The W3C spec doesn't say anything about the 'overflow' property, - // but all major browsers appear to implement the following logic. - if (node.style.overflow == CSSOverflow.Hidden) { - if (isMainAxisRow && float.IsNaN(childHeight) && !float.IsNaN(availableInnerHeight)) { - childHeight = availableInnerHeight; - childHeightMeasureMode = CSSMeasureMode.AtMost; - } - } - - layoutNodeInternal(layoutContext, currentAbsoluteChild, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, false, "abs-measure"); - childWidth = currentAbsoluteChild.layout.measuredDimensions[DIMENSION_WIDTH] + (currentAbsoluteChild.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_ROW], leading[CSS_FLEX_DIRECTION_ROW]) + currentAbsoluteChild.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_ROW], trailing[CSS_FLEX_DIRECTION_ROW])); - childHeight = currentAbsoluteChild.layout.measuredDimensions[DIMENSION_HEIGHT] + (currentAbsoluteChild.style.margin.getWithFallback(leadingSpacing[CSS_FLEX_DIRECTION_COLUMN], leading[CSS_FLEX_DIRECTION_COLUMN]) + currentAbsoluteChild.style.margin.getWithFallback(trailingSpacing[CSS_FLEX_DIRECTION_COLUMN], trailing[CSS_FLEX_DIRECTION_COLUMN])); - } - - layoutNodeInternal(layoutContext, currentAbsoluteChild, childWidth, childHeight, direction, CSSMeasureMode.Exactly, CSSMeasureMode.Exactly, true, "abs-layout"); - - if (!float.IsNaN(currentAbsoluteChild.style.position[trailing[CSS_FLEX_DIRECTION_ROW]]) && - !!float.IsNaN(currentAbsoluteChild.style.position[leading[CSS_FLEX_DIRECTION_ROW]])) { - currentAbsoluteChild.layout.position[leading[CSS_FLEX_DIRECTION_ROW]] = - node.layout.measuredDimensions[dim[CSS_FLEX_DIRECTION_ROW]] - - currentAbsoluteChild.layout.measuredDimensions[dim[CSS_FLEX_DIRECTION_ROW]] - - (float.IsNaN(currentAbsoluteChild.style.position[trailing[CSS_FLEX_DIRECTION_ROW]]) ? 0 : currentAbsoluteChild.style.position[trailing[CSS_FLEX_DIRECTION_ROW]]); - } - - if (!float.IsNaN(currentAbsoluteChild.style.position[trailing[CSS_FLEX_DIRECTION_COLUMN]]) && - !!float.IsNaN(currentAbsoluteChild.style.position[leading[CSS_FLEX_DIRECTION_COLUMN]])) { - currentAbsoluteChild.layout.position[leading[CSS_FLEX_DIRECTION_COLUMN]] = - node.layout.measuredDimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] - - currentAbsoluteChild.layout.measuredDimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] - - (float.IsNaN(currentAbsoluteChild.style.position[trailing[CSS_FLEX_DIRECTION_COLUMN]]) ? 0 : currentAbsoluteChild.style.position[trailing[CSS_FLEX_DIRECTION_COLUMN]]); - } - } - - currentAbsoluteChild = currentAbsoluteChild.nextChild; - } - /** END_GENERATED **/ - } - } -} diff --git a/java/csharp/Facebook.CSSLayout/MeasureOutput.cs b/java/csharp/Facebook.CSSLayout/MeasureOutput.cs deleted file mode 100644 index 4462cd75..00000000 --- a/java/csharp/Facebook.CSSLayout/MeasureOutput.cs +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -namespace Facebook.CSSLayout -{ - /** - * POJO to hold the output of the measure function. - */ - public struct MeasureOutput - { - public MeasureOutput(float width, float height) - { - Width = width; - Height = height; - } - - public readonly float Width; - public readonly float Height; - - internal float width - { - get { return Width; } - } - - internal float height - { - get { return Height; } - } - } -} diff --git a/java/csharp/Facebook.CSSLayout/NullableAttribute.cs b/java/csharp/Facebook.CSSLayout/NullableAttribute.cs deleted file mode 100755 index ff05adfc..00000000 --- a/java/csharp/Facebook.CSSLayout/NullableAttribute.cs +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -using System; - -namespace Facebook.CSSLayout -{ - /** - * This is here to preserve the @nullable attribute of the original Java API. - */ - - [AttributeUsage(AttributeTargets.Field | AttributeTargets.ReturnValue | AttributeTargets.Parameter)] - sealed class NullableAttribute : Attribute - { - } -} diff --git a/java/csharp/Facebook.CSSLayout/Properties/AssemblyInfo.cs b/java/csharp/Facebook.CSSLayout/Properties/AssemblyInfo.cs deleted file mode 100755 index 145f8b05..00000000 --- a/java/csharp/Facebook.CSSLayout/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -using System.Resources; -using System.Reflection; -using System.Runtime.CompilerServices; - -[assembly: AssemblyTitle("Facebook.CSSLayout")] -[assembly: AssemblyDescription("A subset of CSS's flexbox layout algorithm and box model.")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Facebook")] -[assembly: AssemblyProduct("Facebook.CSSLayout")] -[assembly: AssemblyCopyright("Copyright © 2015 Facebook")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] -[assembly: NeutralResourcesLanguage("en")] - -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] - -[assembly: InternalsVisibleTo("Facebook.CSSLayout.Tests")] diff --git a/java/csharp/Facebook.CSSLayout/Spacing.cs b/java/csharp/Facebook.CSSLayout/Spacing.cs deleted file mode 100644 index 8c718e25..00000000 --- a/java/csharp/Facebook.CSSLayout/Spacing.cs +++ /dev/null @@ -1,234 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -namespace Facebook.CSSLayout -{ - /** - * Class representing CSS spacing (padding, margin, and borders). This is mostly necessary to - * properly implement interactions and updates for properties like margin, marginLeft, and - * marginHorizontal. - */ - - sealed class Spacing - { - /** - * Spacing type that represents the left direction. E.g. {@code marginLeft}. - */ - internal const int LEFT = (int)CSSSpacingType.Left; - /** - * Spacing type that represents the top direction. E.g. {@code marginTop}. - */ - internal const int TOP = (int)CSSSpacingType.Top; - /** - * Spacing type that represents the right direction. E.g. {@code marginRight}. - */ - internal const int RIGHT = (int)CSSSpacingType.Right; - /** - * Spacing type that represents the bottom direction. E.g. {@code marginBottom}. - */ - internal const int BOTTOM = (int)CSSSpacingType.Bottom; - /** - * Spacing type that represents vertical direction (top and bottom). E.g. {@code marginVertical}. - */ - internal const int VERTICAL = (int)CSSSpacingType.Vertical; - /** - * Spacing type that represents horizontal direction (left and right). E.g. - * {@code marginHorizontal}. - */ - internal const int HORIZONTAL = (int)CSSSpacingType.Horizontal; - /** - * Spacing type that represents start direction e.g. left in left-to-right, right in right-to-left. - */ - internal const int START = (int)CSSSpacingType.Start; - /** - * Spacing type that represents end direction e.g. right in left-to-right, left in right-to-left. - */ - internal const int END = (int)CSSSpacingType.End; - /** - * Spacing type that represents all directions (left, top, right, bottom). E.g. {@code margin}. - */ - internal const int ALL = (int)CSSSpacingType.All; - - static readonly int[] sFlagsMap = { - 1, /*LEFT*/ - 2, /*TOP*/ - 4, /*RIGHT*/ - 8, /*BOTTOM*/ - 16, /*VERTICAL*/ - 32, /*HORIZONTAL*/ - 64, /*START*/ - 128, /*END*/ - 256 /*ALL*/ - }; - - float[] mSpacing = newFullSpacingArray(); - [Nullable] float[] mDefaultSpacing = null; - int mValueFlags = 0; - bool mHasAliasesSet; - - /** - * Set a spacing value. - * - * @param spacingType one of {@link #LEFT}, {@link #TOP}, {@link #RIGHT}, {@link #BOTTOM}, - * {@link #VERTICAL}, {@link #HORIZONTAL}, {@link #ALL} - * @param value the value for this direction - * @return {@code true} if the spacing has changed, or {@code false} if the same value was already - * set - */ - - internal bool set(int spacingType, float value) - { - if (!FloatUtil.floatsEqual(mSpacing[spacingType], value)) - { - mSpacing[spacingType] = value; - - if (CSSConstants.IsUndefined(value)) - { - mValueFlags &= ~sFlagsMap[spacingType]; - } - else - { - mValueFlags |= sFlagsMap[spacingType]; - } - - mHasAliasesSet = - (mValueFlags & sFlagsMap[ALL]) != 0 || - (mValueFlags & sFlagsMap[VERTICAL]) != 0 || - (mValueFlags & sFlagsMap[HORIZONTAL]) != 0; - - return true; - } - return false; - } - - /** - * Set a default spacing value. This is used as a fallback when no spacing has been set for a - * particular direction. - * - * @param spacingType one of {@link #LEFT}, {@link #TOP}, {@link #RIGHT}, {@link #BOTTOM} - * @param value the default value for this direction - * @return - */ - - internal bool setDefault(int spacingType, float value) - { - if (mDefaultSpacing == null) - mDefaultSpacing = newSpacingResultArray(); - - if (!FloatUtil.floatsEqual(mDefaultSpacing[spacingType], value)) - { - mDefaultSpacing[spacingType] = value; - return true; - } - return false; - } - - /** - * Get the spacing for a direction. This takes into account any default values that have been set. - * - * @param spacingType one of {@link #LEFT}, {@link #TOP}, {@link #RIGHT}, {@link #BOTTOM} - */ - - internal float get(int spacingType) - { - float defaultValue = - (mDefaultSpacing != null) - ? mDefaultSpacing[spacingType] - : (spacingType == START || spacingType == END ? CSSConstants.Undefined : 0); - - if (mValueFlags == 0) - { - return defaultValue; - } - - if ((mValueFlags & sFlagsMap[spacingType]) != 0) - { - return mSpacing[spacingType]; - } - - if (mHasAliasesSet) - { - int secondType = spacingType == TOP || spacingType == BOTTOM ? VERTICAL : HORIZONTAL; - if ((mValueFlags & sFlagsMap[secondType]) != 0) - { - return mSpacing[secondType]; - } - else if ((mValueFlags & sFlagsMap[ALL]) != 0) - { - return mSpacing[ALL]; - } - } - - return defaultValue; - } - - /** - * Get the raw value (that was set using {@link #set(int, float)}), without taking into account - * any default values. - * - * @param spacingType one of {@link #LEFT}, {@link #TOP}, {@link #RIGHT}, {@link #BOTTOM}, - * {@link #VERTICAL}, {@link #HORIZONTAL}, {@link #ALL} - */ - - internal float getRaw(int spacingType) - { - return mSpacing[spacingType]; - } - - /** - * Try to get start value and fallback to given type if not defined. This is used privately - * by the layout engine as a more efficient way to fetch direction-aware values by - * avoid extra method invocations. - */ - internal float getWithFallback(int spacingType, int fallbackType) - { - return - (mValueFlags & sFlagsMap[spacingType]) != 0 - ? mSpacing[spacingType] - : get(fallbackType); - } - - static float[] newFullSpacingArray() - { - return new[] - { - CSSConstants.Undefined, - CSSConstants.Undefined, - CSSConstants.Undefined, - CSSConstants.Undefined, - CSSConstants.Undefined, - CSSConstants.Undefined, - CSSConstants.Undefined, - CSSConstants.Undefined, - CSSConstants.Undefined - }; - } - - static float[] newSpacingResultArray() - { - return newSpacingResultArray(0); - } - - static float[] newSpacingResultArray(float defaultValue) - { - return new[] - { - defaultValue, - defaultValue, - defaultValue, - defaultValue, - defaultValue, - defaultValue, - CSSConstants.Undefined, - CSSConstants.Undefined, - defaultValue - }; - } - } -} diff --git a/java/csharp/Makefile b/java/csharp/Makefile deleted file mode 100644 index 3bc1dc47..00000000 --- a/java/csharp/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -MSB=msbuild.exe /m /verbosity:m /nologo -NUGET=nuget.exe -NUNITC=nunit-console.exe - -VER=1.0.0 -NAME=Facebook.CSSLayout - -.PHONY: all -all: test - -.PHONY: distribute -distribute: package release-package - -.PHONY: package -package: conf=Release -package: build - cd ${NAME} && ${NUGET} pack ${NAME}.csproj -Version ${VER} -Prop Configuration=${conf} - -.PHONY: release-package -release-package: - cd ${NAME} && nuget push ${NAME}.${VER}.nupkg - -.PHONY: test -test: build-debug - cd ${NAME}.Tests/bin/Debug && ${NUNITC} Facebook.CSSLayout.Tests.dll - -.PHONY: build-debug -build-debug: conf=Debug -build-debug: build - -.PHONY: build-release -build-release: conf=Release -build-release: build - -.PHONY: build -build: - ${MSB} ${NAME}.sln /p:Configuration=${conf} /t:"Facebook_CSSLayout:Rebuild;Facebook_CSSLayout_Tests:Rebuild" diff --git a/java/css-layout.js b/java/css-layout.js deleted file mode 100644 index 95283509..00000000 --- a/java/css-layout.js +++ /dev/null @@ -1,29 +0,0 @@ -// UMD (Universal Module Definition) -// See https://github.com/umdjs/umd for reference -// -// This file uses the following specific UMD implementation: -// https://github.com/umdjs/umd/blob/master/templates/returnExports.js -(function(root, factory) { - if (typeof define === 'function' && define.amd) { - // AMD. Register as an anonymous module. - define([], factory); - } else if (typeof exports === 'object') { - // Node. Does not work with strict CommonJS, but - // only CommonJS-like environments that support module.exports, - // like Node. - module.exports = factory(); - } else { - // Browser globals (root is window) - root.computeLayout = factory(); - } -}(this, function() { - // @@include('./Layout.js') - - return function(node) { - /*eslint-disable */ - // disabling ESLint because this code relies on the above include - computeLayout.fillNodes(node); - computeLayout.computeLayout(node); - /*eslint-enable */ - }; -})); diff --git a/java/java/.idea/.name b/java/java/.idea/.name deleted file mode 100644 index 4cc7a509..00000000 --- a/java/java/.idea/.name +++ /dev/null @@ -1 +0,0 @@ -css-layout \ No newline at end of file diff --git a/java/java/.idea/compiler.xml b/java/java/.idea/compiler.xml deleted file mode 100644 index 217af471..00000000 --- a/java/java/.idea/compiler.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - diff --git a/java/java/.idea/copyright/profiles_settings.xml b/java/java/.idea/copyright/profiles_settings.xml deleted file mode 100644 index 3572571a..00000000 --- a/java/java/.idea/copyright/profiles_settings.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/java/java/.idea/encodings.xml b/java/java/.idea/encodings.xml deleted file mode 100644 index e206d70d..00000000 --- a/java/java/.idea/encodings.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/java/java/.idea/misc.xml b/java/java/.idea/misc.xml deleted file mode 100644 index 97320410..00000000 --- a/java/java/.idea/misc.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/java/java/.idea/modules.xml b/java/java/.idea/modules.xml deleted file mode 100644 index 8123b62d..00000000 --- a/java/java/.idea/modules.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/java/java/.idea/scopes/scope_settings.xml b/java/java/.idea/scopes/scope_settings.xml deleted file mode 100644 index 922003b8..00000000 --- a/java/java/.idea/scopes/scope_settings.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/java/java/.idea/uiDesigner.xml b/java/java/.idea/uiDesigner.xml deleted file mode 100644 index 3b000203..00000000 --- a/java/java/.idea/uiDesigner.xml +++ /dev/null @@ -1,125 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/java/java/.idea/vcs.xml b/java/java/.idea/vcs.xml deleted file mode 100644 index def6a6a1..00000000 --- a/java/java/.idea/vcs.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/java/java/java.iml b/java/java/java.iml deleted file mode 100644 index 22ef4acb..00000000 --- a/java/java/java.iml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/java/transpile.js b/java/transpile.js deleted file mode 100644 index 8d3fa24d..00000000 --- a/java/transpile.js +++ /dev/null @@ -1,349 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -var layoutTestUtils = require('./Layout-test-utils.js'); -var computeLayout = require('./Layout.js').layoutNodeImpl; -var fs = require('fs'); -var JavaTranspiler = require('./JavaTranspiler.js'); -var CSharpTranspiler = require('./CSharpTranspiler.js'); - -var currentTest = ''; -var allTests = []; -var computeDOMLayout = layoutTestUtils.computeDOMLayout; -var reduceTest = layoutTestUtils.reduceTest; -global.layoutTestUtils = { - testLayout: function(node, expectedLayout) { - allTests.push({name: currentTest, node: node, expectedLayout: expectedLayout}); - }, - testLayoutAgainstDomOnly: function() { - }, - testRandomLayout: function(node, i) { - allTests.push({name: 'Random #' + i, node: node, expectedLayout: computeDOMLayout(node)}); - }, - testLayoutAgainstExpectedOnly: function(node, expectedLayout) { - allTests.push({name: currentTest, node: node, expectedLayout: expectedLayout}); - }, - computeLayout: layoutTestUtils.computeLayout, - reduceTest: reduceTest, - text: layoutTestUtils.text, - texts: layoutTestUtils.texts, - textSizes: layoutTestUtils.textSizes, - measureWithRatio2: layoutTestUtils.measureWithRatio2, - measureWithMatchParent: layoutTestUtils.measureWithMatchParent -}; - -global.describe = function(name, cb) { - if (name.toLowerCase().indexOf('javascript only') === -1) { - cb(); - } -}; -global.it = function(name, cb) { currentTest = name; cb(); }; -global.xit = function() { /* ignore skipped tests */ }; - -require('./__tests__/Layout-test.js'); - - -function printLayout(test) { - var level = 1; - var res = []; - - function indent(level) { - var result = ''; - for (var i = 0; i < level; ++i) { - result += ' '; - } - return result; - } - - function add(str) { - if (str.length > 0) { - str = indent(level) + str; - } - res.push(str); - } - - function isEmpty(obj) { - return !Object.keys(obj).length; - } - - add('{'); - level++; - - // Output the style node - add('css_node_t *root_node = new_test_css_node();'); - add('{'); - level++; - if (!isEmpty(test.node.style) || test.node.children && test.node.children.length) { - add('css_node_t *node_0 = root_node;'); - } - function recStyle(node) { - - function addStyle(str) { - add('node_' + (level - 3) + '->style.' + str); - } - - function addEnum(node, jsKey, cKey, dict) { - if (jsKey in node.style) { - addStyle(cKey + ' = ' + dict[node.style[jsKey]] + ';'); - } - } - - function addFloat(node, jsKey, cKey) { - if (jsKey in node.style) { - addStyle(cKey + ' = ' + node.style[jsKey] + ';'); - } - } - - function addSpacing(node, spacing, suffix) { - addFloat(node, spacing + suffix, spacing + '[CSS_LEFT]'); - addFloat(node, spacing + suffix, spacing + '[CSS_TOP]'); - addFloat(node, spacing + suffix, spacing + '[CSS_RIGHT]'); - addFloat(node, spacing + suffix, spacing + '[CSS_BOTTOM]'); - addFloat(node, spacing + suffix, spacing + '[CSS_START]'); - addFloat(node, spacing + suffix, spacing + '[CSS_END]'); - - addFloat(node, spacing + 'Left' + suffix, spacing + '[CSS_LEFT]'); - addFloat(node, spacing + 'Top' + suffix, spacing + '[CSS_TOP]'); - addFloat(node, spacing + 'Right' + suffix, spacing + '[CSS_RIGHT]'); - addFloat(node, spacing + 'Bottom' + suffix, spacing + '[CSS_BOTTOM]'); - addFloat(node, spacing + 'Start' + suffix, spacing + '[CSS_START]'); - addFloat(node, spacing + 'End' + suffix, spacing + '[CSS_END]'); - } - - function addMeasure(node) { - if ('measure' in node.style) { - if (node.children && node.children.length) { - throw new Error('Using custom measure function is supported only for leaf nodes.'); - } - add('node_' + (level - 3) + '->measure = measure;'); - add('node_' + (level - 3) + '->context = "' + node.style.measure.toString() + '";'); - } - } - - addEnum(node, 'direction', 'direction', { - 'ltr': 'CSS_DIRECTION_LTR', - 'rtl': 'CSS_DIRECTION_RTL' - }); - addEnum(node, 'flexDirection', 'flex_direction', { - 'row': 'CSS_FLEX_DIRECTION_ROW', - 'row-reverse': 'CSS_FLEX_DIRECTION_ROW_REVERSE', - 'column': 'CSS_FLEX_DIRECTION_COLUMN', - 'column-reverse': 'CSS_FLEX_DIRECTION_COLUMN_REVERSE' - }); - addEnum(node, 'justifyContent', 'justify_content', { - 'flex-start': 'CSS_JUSTIFY_FLEX_START', - 'center': 'CSS_JUSTIFY_CENTER', - 'flex-end': 'CSS_JUSTIFY_FLEX_END', - 'space-between': 'CSS_JUSTIFY_SPACE_BETWEEN', - 'space-around': 'CSS_JUSTIFY_SPACE_AROUND' - }); - addEnum(node, 'alignContent', 'align_content', { - 'flex-start': 'CSS_ALIGN_FLEX_START', - 'center': 'CSS_ALIGN_CENTER', - 'flex-end': 'CSS_ALIGN_FLEX_END', - 'stretch': 'CSS_ALIGN_STRETCH' - }); - addEnum(node, 'alignItems', 'align_items', { - 'flex-start': 'CSS_ALIGN_FLEX_START', - 'center': 'CSS_ALIGN_CENTER', - 'flex-end': 'CSS_ALIGN_FLEX_END', - 'stretch': 'CSS_ALIGN_STRETCH' - }); - addEnum(node, 'alignSelf', 'align_self', { - 'flex-start': 'CSS_ALIGN_FLEX_START', - 'center': 'CSS_ALIGN_CENTER', - 'flex-end': 'CSS_ALIGN_FLEX_END', - 'stretch': 'CSS_ALIGN_STRETCH' - }); - addEnum(node, 'position', 'position_type', { - 'relative': 'CSS_POSITION_RELATIVE', - 'absolute': 'CSS_POSITION_ABSOLUTE' - }); - addEnum(node, 'flexWrap', 'flex_wrap', { - 'nowrap': 'CSS_NOWRAP', - 'wrap': 'CSS_WRAP' - }); - addEnum(node, 'measureMode', 'measure_mode', { - 'undefined': 'CSS_MEASURE_MODE_UNDEFINED', - 'exactly': 'CSS_MEASURE_MODE_EXACTLY', - 'at-most': 'CSS_MEASURE_MODE_AT_MOST' - }); - addEnum(node, 'overflow', 'overflow', { - 'visible': 'CSS_OVERFLOW_VISIBLE', - 'hidden': 'CSS_OVERFLOW_HIDDEN' - }); - addFloat(node, 'flex', 'flex'); - addFloat(node, 'width', 'dimensions[CSS_WIDTH]'); - addFloat(node, 'height', 'dimensions[CSS_HEIGHT]'); - addFloat(node, 'maxWidth', 'maxDimensions[CSS_WIDTH]'); - addFloat(node, 'maxHeight', 'maxDimensions[CSS_HEIGHT]'); - addFloat(node, 'minWidth', 'minDimensions[CSS_WIDTH]'); - addFloat(node, 'minHeight', 'minDimensions[CSS_HEIGHT]'); - addSpacing(node, 'margin', ''); - addSpacing(node, 'padding', ''); - addSpacing(node, 'border', 'Width'); - addFloat(node, 'left', 'position[CSS_LEFT]'); - addFloat(node, 'top', 'position[CSS_TOP]'); - addFloat(node, 'right', 'position[CSS_RIGHT]'); - addFloat(node, 'bottom', 'position[CSS_BOTTOM]'); - addMeasure(node); - - if (node.children) { - add('init_css_node_children(node_' + (level - 3) + ', ' + node.children.length + ');'); - add('{'); - level++; - add('css_node_t *node_' + (level - 3) + ';'); - - for (var i = 0; i < node.children.length; ++i) { - add('node_' + (level - 3) + ' = node_' + (level - 4) + '->get_child(node_' + (level - 4) + '->context, ' + i + ');'); - recStyle(node.children[i]); - } - - level--; - add('}'); - } - } - recStyle(test.node); - level--; - add('}'); - add(''); - - // Output the expected layout node - add('css_node_t *root_layout = new_test_css_node();'); - add('{'); - level++; - add('css_node_t *node_0 = root_layout;'); - - function recLayout(node) { - function addLayout(str) { - add('node_' + (level - 3) + '->layout.' + str); - } - - addLayout('position[CSS_TOP] = ' + node.top + ';'); - addLayout('position[CSS_LEFT] = ' + node.left + ';'); - addLayout('dimensions[CSS_WIDTH] = ' + node.width + ';'); - addLayout('dimensions[CSS_HEIGHT] = ' + node.height + ';'); - - if (node.children) { - add('init_css_node_children(node_' + (level - 3) + ', ' + node.children.length + ');'); - add('{'); - level++; - add('css_node_t *node_' + (level - 3) + ';'); - - for (var i = 0; i < node.children.length; ++i) { - add('node_' + (level - 3) + ' = node_' + (level - 4) + '->get_child(node_' + (level - 4) + '->context, ' + i + ');'); - recLayout(node.children[i]); - } - - level--; - add('}'); - } - } - recLayout(test.expectedLayout); - level--; - add('}'); - add(''); - - // Do the test - add('test("' + test.name.replace(/"/g, '\\"') + '", root_node, root_layout);'); - level--; - add('}'); - return res.join('\n'); -} - -function transpileAnnotatedJStoC(jsCode) { - return jsCode - .replace(/'abs-layout'/g, '"abs-layout"') - .replace(/'abs-measure'/g, '"abs-measure"') - .replace(/'flex'/g, '"flex"') - .replace(/'measure'/g, '"measure"') - .replace(/'stretch'/g, '"stretch"') - .replace('node.style.measure', 'node.measure') - .replace(/undefined/g, 'NULL') - .replace(/\.children\.length/g, '.children_count') - .replace(/\.width/g, '.dimensions[CSS_WIDTH]') - .replace(/\.height/g, '.dimensions[CSS_HEIGHT]') - .replace(/\.maxWidth/g, '.maxDimensions[CSS_WIDTH]') - .replace(/\.maxHeight/g, '.maxDimensions[CSS_HEIGHT]') - .replace(/\.minWidth/g, '.minDimensions[CSS_WIDTH]') - .replace(/\.minHeight/g, '.minDimensions[CSS_HEIGHT]') - .replace(/\.lineIndex/g, '.line_index') - .replace(/\.nextChild/g, '.next_child') - .replace(/\.flexBasis/g, '.flex_basis') - .replace(/layout\[pos/g, 'layout.position[pos') - .replace(/layout\[leading/g, 'layout.position[leading') - .replace(/layout\[trailing/g, 'layout.position[trailing') - .replace(/layout\[measuredDim/g, 'layout.measured_dimensions[dim') - .replace(/layout\.measuredWidth/g, 'layout.measured_dimensions[CSS_WIDTH]') - .replace(/layout\.measuredHeight/g, 'layout.measured_dimensions[CSS_HEIGHT]') - .replace(/style\[dim/g, 'style.dimensions[dim') - .replace(/style\[CSS_LEFT/g, 'style.position[CSS_LEFT') - .replace(/style\[CSS_TOP/g, 'style.position[CSS_TOP') - .replace(/style\[CSS_RIGHT/g, 'style.position[CSS_RIGHT') - .replace(/style\[CSS_BOTTOM/g, 'style.position[CSS_BOTTOM') - .replace(/node.children\[i\]/g, 'node->get_child(node->context, i)') - .replace(/node.children\[j\]/g, 'node->get_child(node->context, j)') - .replace(/node\./g, 'node->') - .replace(/child\./g, 'child->') - .replace(/currentAbsoluteChild\./g, 'currentAbsoluteChild->') - .replace(/currentRelativeChild\./g, 'currentRelativeChild->') - .replace(/getPositionType\((.+?)\)/g, '$1->style.position_type') - .replace(/getJustifyContent\((.+?)\)/g, '$1->style.justify_content') - .replace(/getAlignContent\((.+?)\)/g, '$1->style.align_content') - .replace(/assert\((.+?),\s*'(.+?)'\);/g, 'assert($1); // $2') - .replace(/getOverflow\((.+?)\)/g, '$1->style.overflow') - .replace(/var\/\*\(c\)!([^*]+)\*\//g, '$1') - .replace(/var\/\*([^\/]+)\*\//g, '$1') - .replace(/ === /g, ' == ') - .replace(/ !== /g, ' != ') - .replace(/\n {2}/g, '\n') - .replace(/\/\*\(c\)!([^*]+)\*\//g, '$1') - .replace(/\/[*]!([^*]+)[*]\//g, '$1') - .replace(/\/\*\(java\)!([^*]+)\*\//g, ''); -} - -function makeConstDefs() { - var lines = [ - '#define SMALL_WIDTH ' + layoutTestUtils.textSizes.smallWidth, - '#define SMALL_HEIGHT ' + layoutTestUtils.textSizes.smallHeight, - '#define BIG_WIDTH ' + layoutTestUtils.textSizes.bigWidth, - '#define BIG_HEIGHT ' + layoutTestUtils.textSizes.bigHeight, - '#define BIG_MIN_WIDTH ' + layoutTestUtils.textSizes.bigMinWidth, - '#define SMALL_TEXT "' + layoutTestUtils.texts.small + '"', - '#define LONG_TEXT "' + layoutTestUtils.texts.big + '"', - '#define MEASURE_WITH_RATIO_2 "' + layoutTestUtils.measureWithRatio2() + '"', - '#define MEASURE_WITH_MATCH_PARENT "' + layoutTestUtils.measureWithMatchParent() + '"' - ]; - return lines.join('\n'); -} - -function generateFile(fileName, generatedContent) { - var content = fs.readFileSync(fileName, 'utf8').toString(); - content = content.replace(new RegExp( - /\/\*\* START_GENERATED \*\*\/[\s\S]*\/\*\* END_GENERATED \*\*\// - ), '/** START_GENERATED **/\n' + generatedContent + '\n /** END_GENERATED **/'); - - fs.writeFileSync(fileName, content); -} - -// Extract the function body by trimming the first ('function layoutNode(...) {') and -// last ('}') lines. Also, start the function body with a blank line so that regexes -// that use \n to match the start of a line will match the actual first line. -var computeLayoutCode = [''].concat(computeLayout.toString().split('\n').slice(1, -1)).join('\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(computeLayoutCode)); -generateFile(__dirname + '/java/src/com/facebook/csslayout/LayoutEngine.java', JavaTranspiler.transpileLayoutEngine(computeLayoutCode)); -generateFile(__dirname + '/java/tests/com/facebook/csslayout/TestConstants.java', JavaTranspiler.transpileCConstDefs(makeConstDefs())); -generateFile(__dirname + '/java/tests/com/facebook/csslayout/LayoutEngineTest.java', JavaTranspiler.transpileCTestsArray(allTestsInC)); -generateFile(__dirname + '/csharp/Facebook.CSSLayout/LayoutEngine.cs', CSharpTranspiler.transpileLayoutEngine(computeLayoutCode)); -generateFile(__dirname + '/csharp/Facebook.CSSLayout.Tests/TestConstants.cs', CSharpTranspiler.transpileCConstDefs(makeConstDefs())); -generateFile(__dirname + '/csharp/Facebook.CSSLayout.Tests/LayoutEngineTest.cs', CSharpTranspiler.transpileCTestsArray(allTestsInC)); diff --git a/lib/gtest/BUCK b/lib/gtest/BUCK new file mode 100644 index 00000000..9d94fa72 --- /dev/null +++ b/lib/gtest/BUCK @@ -0,0 +1,42 @@ +# Copyright (c) 2014-present, Facebook, Inc. +# All rights reserved. +# +# This source code is licensed under the BSD-style license found in the +# LICENSE file in the root directory of this source tree. An additional grant +# of patent rights can be found in the PATENTS file in the same directory. + +import os +import urllib2 +import zipfile + +include_defs('//CSSLAYOUT_DEFS') + +# Download gtest dep if it does not exists in path +current_dir = os.path.dirname(os.path.realpath(__file__)) +gtest_folder = 'googletest-release-1.7.0' +if GTEST_DL_URL != None and not os.path.isdir(current_dir + gtest_folder): + gtest = urllib2.urlopen('https://github.com/google/googletest/archive/release-1.7.0.zip').read() + with open("gtest.zip", 'w') as f: + f.write(gtest) + with zipfile.ZipFile('gtest.zip',"r") as zip: + zip.extractall(os.path.dirname(os.path.realpath(__file__))) + os.remove('gtest.zip') + +COMPILER_FLAGS = [ + '-std=c++11', + '-Wno-missing-prototypes', +] + +cxx_library( + name = 'gtest', + srcs = glob([gtest_folder + '/src/*.cc']), + exported_headers = subdir_glob([ + (gtest_folder + '/include', '**/*.h'), + (gtest_folder, 'src/*.h'), + (gtest_folder, 'src/*.cc'), + ]), + header_namespace = '', + compiler_flags = COMPILER_FLAGS, + deps = [], + visibility = [CSSLAYOUT_ROOT], +) diff --git a/lib/infer-annotations/BUCK b/lib/infer-annotations/BUCK new file mode 100644 index 00000000..313f9e5c --- /dev/null +++ b/lib/infer-annotations/BUCK @@ -0,0 +1,21 @@ +# Copyright (c) 2014-present, Facebook, Inc. +# All rights reserved. +# +# This source code is licensed under the BSD-style license found in the +# LICENSE file in the root directory of this source tree. An additional grant +# of patent rights can be found in the PATENTS file in the same directory. + +include_defs('//CSSLAYOUT_DEFS') + +prebuilt_jar( + name = 'infer-annotations-jar', + binary_jar = 'infer-annotations-1.4.jar', +) + +java_library( + name = 'infer-annotations', + exported_deps = [ + ':infer-annotations-jar', + ], + visibility = [CSSLAYOUT_ROOT], +) diff --git a/java/java/lib/infer-annotations-1.4.jar b/lib/infer-annotations/infer-annotations-1.4.jar similarity index 100% rename from java/java/lib/infer-annotations-1.4.jar rename to lib/infer-annotations/infer-annotations-1.4.jar diff --git a/lib/jsr-305/BUCK b/lib/jsr-305/BUCK new file mode 100644 index 00000000..c3f74727 --- /dev/null +++ b/lib/jsr-305/BUCK @@ -0,0 +1,21 @@ +# Copyright (c) 2014-present, Facebook, Inc. +# All rights reserved. +# +# This source code is licensed under the BSD-style license found in the +# LICENSE file in the root directory of this source tree. An additional grant +# of patent rights can be found in the PATENTS file in the same directory. + +include_defs('//CSSLAYOUT_DEFS') + +prebuilt_jar( + name = 'jsr305-jar', + binary_jar = 'jsr305.jar', +) + +java_library( + name = 'jsr-305', + exported_deps = [ + ':jsr305-jar', + ], + visibility = [CSSLAYOUT_ROOT], +) diff --git a/java/java/lib/jsr305.jar b/lib/jsr-305/jsr305.jar similarity index 100% rename from java/java/lib/jsr305.jar rename to lib/jsr-305/jsr305.jar diff --git a/lib/junit/BUCK b/lib/junit/BUCK new file mode 100644 index 00000000..e35b0533 --- /dev/null +++ b/lib/junit/BUCK @@ -0,0 +1,21 @@ +# Copyright (c) 2014-present, Facebook, Inc. +# All rights reserved. +# +# This source code is licensed under the BSD-style license found in the +# LICENSE file in the root directory of this source tree. An additional grant +# of patent rights can be found in the PATENTS file in the same directory. + +include_defs('//CSSLAYOUT_DEFS') + +prebuilt_jar( + name = 'junit-jar', + binary_jar = 'junit4.jar', +) + +java_library( + name = 'junit', + exported_deps = [ + ':junit-jar', + ], + visibility = [CSSLAYOUT_ROOT], +) diff --git a/java/java/lib/junit4.jar b/lib/junit/junit4.jar similarity index 100% rename from java/java/lib/junit4.jar rename to lib/junit/junit4.jar diff --git a/package.json b/package.json deleted file mode 100644 index 730811f3..00000000 --- a/package.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "name": "css-layout", - "version": "1.1.1", - "description": "Reimplementation of CSS layout using pure JavaScript", - "main": "dist/css-layout.js", - "scripts": { - "watch": "grunt watch", - "test": "grunt ci" - }, - "repository": { - "type": "git", - "url": "https://github.com/facebook/css-layout.git" - }, - "keywords": [ - "css", - "flexbox", - "layout" - ], - "author": "", - "license": "BSD", - "bugs": { - "url": "https://github.com/facebook/css-layout/issues" - }, - "homepage": "https://github.com/facebook/css-layout", - "devDependencies": { - "babel-eslint": "^4.1.3", - "fbjs-scripts": "^0.2.2", - "grunt": "^0.4.5", - "grunt-cli": "^0.1.13", - "grunt-contrib-clean": "^0.6.0", - "grunt-contrib-concat": "^0.5.1", - "grunt-contrib-copy": "^0.8.0", - "grunt-contrib-uglify": "^0.9.1", - "grunt-contrib-watch": "^0.6.1", - "grunt-eslint": "^17.1.0", - "grunt-execute": "^0.2.2", - "grunt-include-replace": "^3.1.0", - "grunt-karma": "^0.12.0", - "grunt-mkdir": "^0.1.2", - "grunt-shell": "^1.1.2", - "jasmine-core": "^2.2.0", - "karma": "^0.13.8", - "karma-chrome-launcher": "^0.1.7", - "karma-jasmine": "^0.3.5", - "load-grunt-tasks": "^3.2.0" - } -} diff --git a/tests/CSSLayoutTest.cpp b/tests/CSSLayoutTest.cpp new file mode 100644 index 00000000..277e9830 --- /dev/null +++ b/tests/CSSLayoutTest.cpp @@ -0,0 +1,9361 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#include +#include + +#include + +TEST(CSSLayoutTest, test_layout_single_node_constant_width_height) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 100; + node_0->style.dimensions[CSSDimensionHeight] = 200; + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 100; + node_0->layout.dimensions[CSSDimensionHeight] = 200; + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_children) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 500; + node_1->style.dimensions[CSSDimensionHeight] = 500; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionWidth] = 250; + node_1->style.dimensions[CSSDimensionHeight] = 250; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->style.dimensions[CSSDimensionWidth] = 125; + node_1->style.dimensions[CSSDimensionHeight] = 125; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 500; + node_1->layout.dimensions[CSSDimensionHeight] = 500; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 500; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 250; + node_1->layout.dimensions[CSSDimensionHeight] = 250; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->layout.position[CSSPositionTop] = 750; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 125; + node_1->layout.dimensions[CSSDimensionHeight] = 125; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_children_in_reverse) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionColumnReverse; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 500; + node_1->style.dimensions[CSSDimensionHeight] = 500; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionWidth] = 250; + node_1->style.dimensions[CSSDimensionHeight] = 250; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->style.dimensions[CSSDimensionWidth] = 125; + node_1->style.dimensions[CSSDimensionHeight] = 125; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 500; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 500; + node_1->layout.dimensions[CSSDimensionHeight] = 500; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 250; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 250; + node_1->layout.dimensions[CSSDimensionHeight] = 250; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->layout.position[CSSPositionTop] = 125; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 125; + node_1->layout.dimensions[CSSDimensionHeight] = 125; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_nested_children) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 500; + node_1->style.dimensions[CSSDimensionHeight] = 500; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionWidth] = 500; + node_1->style.dimensions[CSSDimensionHeight] = 500; + init_css_node_children(node_1, 2); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->style.dimensions[CSSDimensionWidth] = 250; + node_2->style.dimensions[CSSDimensionHeight] = 250; + node_2 = CSSNodeGetChild(node_1, 1); + node_2->style.dimensions[CSSDimensionWidth] = 250; + node_2->style.dimensions[CSSDimensionHeight] = 250; + } + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 500; + node_1->layout.dimensions[CSSDimensionHeight] = 500; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 500; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 500; + node_1->layout.dimensions[CSSDimensionHeight] = 500; + init_css_node_children(node_1, 2); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 0; + node_2->layout.position[CSSPositionLeft] = 0; + node_2->layout.dimensions[CSSDimensionWidth] = 250; + node_2->layout.dimensions[CSSDimensionHeight] = 250; + node_2 = CSSNodeGetChild(node_1, 1); + node_2->layout.position[CSSPositionTop] = 250; + node_2->layout.position[CSSPositionLeft] = 0; + node_2->layout.dimensions[CSSDimensionWidth] = 250; + node_2->layout.dimensions[CSSDimensionHeight] = 250; + } + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_nested_children_in_reverse) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionColumnReverse; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 500; + node_1->style.dimensions[CSSDimensionHeight] = 500; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.flexDirection = CSSFlexDirectionColumnReverse; + node_1->style.dimensions[CSSDimensionWidth] = 500; + node_1->style.dimensions[CSSDimensionHeight] = 500; + init_css_node_children(node_1, 2); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->style.dimensions[CSSDimensionWidth] = 250; + node_2->style.dimensions[CSSDimensionHeight] = 250; + node_2 = CSSNodeGetChild(node_1, 1); + node_2->style.dimensions[CSSDimensionWidth] = 250; + node_2->style.dimensions[CSSDimensionHeight] = 250; + } + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 500; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 500; + node_1->layout.dimensions[CSSDimensionHeight] = 500; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 500; + node_1->layout.dimensions[CSSDimensionHeight] = 500; + init_css_node_children(node_1, 2); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 250; + node_2->layout.position[CSSPositionLeft] = 0; + node_2->layout.dimensions[CSSDimensionWidth] = 250; + node_2->layout.dimensions[CSSDimensionHeight] = 250; + node_2 = CSSNodeGetChild(node_1, 1); + node_2->layout.position[CSSPositionTop] = 0; + node_2->layout.position[CSSPositionLeft] = 0; + node_2->layout.dimensions[CSSDimensionWidth] = 250; + node_2->layout.dimensions[CSSDimensionHeight] = 250; + } + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_margin) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 100; + node_0->style.dimensions[CSSDimensionHeight] = 200; + node_0->style.margin[CSSPositionLeft] = 10; + node_0->style.margin[CSSPositionTop] = 10; + node_0->style.margin[CSSPositionRight] = 10; + node_0->style.margin[CSSPositionBottom] = 10; + node_0->style.margin[CSSPositionStart] = 10; + node_0->style.margin[CSSPositionEnd] = 10; + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 10; + node_0->layout.position[CSSPositionLeft] = 10; + node_0->layout.dimensions[CSSDimensionWidth] = 100; + node_0->layout.dimensions[CSSDimensionHeight] = 200; + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_several_children) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + node_0->style.margin[CSSPositionLeft] = 10; + node_0->style.margin[CSSPositionTop] = 10; + node_0->style.margin[CSSPositionRight] = 10; + node_0->style.margin[CSSPositionBottom] = 10; + node_0->style.margin[CSSPositionStart] = 10; + node_0->style.margin[CSSPositionEnd] = 10; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1->style.margin[CSSPositionLeft] = 50; + node_1->style.margin[CSSPositionTop] = 50; + node_1->style.margin[CSSPositionRight] = 50; + node_1->style.margin[CSSPositionBottom] = 50; + node_1->style.margin[CSSPositionStart] = 50; + node_1->style.margin[CSSPositionEnd] = 50; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1->style.margin[CSSPositionLeft] = 25; + node_1->style.margin[CSSPositionTop] = 25; + node_1->style.margin[CSSPositionRight] = 25; + node_1->style.margin[CSSPositionBottom] = 25; + node_1->style.margin[CSSPositionStart] = 25; + node_1->style.margin[CSSPositionEnd] = 25; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1->style.margin[CSSPositionLeft] = 10; + node_1->style.margin[CSSPositionTop] = 10; + node_1->style.margin[CSSPositionRight] = 10; + node_1->style.margin[CSSPositionBottom] = 10; + node_1->style.margin[CSSPositionStart] = 10; + node_1->style.margin[CSSPositionEnd] = 10; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 10; + node_0->layout.position[CSSPositionLeft] = 10; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 50; + node_1->layout.position[CSSPositionLeft] = 50; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 225; + node_1->layout.position[CSSPositionLeft] = 25; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->layout.position[CSSPositionTop] = 360; + node_1->layout.position[CSSPositionLeft] = 10; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_several_children_in_reverse) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionColumnReverse; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + node_0->style.margin[CSSPositionLeft] = 10; + node_0->style.margin[CSSPositionTop] = 10; + node_0->style.margin[CSSPositionRight] = 10; + node_0->style.margin[CSSPositionBottom] = 10; + node_0->style.margin[CSSPositionStart] = 10; + node_0->style.margin[CSSPositionEnd] = 10; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1->style.margin[CSSPositionLeft] = 50; + node_1->style.margin[CSSPositionTop] = 50; + node_1->style.margin[CSSPositionRight] = 50; + node_1->style.margin[CSSPositionBottom] = 50; + node_1->style.margin[CSSPositionStart] = 50; + node_1->style.margin[CSSPositionEnd] = 50; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1->style.margin[CSSPositionLeft] = 25; + node_1->style.margin[CSSPositionTop] = 25; + node_1->style.margin[CSSPositionRight] = 25; + node_1->style.margin[CSSPositionBottom] = 25; + node_1->style.margin[CSSPositionStart] = 25; + node_1->style.margin[CSSPositionEnd] = 25; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1->style.margin[CSSPositionLeft] = 10; + node_1->style.margin[CSSPositionTop] = 10; + node_1->style.margin[CSSPositionRight] = 10; + node_1->style.margin[CSSPositionBottom] = 10; + node_1->style.margin[CSSPositionStart] = 10; + node_1->style.margin[CSSPositionEnd] = 10; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 10; + node_0->layout.position[CSSPositionLeft] = 10; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 850; + node_1->layout.position[CSSPositionLeft] = 50; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 675; + node_1->layout.position[CSSPositionLeft] = 25; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->layout.position[CSSPositionTop] = 540; + node_1->layout.position[CSSPositionLeft] = 10; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_rtl_with_revers) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.direction = CSSDirectionRTL; + node_0->style.flexDirection = CSSFlexDirectionRowReverse; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 200; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionWidth] = 300; + node_1->style.dimensions[CSSDimensionHeight] = 150; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 100; + node_1->layout.dimensions[CSSDimensionWidth] = 300; + node_1->layout.dimensions[CSSDimensionHeight] = 150; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_flexDirection_row) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 200; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionWidth] = 300; + node_1->style.dimensions[CSSDimensionHeight] = 150; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 100; + node_1->layout.dimensions[CSSDimensionWidth] = 300; + node_1->layout.dimensions[CSSDimensionHeight] = 150; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_flexDirection_row_rtl) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.direction = CSSDirectionRTL; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 200; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionWidth] = 300; + node_1->style.dimensions[CSSDimensionHeight] = 150; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 900; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 600; + node_1->layout.dimensions[CSSDimensionWidth] = 300; + node_1->layout.dimensions[CSSDimensionHeight] = 150; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_based_on_children_main_dimensions) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 300; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 200; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionWidth] = 300; + node_1->style.dimensions[CSSDimensionHeight] = 150; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 300; + node_0->layout.dimensions[CSSDimensionHeight] = 350; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 200; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 300; + node_1->layout.dimensions[CSSDimensionHeight] = 150; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_based_on_children_main_dimensions_in_reverse) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionColumnReverse; + node_0->style.dimensions[CSSDimensionWidth] = 300; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 200; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionWidth] = 300; + node_1->style.dimensions[CSSDimensionHeight] = 150; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 300; + node_0->layout.dimensions[CSSDimensionHeight] = 350; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 150; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 300; + node_1->layout.dimensions[CSSDimensionHeight] = 150; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_flex) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 200; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.flex = 1; + node_1->style.dimensions[CSSDimensionWidth] = 100; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 200; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 800; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_flex_in_revese) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionColumnReverse; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 200; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.flex = 1; + node_1->style.dimensions[CSSDimensionWidth] = 100; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 800; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 800; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_flex_recursively) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flex = 1; + node_1->style.dimensions[CSSDimensionWidth] = 1000; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->style.flex = 1; + node_2->style.dimensions[CSSDimensionWidth] = 1000; + init_css_node_children(node_2, 1); + { + CSSNode *node_3; + node_3 = CSSNodeGetChild(node_2, 0); + node_3->style.flex = 1; + node_3->style.dimensions[CSSDimensionWidth] = 1000; + } + } + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 1000; + node_1->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 0; + node_2->layout.position[CSSPositionLeft] = 0; + node_2->layout.dimensions[CSSDimensionWidth] = 1000; + node_2->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_2, 1); + { + CSSNode *node_3; + node_3 = CSSNodeGetChild(node_2, 0); + node_3->layout.position[CSSPositionTop] = 0; + node_3->layout.position[CSSPositionLeft] = 0; + node_3->layout.dimensions[CSSDimensionWidth] = 1000; + node_3->layout.dimensions[CSSDimensionHeight] = 1000; + } + } + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_flex_recursively_in_reverse) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionColumnReverse; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flexDirection = CSSFlexDirectionColumnReverse; + node_1->style.flex = 1; + node_1->style.dimensions[CSSDimensionWidth] = 1000; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->style.flexDirection = CSSFlexDirectionColumnReverse; + node_2->style.flex = 1; + node_2->style.dimensions[CSSDimensionWidth] = 1000; + init_css_node_children(node_2, 1); + { + CSSNode *node_3; + node_3 = CSSNodeGetChild(node_2, 0); + node_3->style.flexDirection = CSSFlexDirectionColumnReverse; + node_3->style.flex = 1; + node_3->style.dimensions[CSSDimensionWidth] = 1000; + } + } + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 1000; + node_1->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 0; + node_2->layout.position[CSSPositionLeft] = 0; + node_2->layout.dimensions[CSSDimensionWidth] = 1000; + node_2->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_2, 1); + { + CSSNode *node_3; + node_3 = CSSNodeGetChild(node_2, 0); + node_3->layout.position[CSSPositionTop] = 0; + node_3->layout.position[CSSPositionLeft] = 0; + node_3->layout.dimensions[CSSDimensionWidth] = 1000; + node_3->layout.dimensions[CSSDimensionHeight] = 1000; + } + } + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_targeted_margin) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + node_0->style.margin[CSSPositionLeft] = 5; + node_0->style.margin[CSSPositionTop] = 10; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1->style.margin[CSSPositionLeft] = 15; + node_1->style.margin[CSSPositionTop] = 50; + node_1->style.margin[CSSPositionBottom] = 20; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1->style.margin[CSSPositionLeft] = 30; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 10; + node_0->layout.position[CSSPositionLeft] = 5; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 50; + node_1->layout.position[CSSPositionLeft] = 15; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 170; + node_1->layout.position[CSSPositionLeft] = 30; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_targeted_margin_in_reverse) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionColumnReverse; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + node_0->style.margin[CSSPositionLeft] = 5; + node_0->style.margin[CSSPositionTop] = 10; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1->style.margin[CSSPositionLeft] = 15; + node_1->style.margin[CSSPositionTop] = 50; + node_1->style.margin[CSSPositionBottom] = 20; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1->style.margin[CSSPositionLeft] = 30; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 10; + node_0->layout.position[CSSPositionLeft] = 5; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 880; + node_1->layout.position[CSSPositionLeft] = 15; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 730; + node_1->layout.position[CSSPositionLeft] = 30; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_justifyContent_flex_start) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.justifyContent = CSSJustifyFlexStart; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 100; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_justifyContent_flex_start_in_reverse) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionColumnReverse; + node_0->style.justifyContent = CSSJustifyFlexStart; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 900; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 800; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_justifyContent_flex_end) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.justifyContent = CSSJustifyFlexEnd; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 800; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 900; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_justifyContent_flex_end_in_reverse) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionColumnReverse; + node_0->style.justifyContent = CSSJustifyFlexEnd; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 100; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_justifyContent_space_between) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.justifyContent = CSSJustifySpaceBetween; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 900; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_justifyContent_space_between_in_reverse) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionColumnReverse; + node_0->style.justifyContent = CSSJustifySpaceBetween; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 900; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_justifyContent_space_around) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.justifyContent = CSSJustifySpaceAround; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 200; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 700; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_justifyContent_space_around_in_reverse) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionColumnReverse; + node_0->style.justifyContent = CSSJustifySpaceAround; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 700; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 200; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_justifyContent_center) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.justifyContent = CSSJustifyCenter; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 400; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 500; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_justifyContent_center_in_reverse) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionColumnReverse; + node_0->style.justifyContent = CSSJustifyCenter; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 500; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 400; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_flex_with_override_height) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flex = 1; + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 1000; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_alignItems_flex_start) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.alignItems = CSSAlignFlexStart; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 200; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 200; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 100; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_alignItems_flex_start_in_reverse) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionColumnReverse; + node_0->style.alignItems = CSSAlignFlexStart; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 200; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 900; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 200; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 800; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_alignItems_center) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.alignItems = CSSAlignCenter; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 200; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 400; + node_1->layout.dimensions[CSSDimensionWidth] = 200; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 100; + node_1->layout.position[CSSPositionLeft] = 450; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_alignItems_center_in_reverse) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionColumnReverse; + node_0->style.alignItems = CSSAlignCenter; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 200; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 900; + node_1->layout.position[CSSPositionLeft] = 400; + node_1->layout.dimensions[CSSDimensionWidth] = 200; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 800; + node_1->layout.position[CSSPositionLeft] = 450; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_alignItems_flex_end) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.alignItems = CSSAlignFlexEnd; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 200; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 800; + node_1->layout.dimensions[CSSDimensionWidth] = 200; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 100; + node_1->layout.position[CSSPositionLeft] = 900; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_alignItems_flex_end_in_reverse) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionColumnReverse; + node_0->style.alignItems = CSSAlignFlexEnd; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 200; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 900; + node_1->layout.position[CSSPositionLeft] = 800; + node_1->layout.dimensions[CSSDimensionWidth] = 200; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 800; + node_1->layout.position[CSSPositionLeft] = 900; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_alignSelf_overrides_alignItems) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.alignItems = CSSAlignFlexEnd; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 200; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.alignSelf = CSSAlignCenter; + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 800; + node_1->layout.dimensions[CSSDimensionWidth] = 200; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 100; + node_1->layout.position[CSSPositionLeft] = 450; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_alignSelf_overrides_alignItems_in_reverse) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionColumnReverse; + node_0->style.alignItems = CSSAlignFlexEnd; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 200; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.alignSelf = CSSAlignCenter; + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 900; + node_1->layout.position[CSSPositionLeft] = 800; + node_1->layout.dimensions[CSSDimensionWidth] = 200; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 800; + node_1->layout.position[CSSPositionLeft] = 450; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_alignItems_stretch) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.alignItems = CSSAlignStretch; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionHeight] = 100; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 1000; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_alignItems_stretch_in_reverse) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionColumnReverse; + node_0->style.alignItems = CSSAlignStretch; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionHeight] = 100; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 900; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 1000; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_empty_node) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + init_css_node_children(node_0, 1); + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 0; + node_0->layout.dimensions[CSSDimensionHeight] = 0; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_empty_node_in_reverse) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionColumnReverse; + init_css_node_children(node_0, 1); + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 0; + node_0->layout.dimensions[CSSDimensionHeight] = 0; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_child_with_margin) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.margin[CSSPositionLeft] = 5; + node_1->style.margin[CSSPositionTop] = 5; + node_1->style.margin[CSSPositionRight] = 5; + node_1->style.margin[CSSPositionBottom] = 5; + node_1->style.margin[CSSPositionStart] = 5; + node_1->style.margin[CSSPositionEnd] = 5; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 10; + node_0->layout.dimensions[CSSDimensionHeight] = 10; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 5; + node_1->layout.position[CSSPositionLeft] = 5; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_child_with_margin_in_reverse) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionColumnReverse; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.margin[CSSPositionLeft] = 5; + node_1->style.margin[CSSPositionTop] = 5; + node_1->style.margin[CSSPositionRight] = 5; + node_1->style.margin[CSSPositionBottom] = 5; + node_1->style.margin[CSSPositionStart] = 5; + node_1->style.margin[CSSPositionEnd] = 5; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 10; + node_0->layout.dimensions[CSSDimensionHeight] = 10; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 5; + node_1->layout.position[CSSPositionLeft] = 5; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_not_shrink_children_if_not_enough_space) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionHeight] = 200; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 0; + node_0->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 100; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_not_shrink_children_if_not_enough_space_in_reverse) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionColumnReverse; + node_0->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionHeight] = 200; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 0; + node_0->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = -200; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_for_center) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.justifyContent = CSSJustifyCenter; + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 0; + node_0->layout.dimensions[CSSDimensionHeight] = 0; + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_flex_end_with_margin) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.justifyContent = CSSJustifyFlexEnd; + node_0->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.margin[CSSPositionTop] = 10; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 0; + node_0->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 100; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_flex_end_with_margin_reverse) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionColumnReverse; + node_0->style.justifyContent = CSSJustifyFlexEnd; + node_0->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.margin[CSSPositionTop] = 10; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 0; + node_0->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 10; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_alignItems_with_margin) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.alignItems = CSSAlignFlexEnd; + init_css_node_children(node_1, 2); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->style.margin[CSSPositionLeft] = 10; + node_2->style.margin[CSSPositionTop] = 10; + node_2->style.margin[CSSPositionRight] = 10; + node_2->style.margin[CSSPositionBottom] = 10; + node_2->style.margin[CSSPositionStart] = 10; + node_2->style.margin[CSSPositionEnd] = 10; + node_2 = CSSNodeGetChild(node_1, 1); + node_2->style.dimensions[CSSDimensionHeight] = 100; + } + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 20; + node_0->layout.dimensions[CSSDimensionHeight] = 120; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 20; + node_1->layout.dimensions[CSSDimensionHeight] = 120; + init_css_node_children(node_1, 2); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 10; + node_2->layout.position[CSSPositionLeft] = 10; + node_2->layout.dimensions[CSSDimensionWidth] = 0; + node_2->layout.dimensions[CSSDimensionHeight] = 0; + node_2 = CSSNodeGetChild(node_1, 1); + node_2->layout.position[CSSPositionTop] = 20; + node_2->layout.position[CSSPositionLeft] = 20; + node_2->layout.dimensions[CSSDimensionWidth] = 0; + node_2->layout.dimensions[CSSDimensionHeight] = 100; + } + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_alignItems_with_margin_in_reverse) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flexDirection = CSSFlexDirectionColumnReverse; + node_1->style.alignItems = CSSAlignFlexEnd; + init_css_node_children(node_1, 2); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->style.margin[CSSPositionLeft] = 10; + node_2->style.margin[CSSPositionTop] = 10; + node_2->style.margin[CSSPositionRight] = 10; + node_2->style.margin[CSSPositionBottom] = 10; + node_2->style.margin[CSSPositionStart] = 10; + node_2->style.margin[CSSPositionEnd] = 10; + node_2 = CSSNodeGetChild(node_1, 1); + node_2->style.dimensions[CSSDimensionHeight] = 100; + } + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 20; + node_0->layout.dimensions[CSSDimensionHeight] = 120; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 20; + node_1->layout.dimensions[CSSDimensionHeight] = 120; + init_css_node_children(node_1, 2); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 110; + node_2->layout.position[CSSPositionLeft] = 10; + node_2->layout.dimensions[CSSDimensionWidth] = 0; + node_2->layout.dimensions[CSSDimensionHeight] = 0; + node_2 = CSSNodeGetChild(node_1, 1); + node_2->layout.position[CSSPositionTop] = 0; + node_2->layout.position[CSSPositionLeft] = 20; + node_2->layout.dimensions[CSSDimensionWidth] = 0; + node_2->layout.dimensions[CSSDimensionHeight] = 100; + } + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_flex_inside_empty_node) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flex = 1; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 0; + node_0->layout.dimensions[CSSDimensionHeight] = 0; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_alignItems_stretch_with_margin) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.alignItems = CSSAlignStretch; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.margin[CSSPositionLeft] = 10; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 10; + node_0->layout.dimensions[CSSDimensionHeight] = 0; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 10; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_alignItems_stretch_with_margin_in_reverse) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionColumnReverse; + node_0->style.alignItems = CSSAlignStretch; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.margin[CSSPositionLeft] = 10; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 10; + node_0->layout.dimensions[CSSDimensionHeight] = 0; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 10; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_padding) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.padding[CSSPositionLeft] = 5; + node_0->style.padding[CSSPositionTop] = 5; + node_0->style.padding[CSSPositionRight] = 5; + node_0->style.padding[CSSPositionBottom] = 5; + node_0->style.padding[CSSPositionStart] = 5; + node_0->style.padding[CSSPositionEnd] = 5; + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 10; + node_0->layout.dimensions[CSSDimensionHeight] = 10; + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_padding_and_child) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.padding[CSSPositionLeft] = 5; + node_0->style.padding[CSSPositionTop] = 5; + node_0->style.padding[CSSPositionRight] = 5; + node_0->style.padding[CSSPositionBottom] = 5; + node_0->style.padding[CSSPositionStart] = 5; + node_0->style.padding[CSSPositionEnd] = 5; + init_css_node_children(node_0, 1); + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 10; + node_0->layout.dimensions[CSSDimensionHeight] = 10; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 5; + node_1->layout.position[CSSPositionLeft] = 5; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_padding_and_child_with_margin) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.padding[CSSPositionLeft] = 5; + node_0->style.padding[CSSPositionTop] = 5; + node_0->style.padding[CSSPositionRight] = 5; + node_0->style.padding[CSSPositionBottom] = 5; + node_0->style.padding[CSSPositionStart] = 5; + node_0->style.padding[CSSPositionEnd] = 5; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.margin[CSSPositionLeft] = 5; + node_1->style.margin[CSSPositionTop] = 5; + node_1->style.margin[CSSPositionRight] = 5; + node_1->style.margin[CSSPositionBottom] = 5; + node_1->style.margin[CSSPositionStart] = 5; + node_1->style.margin[CSSPositionEnd] = 5; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 20; + node_0->layout.dimensions[CSSDimensionHeight] = 20; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 10; + node_1->layout.position[CSSPositionLeft] = 10; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_padding_and_stretch) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.alignSelf = CSSAlignStretch; + node_1->style.padding[CSSPositionLeft] = 10; + node_1->style.padding[CSSPositionTop] = 10; + node_1->style.padding[CSSPositionRight] = 10; + node_1->style.padding[CSSPositionBottom] = 10; + node_1->style.padding[CSSPositionStart] = 10; + node_1->style.padding[CSSPositionEnd] = 10; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 20; + node_0->layout.dimensions[CSSDimensionHeight] = 20; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 20; + node_1->layout.dimensions[CSSDimensionHeight] = 20; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_inner_outer_padding_and_stretch) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.padding[CSSPositionLeft] = 50; + node_0->style.padding[CSSPositionTop] = 50; + node_0->style.padding[CSSPositionRight] = 50; + node_0->style.padding[CSSPositionBottom] = 50; + node_0->style.padding[CSSPositionStart] = 50; + node_0->style.padding[CSSPositionEnd] = 50; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.alignSelf = CSSAlignStretch; + node_1->style.padding[CSSPositionLeft] = 10; + node_1->style.padding[CSSPositionTop] = 10; + node_1->style.padding[CSSPositionRight] = 10; + node_1->style.padding[CSSPositionBottom] = 10; + node_1->style.padding[CSSPositionStart] = 10; + node_1->style.padding[CSSPositionEnd] = 10; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 120; + node_0->layout.dimensions[CSSDimensionHeight] = 120; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 50; + node_1->layout.position[CSSPositionLeft] = 50; + node_1->layout.dimensions[CSSDimensionWidth] = 20; + node_1->layout.dimensions[CSSDimensionHeight] = 20; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_pstretch_and_child_with_margin) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.alignSelf = CSSAlignStretch; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->style.margin[CSSPositionLeft] = 16; + node_2->style.margin[CSSPositionTop] = 16; + node_2->style.margin[CSSPositionRight] = 16; + node_2->style.margin[CSSPositionBottom] = 16; + node_2->style.margin[CSSPositionStart] = 16; + node_2->style.margin[CSSPositionEnd] = 16; + } + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 32; + node_0->layout.dimensions[CSSDimensionHeight] = 32; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 32; + node_1->layout.dimensions[CSSDimensionHeight] = 32; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 16; + node_2->layout.position[CSSPositionLeft] = 16; + node_2->layout.dimensions[CSSDimensionWidth] = 0; + node_2->layout.dimensions[CSSDimensionHeight] = 0; + } + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_top_and_left) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.position[CSSPositionLeft] = 5; + node_0->style.position[CSSPositionTop] = 5; + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 5; + node_0->layout.position[CSSPositionLeft] = 5; + node_0->layout.dimensions[CSSDimensionWidth] = 0; + node_0->layout.dimensions[CSSDimensionHeight] = 0; + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_height_padding_space_around) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.justifyContent = CSSJustifySpaceAround; + node_0->style.dimensions[CSSDimensionHeight] = 10; + node_0->style.padding[CSSPositionTop] = 5; + init_css_node_children(node_0, 1); + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 0; + node_0->layout.dimensions[CSSDimensionHeight] = 10; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 7.5; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_bottom) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.position[CSSPositionBottom] = 5; + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = -5; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 0; + node_0->layout.dimensions[CSSDimensionHeight] = 0; + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_top_and_bottom) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.position[CSSPositionTop] = 10; + node_0->style.position[CSSPositionBottom] = 5; + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 10; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 0; + node_0->layout.dimensions[CSSDimensionHeight] = 0; + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_absolute_position) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.dimensions[CSSDimensionWidth] = 500; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flex = 1; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.positionType = CSSPositionTypeAbsolute; + node_1->style.dimensions[CSSDimensionWidth] = 50; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->style.flex = 1; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 500; + node_0->layout.dimensions[CSSDimensionHeight] = 0; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 250; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 250; + node_1->layout.dimensions[CSSDimensionWidth] = 50; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 250; + node_1->layout.dimensions[CSSDimensionWidth] = 250; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_absolute_position_and_margin) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.positionType = CSSPositionTypeAbsolute; + node_1->style.margin[CSSPositionRight] = 15; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 0; + node_0->layout.dimensions[CSSDimensionHeight] = 0; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_absolute_position_and_padding_and_alignSelf_center) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.alignSelf = CSSAlignCenter; + node_1->style.positionType = CSSPositionTypeAbsolute; + node_1->style.padding[CSSPositionRight] = 12; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 0; + node_0->layout.dimensions[CSSDimensionHeight] = 0; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 12; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_work_with_height_smaller_than_padding_bottom) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionHeight] = 5; + node_0->style.padding[CSSPositionBottom] = 20; + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 0; + node_0->layout.dimensions[CSSDimensionHeight] = 20; + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_work_with_width_smaller_than_padding_left) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 5; + node_0->style.padding[CSSPositionLeft] = 20; + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 20; + node_0->layout.dimensions[CSSDimensionHeight] = 0; + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_width_and_stretch) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->style.dimensions[CSSDimensionWidth] = 400; + } + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.alignSelf = CSSAlignStretch; + node_1->style.dimensions[CSSDimensionWidth] = 200; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 400; + node_0->layout.dimensions[CSSDimensionHeight] = 0; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 400; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 0; + node_2->layout.position[CSSPositionLeft] = 0; + node_2->layout.dimensions[CSSDimensionWidth] = 400; + node_2->layout.dimensions[CSSDimensionHeight] = 0; + } + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 200; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_padding_and_absolute_child) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.padding[CSSPositionLeft] = 5; + node_0->style.padding[CSSPositionTop] = 5; + node_0->style.padding[CSSPositionRight] = 5; + node_0->style.padding[CSSPositionBottom] = 5; + node_0->style.padding[CSSPositionStart] = 5; + node_0->style.padding[CSSPositionEnd] = 5; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.positionType = CSSPositionTypeAbsolute; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 10; + node_0->layout.dimensions[CSSDimensionHeight] = 10; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 5; + node_1->layout.position[CSSPositionLeft] = 5; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_absolute_node_with_top_and_left) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.positionType = CSSPositionTypeAbsolute; + node_1->style.position[CSSPositionLeft] = 10; + node_1->style.position[CSSPositionTop] = 10; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 0; + node_0->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 10; + node_1->layout.position[CSSPositionLeft] = 10; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_padding_and_absolute_child_position_left) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.padding[CSSPositionLeft] = 20; + node_0->style.padding[CSSPositionTop] = 20; + node_0->style.padding[CSSPositionRight] = 20; + node_0->style.padding[CSSPositionBottom] = 20; + node_0->style.padding[CSSPositionStart] = 20; + node_0->style.padding[CSSPositionEnd] = 20; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.positionType = CSSPositionTypeAbsolute; + node_1->style.position[CSSPositionLeft] = 5; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 40; + node_0->layout.dimensions[CSSDimensionHeight] = 40; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 20; + node_1->layout.position[CSSPositionLeft] = 5; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_absolute_node_with_top_and_margin_top) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.positionType = CSSPositionTypeAbsolute; + node_1->style.margin[CSSPositionTop] = 5; + node_1->style.position[CSSPositionTop] = 5; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 0; + node_0->layout.dimensions[CSSDimensionHeight] = 0; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 10; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_absolute_node_with_left_and_margin_left) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.positionType = CSSPositionTypeAbsolute; + node_1->style.margin[CSSPositionLeft] = 5; + node_1->style.position[CSSPositionLeft] = 5; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 0; + node_0->layout.dimensions[CSSDimensionHeight] = 0; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 10; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_space_around_and_absolute_child) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.justifyContent = CSSJustifySpaceAround; + node_0->style.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.positionType = CSSPositionTypeAbsolute; + node_1 = CSSNodeGetChild(node_0, 1); + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 0; + node_0->layout.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 100; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 100; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_space_around_and_absolute_child_in_reverse) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionColumnReverse; + node_0->style.justifyContent = CSSJustifySpaceAround; + node_0->style.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.positionType = CSSPositionTypeAbsolute; + node_1 = CSSNodeGetChild(node_0, 1); + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 0; + node_0->layout.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 100; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 100; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_flex_and_main_margin) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.dimensions[CSSDimensionWidth] = 700; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flex = 1; + node_1->style.margin[CSSPositionLeft] = 5; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 700; + node_0->layout.dimensions[CSSDimensionHeight] = 0; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 5; + node_1->layout.dimensions[CSSDimensionWidth] = 695; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_flex_and_main_margin_rtl) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.direction = CSSDirectionRTL; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.dimensions[CSSDimensionWidth] = 700; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flex = 1; + node_1->style.margin[CSSPositionRight] = 5; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 700; + node_0->layout.dimensions[CSSDimensionHeight] = 0; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 695; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_multiple_flex_and_padding) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.dimensions[CSSDimensionWidth] = 700; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flex = 1; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.flex = 1; + node_1->style.padding[CSSPositionRight] = 5; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 700; + node_0->layout.dimensions[CSSDimensionHeight] = 0; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 347.5; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 347.5; + node_1->layout.dimensions[CSSDimensionWidth] = 352.5; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_multiple_flex_and_padding_rtl) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.direction = CSSDirectionRTL; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.dimensions[CSSDimensionWidth] = 700; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flex = 1; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.flex = 1; + node_1->style.padding[CSSPositionLeft] = 5; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 700; + node_0->layout.dimensions[CSSDimensionHeight] = 0; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 352.5; + node_1->layout.dimensions[CSSDimensionWidth] = 347.5; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 352.5; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_multiple_flex_and_margin) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.dimensions[CSSDimensionWidth] = 700; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flex = 1; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.flex = 1; + node_1->style.margin[CSSPositionLeft] = 5; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 700; + node_0->layout.dimensions[CSSDimensionHeight] = 0; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 347.5; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 352.5; + node_1->layout.dimensions[CSSDimensionWidth] = 347.5; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_multiple_flex_and_margin_rtl) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.direction = CSSDirectionRTL; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.dimensions[CSSDimensionWidth] = 700; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flex = 1; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.flex = 1; + node_1->style.margin[CSSPositionRight] = 5; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 700; + node_0->layout.dimensions[CSSDimensionHeight] = 0; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 352.5; + node_1->layout.dimensions[CSSDimensionWidth] = 347.5; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 347.5; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_flex_and_overflow) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionHeight] = 300; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionHeight] = 600; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.flex = 1; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 0; + node_0->layout.dimensions[CSSDimensionHeight] = 300; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 600; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 600; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_absolute_node_with_flex) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.dimensions[CSSDimensionWidth] = 600; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.positionType = CSSPositionTypeAbsolute; + node_1->style.flex = 1; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 600; + node_0->layout.dimensions[CSSDimensionHeight] = 0; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_absolute_node_with_flex_rtl) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.direction = CSSDirectionRTL; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.dimensions[CSSDimensionWidth] = 600; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.positionType = CSSPositionTypeAbsolute; + node_1->style.flex = 1; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 600; + node_0->layout.dimensions[CSSDimensionHeight] = 0; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 600; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_absolute_node_with_double_flex) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionHeight] = 500; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flex = 1; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.positionType = CSSPositionTypeAbsolute; + node_1->style.flex = 1; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 0; + node_0->layout.dimensions[CSSDimensionHeight] = 500; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 500; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 500; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_border_width) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.border[CSSPositionLeft] = 5; + node_0->style.border[CSSPositionTop] = 5; + node_0->style.border[CSSPositionRight] = 5; + node_0->style.border[CSSPositionBottom] = 5; + node_0->style.border[CSSPositionStart] = 5; + node_0->style.border[CSSPositionEnd] = 5; + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 10; + node_0->layout.dimensions[CSSDimensionHeight] = 10; + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_absolute_node_with_border_width_position_top) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.border[CSSPositionTop] = 1; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.positionType = CSSPositionTypeAbsolute; + node_1->style.position[CSSPositionTop] = -1; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 0; + node_0->layout.dimensions[CSSDimensionHeight] = 1; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_absolute_node_with_border_width_position_top_cross_axis) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.border[CSSPositionLeft] = 1; + node_0->style.border[CSSPositionTop] = 1; + node_0->style.border[CSSPositionRight] = 1; + node_0->style.border[CSSPositionBottom] = 1; + node_0->style.border[CSSPositionStart] = 1; + node_0->style.border[CSSPositionEnd] = 1; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.positionType = CSSPositionTypeAbsolute; + node_1->style.position[CSSPositionLeft] = 5; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 2; + node_0->layout.dimensions[CSSDimensionHeight] = 2; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 1; + node_1->layout.position[CSSPositionLeft] = 6; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_min_padding_align_stretch) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 50; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.alignSelf = CSSAlignStretch; + node_1->style.margin[CSSPositionLeft] = 20; + node_1->style.padding[CSSPositionLeft] = 20; + node_1->style.padding[CSSPositionTop] = 20; + node_1->style.padding[CSSPositionRight] = 20; + node_1->style.padding[CSSPositionBottom] = 20; + node_1->style.padding[CSSPositionStart] = 20; + node_1->style.padding[CSSPositionEnd] = 20; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 50; + node_0->layout.dimensions[CSSDimensionHeight] = 40; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 20; + node_1->layout.dimensions[CSSDimensionWidth] = 40; + node_1->layout.dimensions[CSSDimensionHeight] = 40; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_negative_width) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = -31; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.border[CSSPositionRight] = 5; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 5; + node_0->layout.dimensions[CSSDimensionHeight] = 0; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 5; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_min_padding_and_negative_margin) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.border[CSSPositionRight] = 1; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.margin[CSSPositionRight] = -8; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1; + node_0->layout.dimensions[CSSDimensionHeight] = 0; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_min_padding_and_negative_margin_rtl) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.direction = CSSDirectionRTL; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.border[CSSPositionLeft] = 1; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.margin[CSSPositionLeft] = -8; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1; + node_0->layout.dimensions[CSSDimensionHeight] = 0; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 1; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_just_text) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->measure = measure; + node_0->context = (char *) SMALL_TEXT; + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = SMALL_WIDTH; + node_0->layout.dimensions[CSSDimensionHeight] = SMALL_HEIGHT; + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_fixed_width_and_custom_measure) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 100; + node_0->measure = measure; + node_0->context = (char *) MEASURE_WITH_RATIO_2; + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 100; + node_0->layout.dimensions[CSSDimensionHeight] = 200; + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_layout_node_with_fixed_height_and_custom_measure) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionHeight] = 100; + node_0->measure = measure; + node_0->context = (char *) MEASURE_WITH_RATIO_2; + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 200; + node_0->layout.dimensions[CSSDimensionHeight] = 100; + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_skip_measure_if_fixed_height_and_width) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 100; + node_0->style.dimensions[CSSDimensionHeight] = 100; + node_0->measure = measure; + node_0->context = (char *) MEASURE_WITH_RATIO_2; + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 100; + node_0->layout.dimensions[CSSDimensionHeight] = 100; + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_with_measure) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->measure = measure; + node_0->context = (char *) MEASURE_WITH_RATIO_2; + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 99999; + node_0->layout.dimensions[CSSDimensionHeight] = 99999; + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_nested_stacks_with_measure) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionColumn; + node_0->style.dimensions[CSSDimensionWidth] = 320; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->measure = measure; + node_1->context = (char *) MEASURE_WITH_RATIO_2; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.flexDirection = CSSFlexDirectionRow; + node_1->style.overflow = CSSOverflowHidden; + node_1->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_1, 2); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->measure = measure; + node_2->context = (char *) MEASURE_WITH_RATIO_2; + node_2 = CSSNodeGetChild(node_1, 1); + node_2->measure = measure; + node_2->context = (char *) MEASURE_WITH_RATIO_2; + } + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 320; + node_0->layout.dimensions[CSSDimensionHeight] = 740; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 320; + node_1->layout.dimensions[CSSDimensionHeight] = 640; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 640; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 320; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_1, 2); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 0; + node_2->layout.position[CSSPositionLeft] = 0; + node_2->layout.dimensions[CSSDimensionWidth] = 200; + node_2->layout.dimensions[CSSDimensionHeight] = 100; + node_2 = CSSNodeGetChild(node_1, 1); + node_2->layout.position[CSSPositionTop] = 0; + node_2->layout.position[CSSPositionLeft] = 200; + node_2->layout.dimensions[CSSDimensionWidth] = 200; + node_2->layout.dimensions[CSSDimensionHeight] = 100; + } + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_text_node_with_width) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 10; + node_0->measure = measure; + node_0->context = (char *) SMALL_TEXT; + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 10; + node_0->layout.dimensions[CSSDimensionHeight] = BIG_HEIGHT; + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_text_node_with_padding_and_margin) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->measure = measure; + node_0->context = (char *) LONG_TEXT; + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = BIG_WIDTH; + node_0->layout.dimensions[CSSDimensionHeight] = SMALL_HEIGHT; + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_with_nested_alignSelf_stretch) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 300; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.alignSelf = CSSAlignStretch; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->style.alignSelf = CSSAlignStretch; + } + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 300; + node_0->layout.dimensions[CSSDimensionHeight] = 0; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 300; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 0; + node_2->layout.position[CSSPositionLeft] = 0; + node_2->layout.dimensions[CSSDimensionWidth] = 300; + node_2->layout.dimensions[CSSDimensionHeight] = 0; + } + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_with_text_and_flex) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flexDirection = CSSFlexDirectionRow; + node_1->style.dimensions[CSSDimensionWidth] = 500; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->style.flex = 1; + node_2->measure = measure; + node_2->context = (char *) LONG_TEXT; + } + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 500; + node_0->layout.dimensions[CSSDimensionHeight] = SMALL_HEIGHT; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 500; + node_1->layout.dimensions[CSSDimensionHeight] = SMALL_HEIGHT; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 0; + node_2->layout.position[CSSPositionLeft] = 0; + node_2->layout.dimensions[CSSDimensionWidth] = 500; + node_2->layout.dimensions[CSSDimensionHeight] = SMALL_HEIGHT; + } + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_text_and_flex_rtl) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.direction = CSSDirectionRTL; + node_1->style.flexDirection = CSSFlexDirectionRow; + node_1->style.dimensions[CSSDimensionWidth] = 500; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->style.flex = 1; + node_2->measure = measure; + node_2->context = (char *) LONG_TEXT; + } + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 500; + node_0->layout.dimensions[CSSDimensionHeight] = SMALL_HEIGHT; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 500; + node_1->layout.dimensions[CSSDimensionHeight] = SMALL_HEIGHT; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 0; + node_2->layout.position[CSSPositionLeft] = 0; + node_2->layout.dimensions[CSSDimensionWidth] = 500; + node_2->layout.dimensions[CSSDimensionHeight] = SMALL_HEIGHT; + } + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_text_and_stretch) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 130; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.alignItems = CSSAlignStretch; + node_1->style.alignSelf = CSSAlignStretch; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->measure = measure; + node_2->context = (char *) LONG_TEXT; + } + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 130; + node_0->layout.dimensions[CSSDimensionHeight] = BIG_HEIGHT; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 130; + node_1->layout.dimensions[CSSDimensionHeight] = BIG_HEIGHT; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 0; + node_2->layout.position[CSSPositionLeft] = 0; + node_2->layout.dimensions[CSSDimensionWidth] = 130; + node_2->layout.dimensions[CSSDimensionHeight] = BIG_HEIGHT; + } + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_text_and_stretch_and_width) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 200; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.alignItems = CSSAlignStretch; + node_1->style.alignSelf = CSSAlignStretch; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->style.dimensions[CSSDimensionWidth] = 130; + node_2->measure = measure; + node_2->context = (char *) LONG_TEXT; + } + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 200; + node_0->layout.dimensions[CSSDimensionHeight] = BIG_HEIGHT; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 200; + node_1->layout.dimensions[CSSDimensionHeight] = BIG_HEIGHT; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 0; + node_2->layout.position[CSSPositionLeft] = 0; + node_2->layout.dimensions[CSSDimensionWidth] = 130; + node_2->layout.dimensions[CSSDimensionHeight] = BIG_HEIGHT; + } + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_text_bounded_by_parent) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.alignSelf = CSSAlignFlexStart; + node_0->style.dimensions[CSSDimensionWidth] = 100; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.alignSelf = CSSAlignFlexStart; + node_1->measure = measure; + node_1->context = (char *) LONG_TEXT; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 100; + node_0->layout.dimensions[CSSDimensionHeight] = BIG_HEIGHT; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = BIG_HEIGHT; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_text_bounded_by_grand_parent) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.alignSelf = CSSAlignFlexStart; + node_0->style.dimensions[CSSDimensionWidth] = 100; + node_0->style.padding[CSSPositionLeft] = 10; + node_0->style.padding[CSSPositionTop] = 10; + node_0->style.padding[CSSPositionRight] = 10; + node_0->style.padding[CSSPositionBottom] = 10; + node_0->style.padding[CSSPositionStart] = 10; + node_0->style.padding[CSSPositionEnd] = 10; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.alignSelf = CSSAlignFlexStart; + node_1->style.margin[CSSPositionLeft] = 10; + node_1->style.margin[CSSPositionTop] = 10; + node_1->style.margin[CSSPositionRight] = 10; + node_1->style.margin[CSSPositionBottom] = 10; + node_1->style.margin[CSSPositionStart] = 10; + node_1->style.margin[CSSPositionEnd] = 10; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->measure = measure; + node_2->context = (char *) LONG_TEXT; + } + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 100; + node_0->layout.dimensions[CSSDimensionHeight] = 76; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 20; + node_1->layout.position[CSSPositionLeft] = 20; + node_1->layout.dimensions[CSSDimensionWidth] = 60; + node_1->layout.dimensions[CSSDimensionHeight] = BIG_HEIGHT; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 0; + node_2->layout.position[CSSPositionLeft] = 0; + node_2->layout.dimensions[CSSDimensionWidth] = 60; + node_2->layout.dimensions[CSSDimensionHeight] = BIG_HEIGHT; + } + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_space_between_negative_space) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.justifyContent = CSSJustifySpaceBetween; + node_0->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionHeight] = 900; + node_1 = CSSNodeGetChild(node_0, 1); + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 0; + node_0->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 900; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 900; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_space_between_negative_space_in_reverse) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionColumnReverse; + node_0->style.justifyContent = CSSJustifySpaceBetween; + node_0->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionHeight] = 900; + node_1 = CSSNodeGetChild(node_0, 1); + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 0; + node_0->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = -800; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 900; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = -800; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_flex_end_negative_remaining_space) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.justifyContent = CSSJustifyFlexEnd; + node_0->style.dimensions[CSSDimensionWidth] = 200; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 900; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 200; + node_0->layout.dimensions[CSSDimensionHeight] = 0; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = -700; + node_1->layout.dimensions[CSSDimensionWidth] = 900; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_flex_end_negative_remaining_space_rtl) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.direction = CSSDirectionRTL; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.justifyContent = CSSJustifyFlexEnd; + node_0->style.dimensions[CSSDimensionWidth] = 200; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 900; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 200; + node_0->layout.dimensions[CSSDimensionHeight] = 0; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 900; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_text_direction_row) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flexDirection = CSSFlexDirectionRow; + node_1->style.dimensions[CSSDimensionWidth] = 200; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->style.margin[CSSPositionLeft] = 20; + node_2->style.margin[CSSPositionTop] = 20; + node_2->style.margin[CSSPositionRight] = 20; + node_2->style.margin[CSSPositionBottom] = 20; + node_2->style.margin[CSSPositionStart] = 20; + node_2->style.margin[CSSPositionEnd] = 20; + node_2->measure = measure; + node_2->context = (char *) SMALL_TEXT; + } + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 200; + node_0->layout.dimensions[CSSDimensionHeight] = 58; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 200; + node_1->layout.dimensions[CSSDimensionHeight] = 58; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 20; + node_2->layout.position[CSSPositionLeft] = 20; + node_2->layout.dimensions[CSSDimensionWidth] = SMALL_WIDTH; + node_2->layout.dimensions[CSSDimensionHeight] = SMALL_HEIGHT; + } + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_text_direction_row_rtl) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.direction = CSSDirectionRTL; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flexDirection = CSSFlexDirectionRow; + node_1->style.dimensions[CSSDimensionWidth] = 200; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->style.margin[CSSPositionLeft] = 20; + node_2->style.margin[CSSPositionTop] = 20; + node_2->style.margin[CSSPositionRight] = 20; + node_2->style.margin[CSSPositionBottom] = 20; + node_2->style.margin[CSSPositionStart] = 20; + node_2->style.margin[CSSPositionEnd] = 20; + node_2->measure = measure; + node_2->context = (char *) SMALL_TEXT; + } + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 200; + node_0->layout.dimensions[CSSDimensionHeight] = 58; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 200; + node_1->layout.dimensions[CSSDimensionHeight] = 58; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 20; + node_2->layout.position[CSSPositionLeft] = 145; + node_2->layout.dimensions[CSSDimensionWidth] = SMALL_WIDTH; + node_2->layout.dimensions[CSSDimensionHeight] = SMALL_HEIGHT; + } + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_text_with_margin) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 200; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->style.margin[CSSPositionLeft] = 20; + node_2->style.margin[CSSPositionTop] = 20; + node_2->style.margin[CSSPositionRight] = 20; + node_2->style.margin[CSSPositionBottom] = 20; + node_2->style.margin[CSSPositionStart] = 20; + node_2->style.margin[CSSPositionEnd] = 20; + node_2->measure = measure; + node_2->context = (char *) LONG_TEXT; + } + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 200; + node_0->layout.dimensions[CSSDimensionHeight] = 76; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 200; + node_1->layout.dimensions[CSSDimensionHeight] = 76; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 20; + node_2->layout.position[CSSPositionLeft] = 20; + node_2->layout.dimensions[CSSDimensionWidth] = 160; + node_2->layout.dimensions[CSSDimensionHeight] = BIG_HEIGHT; + } + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_absolute_node_with_left_top_right_bottom) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 100; + node_0->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.positionType = CSSPositionTypeAbsolute; + node_1->style.position[CSSPositionLeft] = 0; + node_1->style.position[CSSPositionTop] = 0; + node_1->style.position[CSSPositionRight] = 0; + node_1->style.position[CSSPositionBottom] = 0; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 100; + node_0->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_with_arbitrary_flex) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.alignSelf = CSSAlignFlexStart; + node_0->style.dimensions[CSSDimensionWidth] = 100; + node_0->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.alignSelf = CSSAlignFlexStart; + node_1->style.flex = 2.5; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.alignSelf = CSSAlignFlexStart; + node_1->style.flex = 7.5; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 100; + node_0->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 25; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 25; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 75; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_with_arbitrary_flex_in_reverse) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionColumnReverse; + node_0->style.alignSelf = CSSAlignFlexStart; + node_0->style.dimensions[CSSDimensionWidth] = 100; + node_0->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.alignSelf = CSSAlignFlexStart; + node_1->style.flex = 2.5; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.alignSelf = CSSAlignFlexStart; + node_1->style.flex = 7.5; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 100; + node_0->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 75; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 25; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 75; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_with_negative_flex_in_reverse) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionColumnReverse; + node_0->style.alignSelf = CSSAlignFlexStart; + node_0->style.dimensions[CSSDimensionWidth] = 100; + node_0->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.alignSelf = CSSAlignFlexStart; + node_1->style.flex = -2.5; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.alignSelf = CSSAlignFlexStart; + node_1->style.flex = 0; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 100; + node_0->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 100; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 100; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_absolute_node_with_sibling) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 50; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.positionType = CSSPositionTypeAbsolute; + node_1->style.position[CSSPositionLeft] = 0; + node_1->style.position[CSSPositionRight] = 0; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 50; + node_0->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 50; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 100; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 50; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_absolute_node_with_top_bottom) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.positionType = CSSPositionTypeAbsolute; + node_1->style.position[CSSPositionTop] = 0; + node_1->style.position[CSSPositionBottom] = 20; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 0; + node_0->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 80; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_absolute_node_with_justifyContent_center) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 200; + node_0->style.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.justifyContent = CSSJustifyCenter; + node_1->style.positionType = CSSPositionTypeAbsolute; + node_1->style.position[CSSPositionLeft] = 0; + node_1->style.position[CSSPositionTop] = 0; + node_1->style.position[CSSPositionRight] = 0; + node_1->style.position[CSSPositionBottom] = 0; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->style.dimensions[CSSDimensionWidth] = 100; + node_2->style.dimensions[CSSDimensionHeight] = 100; + } + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 200; + node_0->layout.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 200; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 50; + node_2->layout.position[CSSPositionLeft] = 0; + node_2->layout.dimensions[CSSDimensionWidth] = 100; + node_2->layout.dimensions[CSSDimensionHeight] = 100; + } + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_absolute_node_with_bottom) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.positionType = CSSPositionTypeAbsolute; + node_1->style.position[CSSPositionBottom] = 0; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 0; + node_0->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 100; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_absolute_node_with_right) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 100; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.positionType = CSSPositionTypeAbsolute; + node_1->style.position[CSSPositionRight] = 0; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 100; + node_0->layout.dimensions[CSSDimensionHeight] = 0; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 100; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_absolute_node_with_bottom_right) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.positionType = CSSPositionTypeAbsolute; + node_1->style.dimensions[CSSDimensionHeight] = 10; + node_1->style.position[CSSPositionBottom] = 0; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 0; + node_0->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 90; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 10; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_absolute_node_with_right_width) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 100; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.positionType = CSSPositionTypeAbsolute; + node_1->style.dimensions[CSSDimensionWidth] = 10; + node_1->style.position[CSSPositionRight] = 0; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 100; + node_0->layout.dimensions[CSSDimensionHeight] = 0; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 90; + node_1->layout.dimensions[CSSDimensionWidth] = 10; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_absolute_node_top_with_right_width_and_no_parent_dimension) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.positionType = CSSPositionTypeAbsolute; + node_1->style.dimensions[CSSDimensionHeight] = 10; + node_1->style.position[CSSPositionBottom] = 0; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 0; + node_0->layout.dimensions[CSSDimensionHeight] = 0; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = -10; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 10; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_absolute_node_left_with_right_width_and_no_parent_dimension) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.positionType = CSSPositionTypeAbsolute; + node_1->style.dimensions[CSSDimensionWidth] = 10; + node_1->style.position[CSSPositionRight] = 0; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 0; + node_0->layout.dimensions[CSSDimensionHeight] = 0; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = -10; + node_1->layout.dimensions[CSSDimensionWidth] = 10; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_with_border_bottom__insidejustifyContent_space_between_container) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.justifyContent = CSSJustifySpaceBetween; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.border[CSSPositionBottom] = 1; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 0; + node_0->layout.dimensions[CSSDimensionHeight] = 1; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 1; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_with_negative_margin_top_inside_justifyContent_center_container) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.justifyContent = CSSJustifyCenter; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.margin[CSSPositionTop] = -6; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 0; + node_0->layout.dimensions[CSSDimensionHeight] = 0; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = -3; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_with_margin_top_inside_justifyContent_center_container) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.justifyContent = CSSJustifyCenter; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.margin[CSSPositionTop] = 20; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 0; + node_0->layout.dimensions[CSSDimensionHeight] = 20; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 20; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_with_border_bottom_and_flex_end_with_empty_child) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.justifyContent = CSSJustifyFlexEnd; + node_0->style.border[CSSPositionBottom] = 5; + init_css_node_children(node_0, 1); + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 0; + node_0->layout.dimensions[CSSDimensionHeight] = 5; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_with_children_of_container_with_left) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 800; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.position[CSSPositionLeft] = 5; + init_css_node_children(node_1, 1); + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 800; + node_0->layout.dimensions[CSSDimensionHeight] = 0; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 5; + node_1->layout.dimensions[CSSDimensionWidth] = 800; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 0; + node_2->layout.position[CSSPositionLeft] = 0; + node_2->layout.dimensions[CSSDimensionWidth] = 800; + node_2->layout.dimensions[CSSDimensionHeight] = 0; + } + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_with_flexWrap) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.flexWrap = CSSWrapTypeWrap; + node_0->style.dimensions[CSSDimensionWidth] = 100; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 40; + node_1->style.dimensions[CSSDimensionHeight] = 10; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionWidth] = 40; + node_1->style.dimensions[CSSDimensionHeight] = 10; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->style.dimensions[CSSDimensionWidth] = 40; + node_1->style.dimensions[CSSDimensionHeight] = 10; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 100; + node_0->layout.dimensions[CSSDimensionHeight] = 20; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 40; + node_1->layout.dimensions[CSSDimensionHeight] = 10; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 40; + node_1->layout.dimensions[CSSDimensionWidth] = 40; + node_1->layout.dimensions[CSSDimensionHeight] = 10; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->layout.position[CSSPositionTop] = 10; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 40; + node_1->layout.dimensions[CSSDimensionHeight] = 10; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_with_flexWrap_rtl) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.direction = CSSDirectionRTL; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.flexWrap = CSSWrapTypeWrap; + node_0->style.dimensions[CSSDimensionWidth] = 100; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 40; + node_1->style.dimensions[CSSDimensionHeight] = 10; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionWidth] = 40; + node_1->style.dimensions[CSSDimensionHeight] = 10; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->style.dimensions[CSSDimensionWidth] = 40; + node_1->style.dimensions[CSSDimensionHeight] = 10; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 100; + node_0->layout.dimensions[CSSDimensionHeight] = 20; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 60; + node_1->layout.dimensions[CSSDimensionWidth] = 40; + node_1->layout.dimensions[CSSDimensionHeight] = 10; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 20; + node_1->layout.dimensions[CSSDimensionWidth] = 40; + node_1->layout.dimensions[CSSDimensionHeight] = 10; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->layout.position[CSSPositionTop] = 10; + node_1->layout.position[CSSPositionLeft] = 60; + node_1->layout.dimensions[CSSDimensionWidth] = 40; + node_1->layout.dimensions[CSSDimensionHeight] = 10; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_with_flexWrap_and_line_bigger_than_container) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexWrap = CSSWrapTypeWrap; + node_0->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionHeight] = 200; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 0; + node_0->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_with_max_bounds) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 100; + node_0->style.dimensions[CSSDimensionHeight] = 200; + node_0->style.maxDimensions[CSSDimensionWidth] = 90; + node_0->style.maxDimensions[CSSDimensionHeight] = 190; + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 90; + node_0->layout.dimensions[CSSDimensionHeight] = 190; + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_with_min_bounds) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 100; + node_0->style.dimensions[CSSDimensionHeight] = 200; + node_0->style.minDimensions[CSSDimensionWidth] = 110; + node_0->style.minDimensions[CSSDimensionHeight] = 210; + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 110; + node_0->layout.dimensions[CSSDimensionHeight] = 210; + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_with_min_and_max_bounds) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 100; + node_0->style.dimensions[CSSDimensionHeight] = 200; + node_0->style.maxDimensions[CSSDimensionWidth] = 90; + node_0->style.maxDimensions[CSSDimensionHeight] = 190; + node_0->style.minDimensions[CSSDimensionWidth] = 110; + node_0->style.minDimensions[CSSDimensionHeight] = 210; + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 110; + node_0->layout.dimensions[CSSDimensionHeight] = 210; + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_with_min_and_max_bounds_and_width) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 100; + node_0->style.dimensions[CSSDimensionHeight] = 200; + node_0->style.maxDimensions[CSSDimensionWidth] = 80; + node_0->style.maxDimensions[CSSDimensionHeight] = 180; + node_0->style.minDimensions[CSSDimensionWidth] = 90; + node_0->style.minDimensions[CSSDimensionHeight] = 190; + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 90; + node_0->layout.dimensions[CSSDimensionHeight] = 190; + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_with_negative_min_bounds) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 100; + node_0->style.dimensions[CSSDimensionHeight] = 200; + node_0->style.minDimensions[CSSDimensionWidth] = -10; + node_0->style.minDimensions[CSSDimensionHeight] = -20; + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 100; + node_0->layout.dimensions[CSSDimensionHeight] = 200; + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_with_negative_max_bounds) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 100; + node_0->style.dimensions[CSSDimensionHeight] = 200; + node_0->style.maxDimensions[CSSDimensionWidth] = -10; + node_0->style.maxDimensions[CSSDimensionHeight] = -20; + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 100; + node_0->layout.dimensions[CSSDimensionHeight] = 200; + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_with_max_bounds_and_larger_padded_bounds) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.maxDimensions[CSSDimensionWidth] = 30; + node_0->style.maxDimensions[CSSDimensionHeight] = 10; + node_0->style.padding[CSSPositionLeft] = 20; + node_0->style.padding[CSSPositionTop] = 15; + node_0->style.padding[CSSPositionRight] = 20; + node_0->style.padding[CSSPositionBottom] = 15; + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 40; + node_0->layout.dimensions[CSSDimensionHeight] = 30; + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_with_min_bounds_and_smaller_padded_bounds) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.minDimensions[CSSDimensionWidth] = 50; + node_0->style.minDimensions[CSSDimensionHeight] = 40; + node_0->style.padding[CSSPositionLeft] = 20; + node_0->style.padding[CSSPositionTop] = 15; + node_0->style.padding[CSSPositionRight] = 20; + node_0->style.padding[CSSPositionBottom] = 15; + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 50; + node_0->layout.dimensions[CSSDimensionHeight] = 40; + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_min_bounds_and_flex) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.dimensions[CSSDimensionWidth] = 300; + node_0->style.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flex = 1; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.flex = 1; + node_1->style.minDimensions[CSSDimensionWidth] = 200; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->style.flex = 1; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 300; + node_0->layout.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 50; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 50; + node_1->layout.dimensions[CSSDimensionWidth] = 200; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 250; + node_1->layout.dimensions[CSSDimensionWidth] = 50; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_min_bounds_and_flex_rtl) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.direction = CSSDirectionRTL; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.dimensions[CSSDimensionWidth] = 300; + node_0->style.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flex = 1; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.flex = 1; + node_1->style.minDimensions[CSSDimensionWidth] = 200; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->style.flex = 1; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 300; + node_0->layout.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 250; + node_1->layout.dimensions[CSSDimensionWidth] = 50; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 50; + node_1->layout.dimensions[CSSDimensionWidth] = 200; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 50; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_with_flex_size_within_bounds) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.dimensions[CSSDimensionWidth] = 300; + node_0->style.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flex = 1; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.flex = 1; + node_1->style.maxDimensions[CSSDimensionWidth] = 110; + node_1->style.minDimensions[CSSDimensionWidth] = 90; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->style.flex = 1; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 300; + node_0->layout.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 100; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 200; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_with_flex_size_within_bounds_rtl) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.direction = CSSDirectionRTL; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.dimensions[CSSDimensionWidth] = 300; + node_0->style.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flex = 1; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.flex = 1; + node_1->style.maxDimensions[CSSDimensionWidth] = 110; + node_1->style.minDimensions[CSSDimensionWidth] = 90; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->style.flex = 1; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 300; + node_0->layout.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 200; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 100; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_max_bounds_and_flex) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.dimensions[CSSDimensionWidth] = 300; + node_0->style.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flex = 1; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.flex = 1; + node_1->style.maxDimensions[CSSDimensionWidth] = 60; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->style.flex = 1; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 300; + node_0->layout.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 120; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 120; + node_1->layout.dimensions[CSSDimensionWidth] = 60; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 180; + node_1->layout.dimensions[CSSDimensionWidth] = 120; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_max_bounds_and_flex_rtl) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.direction = CSSDirectionRTL; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.dimensions[CSSDimensionWidth] = 300; + node_0->style.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flex = 1; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.flex = 1; + node_1->style.maxDimensions[CSSDimensionWidth] = 60; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->style.flex = 1; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 300; + node_0->layout.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 180; + node_1->layout.dimensions[CSSDimensionWidth] = 120; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 120; + node_1->layout.dimensions[CSSDimensionWidth] = 60; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 120; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_all_children_max_bounds_and_flex) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.dimensions[CSSDimensionWidth] = 300; + node_0->style.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flex = 1; + node_1->style.maxDimensions[CSSDimensionWidth] = 60; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.flex = 1; + node_1->style.maxDimensions[CSSDimensionWidth] = 60; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->style.flex = 1; + node_1->style.maxDimensions[CSSDimensionWidth] = 60; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 300; + node_0->layout.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 60; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 60; + node_1->layout.dimensions[CSSDimensionWidth] = 60; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 120; + node_1->layout.dimensions[CSSDimensionWidth] = 60; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_all_children_max_bounds_and_flex_rtl) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.direction = CSSDirectionRTL; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.dimensions[CSSDimensionWidth] = 300; + node_0->style.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flex = 1; + node_1->style.maxDimensions[CSSDimensionWidth] = 60; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.flex = 1; + node_1->style.maxDimensions[CSSDimensionWidth] = 60; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->style.flex = 1; + node_1->style.maxDimensions[CSSDimensionWidth] = 60; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 300; + node_0->layout.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 240; + node_1->layout.dimensions[CSSDimensionWidth] = 60; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 180; + node_1->layout.dimensions[CSSDimensionWidth] = 60; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 120; + node_1->layout.dimensions[CSSDimensionWidth] = 60; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_all_children_min_bounds_and_flex) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.dimensions[CSSDimensionWidth] = 300; + node_0->style.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flex = 1; + node_1->style.minDimensions[CSSDimensionWidth] = 120; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.flex = 1; + node_1->style.minDimensions[CSSDimensionWidth] = 120; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->style.flex = 1; + node_1->style.minDimensions[CSSDimensionWidth] = 120; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 300; + node_0->layout.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 120; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 120; + node_1->layout.dimensions[CSSDimensionWidth] = 120; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 240; + node_1->layout.dimensions[CSSDimensionWidth] = 120; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_all_children_min_bounds_and_flex_rtl) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.direction = CSSDirectionRTL; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.dimensions[CSSDimensionWidth] = 300; + node_0->style.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flex = 1; + node_1->style.minDimensions[CSSDimensionWidth] = 120; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.flex = 1; + node_1->style.minDimensions[CSSDimensionWidth] = 120; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->style.flex = 1; + node_1->style.minDimensions[CSSDimensionWidth] = 120; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 300; + node_0->layout.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 180; + node_1->layout.dimensions[CSSDimensionWidth] = 120; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 60; + node_1->layout.dimensions[CSSDimensionWidth] = 120; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = -60; + node_1->layout.dimensions[CSSDimensionWidth] = 120; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_prefill_child_size_within_bounds) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 300; + node_0->style.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flex = 1; + node_1->style.maxDimensions[CSSDimensionWidth] = 310; + node_1->style.minDimensions[CSSDimensionWidth] = 290; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 300; + node_0->layout.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 300; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_prefill_child_size_within_max_bounds) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 300; + node_0->style.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flex = 1; + node_1->style.maxDimensions[CSSDimensionWidth] = 290; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 300; + node_0->layout.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 290; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_prefill_child_size_within_min_bounds) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 300; + node_0->style.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flex = 1; + node_1->style.minDimensions[CSSDimensionWidth] = 310; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 300; + node_0->layout.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 310; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_set_parent_size_based_on_bounded_children) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.maxDimensions[CSSDimensionWidth] = 300; + node_0->style.maxDimensions[CSSDimensionHeight] = 700; + node_0->style.minDimensions[CSSDimensionWidth] = 100; + node_0->style.minDimensions[CSSDimensionHeight] = 500; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 200; + node_1->style.dimensions[CSSDimensionHeight] = 300; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionWidth] = 200; + node_1->style.dimensions[CSSDimensionHeight] = 300; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 200; + node_0->layout.dimensions[CSSDimensionHeight] = 600; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 200; + node_1->layout.dimensions[CSSDimensionHeight] = 300; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 300; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 200; + node_1->layout.dimensions[CSSDimensionHeight] = 300; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_set_parent_size_based_on_max_bounded_children) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.maxDimensions[CSSDimensionWidth] = 100; + node_0->style.maxDimensions[CSSDimensionHeight] = 500; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 200; + node_1->style.dimensions[CSSDimensionHeight] = 300; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionWidth] = 200; + node_1->style.dimensions[CSSDimensionHeight] = 300; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 100; + node_0->layout.dimensions[CSSDimensionHeight] = 500; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 200; + node_1->layout.dimensions[CSSDimensionHeight] = 300; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 300; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 200; + node_1->layout.dimensions[CSSDimensionHeight] = 300; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_set_parent_size_based_on_min_bounded_children) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.minDimensions[CSSDimensionWidth] = 300; + node_0->style.minDimensions[CSSDimensionHeight] = 700; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 200; + node_1->style.dimensions[CSSDimensionHeight] = 300; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionWidth] = 200; + node_1->style.dimensions[CSSDimensionHeight] = 300; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 300; + node_0->layout.dimensions[CSSDimensionHeight] = 700; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 200; + node_1->layout.dimensions[CSSDimensionHeight] = 300; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 300; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 200; + node_1->layout.dimensions[CSSDimensionHeight] = 300; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_keep_stretched_size_within_bounds) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.alignItems = CSSAlignStretch; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1->style.maxDimensions[CSSDimensionWidth] = 1100; + node_1->style.maxDimensions[CSSDimensionHeight] = 110; + node_1->style.minDimensions[CSSDimensionWidth] = 900; + node_1->style.minDimensions[CSSDimensionHeight] = 90; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 1000; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_keep_stretched_size_within_max_bounds) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.alignItems = CSSAlignStretch; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1->style.maxDimensions[CSSDimensionWidth] = 900; + node_1->style.maxDimensions[CSSDimensionHeight] = 90; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 90; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 900; + node_1->layout.dimensions[CSSDimensionHeight] = 90; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_keep_stretched_size_within_min_bounds) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.alignItems = CSSAlignStretch; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1->style.minDimensions[CSSDimensionWidth] = 1100; + node_1->style.minDimensions[CSSDimensionHeight] = 110; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 110; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 1100; + node_1->layout.dimensions[CSSDimensionHeight] = 110; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_keep_cross_axis_within_min_bounds) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1->style.minDimensions[CSSDimensionWidth] = 100; + node_1->style.minDimensions[CSSDimensionHeight] = 110; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 110; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 110; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_keep_cross_axis_within_min_bounds_rtl) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.direction = CSSDirectionRTL; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1->style.minDimensions[CSSDimensionWidth] = 100; + node_1->style.minDimensions[CSSDimensionHeight] = 110; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 110; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 900; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 110; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_absolute_node_with_top_left_max_bounds) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.positionType = CSSPositionTypeAbsolute; + node_1->style.maxDimensions[CSSDimensionWidth] = 500; + node_1->style.maxDimensions[CSSDimensionHeight] = 600; + node_1->style.position[CSSPositionLeft] = 100; + node_1->style.position[CSSPositionTop] = 100; + node_1->style.position[CSSPositionRight] = 100; + node_1->style.position[CSSPositionBottom] = 100; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 100; + node_1->layout.position[CSSPositionLeft] = 100; + node_1->layout.dimensions[CSSDimensionWidth] = 500; + node_1->layout.dimensions[CSSDimensionHeight] = 600; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_absolute_node_with_top_left_min_bounds) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.positionType = CSSPositionTypeAbsolute; + node_1->style.minDimensions[CSSDimensionWidth] = 900; + node_1->style.minDimensions[CSSDimensionHeight] = 1000; + node_1->style.position[CSSPositionLeft] = 100; + node_1->style.position[CSSPositionTop] = 100; + node_1->style.position[CSSPositionRight] = 100; + node_1->style.position[CSSPositionBottom] = 100; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 100; + node_1->layout.position[CSSPositionLeft] = 100; + node_1->layout.dimensions[CSSDimensionWidth] = 900; + node_1->layout.dimensions[CSSDimensionHeight] = 1000; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_center_flex_item_with_max_size) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.justifyContent = CSSJustifyCenter; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flex = 1; + node_1->style.dimensions[CSSDimensionHeight] = 1000; + node_1->style.maxDimensions[CSSDimensionWidth] = 600; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 200; + node_1->layout.dimensions[CSSDimensionWidth] = 600; + node_1->layout.dimensions[CSSDimensionHeight] = 1000; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_correctly_size_flex_items_with_flexBasis_and_max_width) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.dimensions[CSSDimensionWidth] = 1000; + node_0->style.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flex = 1; + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 1000; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.flex = 1; + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 1000; + node_1->style.maxDimensions[CSSDimensionWidth] = 200; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 1000; + node_0->layout.dimensions[CSSDimensionHeight] = 1000; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 800; + node_1->layout.dimensions[CSSDimensionHeight] = 1000; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 800; + node_1->layout.dimensions[CSSDimensionWidth] = 200; + node_1->layout.dimensions[CSSDimensionHeight] = 1000; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_absolute_node_with_absolute_parent) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 400; + node_0->style.dimensions[CSSDimensionHeight] = 400; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.positionType = CSSPositionTypeAbsolute; + node_1->style.padding[CSSPositionLeft] = 10; + node_1->style.padding[CSSPositionTop] = 10; + node_1->style.padding[CSSPositionRight] = 10; + node_1->style.padding[CSSPositionBottom] = 10; + node_1->style.padding[CSSPositionStart] = 10; + node_1->style.padding[CSSPositionEnd] = 10; + node_1->style.position[CSSPositionLeft] = 100; + node_1->style.position[CSSPositionTop] = 100; + node_1->style.position[CSSPositionRight] = 100; + node_1->style.position[CSSPositionBottom] = 100; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->style.positionType = CSSPositionTypeAbsolute; + node_2->style.position[CSSPositionLeft] = 10; + node_2->style.position[CSSPositionTop] = 10; + node_2->style.position[CSSPositionRight] = 10; + node_2->style.position[CSSPositionBottom] = 10; + } + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 400; + node_0->layout.dimensions[CSSDimensionHeight] = 400; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 100; + node_1->layout.position[CSSPositionLeft] = 100; + node_1->layout.dimensions[CSSDimensionWidth] = 200; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 10; + node_2->layout.position[CSSPositionLeft] = 10; + node_2->layout.dimensions[CSSDimensionWidth] = 180; + node_2->layout.dimensions[CSSDimensionHeight] = 180; + } + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_absolute_node_with_absolute_parent_with_border) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 400; + node_0->style.dimensions[CSSDimensionHeight] = 400; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.positionType = CSSPositionTypeAbsolute; + node_1->style.padding[CSSPositionLeft] = 10; + node_1->style.padding[CSSPositionTop] = 10; + node_1->style.padding[CSSPositionRight] = 10; + node_1->style.padding[CSSPositionBottom] = 10; + node_1->style.padding[CSSPositionStart] = 10; + node_1->style.padding[CSSPositionEnd] = 10; + node_1->style.border[CSSPositionLeft] = 1; + node_1->style.border[CSSPositionTop] = 1; + node_1->style.border[CSSPositionRight] = 1; + node_1->style.border[CSSPositionBottom] = 1; + node_1->style.border[CSSPositionStart] = 1; + node_1->style.border[CSSPositionEnd] = 1; + node_1->style.position[CSSPositionLeft] = 100; + node_1->style.position[CSSPositionTop] = 100; + node_1->style.position[CSSPositionRight] = 100; + node_1->style.position[CSSPositionBottom] = 100; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->style.positionType = CSSPositionTypeAbsolute; + node_2->style.position[CSSPositionLeft] = 10; + node_2->style.position[CSSPositionTop] = 10; + node_2->style.position[CSSPositionRight] = 10; + node_2->style.position[CSSPositionBottom] = 10; + } + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 400; + node_0->layout.dimensions[CSSDimensionHeight] = 400; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 100; + node_1->layout.position[CSSPositionLeft] = 100; + node_1->layout.dimensions[CSSDimensionWidth] = 200; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 11; + node_2->layout.position[CSSPositionLeft] = 11; + node_2->layout.dimensions[CSSDimensionWidth] = 178; + node_2->layout.dimensions[CSSDimensionHeight] = 178; + } + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_absolute_node_with_parent_with_padding_and_flex) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 400; + node_0->style.dimensions[CSSDimensionHeight] = 400; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flex = 1; + node_1->style.padding[CSSPositionLeft] = 10; + node_1->style.padding[CSSPositionTop] = 10; + node_1->style.padding[CSSPositionRight] = 10; + node_1->style.padding[CSSPositionBottom] = 10; + node_1->style.padding[CSSPositionStart] = 10; + node_1->style.padding[CSSPositionEnd] = 10; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->style.positionType = CSSPositionTypeAbsolute; + node_2->style.position[CSSPositionLeft] = 10; + node_2->style.position[CSSPositionTop] = 10; + node_2->style.position[CSSPositionRight] = 10; + node_2->style.position[CSSPositionBottom] = 10; + } + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 400; + node_0->layout.dimensions[CSSDimensionHeight] = 400; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 400; + node_1->layout.dimensions[CSSDimensionHeight] = 400; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 10; + node_2->layout.position[CSSPositionLeft] = 10; + node_2->layout.dimensions[CSSDimensionWidth] = 380; + node_2->layout.dimensions[CSSDimensionHeight] = 380; + } + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_nested_nodes_with_mixed_directions) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.direction = CSSDirectionRTL; + node_0->style.dimensions[CSSDimensionWidth] = 200; + node_0->style.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flexDirection = CSSFlexDirectionRow; + init_css_node_children(node_1, 2); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->style.dimensions[CSSDimensionWidth] = 50; + node_2->style.dimensions[CSSDimensionHeight] = 50; + node_2 = CSSNodeGetChild(node_1, 1); + node_2->style.dimensions[CSSDimensionWidth] = 50; + node_2->style.dimensions[CSSDimensionHeight] = 50; + } + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.direction = CSSDirectionLTR; + node_1->style.flexDirection = CSSFlexDirectionRow; + init_css_node_children(node_1, 2); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->style.dimensions[CSSDimensionWidth] = 50; + node_2->style.dimensions[CSSDimensionHeight] = 50; + node_2 = CSSNodeGetChild(node_1, 1); + node_2->style.dimensions[CSSDimensionWidth] = 50; + node_2->style.dimensions[CSSDimensionHeight] = 50; + } + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 200; + node_0->layout.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 200; + node_1->layout.dimensions[CSSDimensionHeight] = 50; + init_css_node_children(node_1, 2); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 0; + node_2->layout.position[CSSPositionLeft] = 150; + node_2->layout.dimensions[CSSDimensionWidth] = 50; + node_2->layout.dimensions[CSSDimensionHeight] = 50; + node_2 = CSSNodeGetChild(node_1, 1); + node_2->layout.position[CSSPositionTop] = 0; + node_2->layout.position[CSSPositionLeft] = 100; + node_2->layout.dimensions[CSSDimensionWidth] = 50; + node_2->layout.dimensions[CSSDimensionHeight] = 50; + } + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 50; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 200; + node_1->layout.dimensions[CSSDimensionHeight] = 50; + init_css_node_children(node_1, 2); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 0; + node_2->layout.position[CSSPositionLeft] = 0; + node_2->layout.dimensions[CSSDimensionWidth] = 50; + node_2->layout.dimensions[CSSDimensionHeight] = 50; + node_2 = CSSNodeGetChild(node_1, 1); + node_2->layout.position[CSSPositionTop] = 0; + node_2->layout.position[CSSPositionLeft] = 50; + node_2->layout.dimensions[CSSDimensionWidth] = 50; + node_2->layout.dimensions[CSSDimensionHeight] = 50; + } + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_correctly_space_wrapped_nodes) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.justifyContent = CSSJustifySpaceBetween; + node_0->style.flexWrap = CSSWrapTypeWrap; + node_0->style.dimensions[CSSDimensionWidth] = 320; + node_0->style.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_0, 6); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 3); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 4); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 5); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 100; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 320; + node_0->layout.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_0, 6); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 110; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 220; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 3); + node_1->layout.position[CSSPositionTop] = 100; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 4); + node_1->layout.position[CSSPositionTop] = 100; + node_1->layout.position[CSSPositionLeft] = 110; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 5); + node_1->layout.position[CSSPositionTop] = 100; + node_1->layout.position[CSSPositionLeft] = 220; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_prefer_start_end_padding) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 200; + node_0->style.padding[CSSPositionLeft] = 5; + node_0->style.padding[CSSPositionRight] = 5; + node_0->style.padding[CSSPositionStart] = 15; + node_0->style.padding[CSSPositionEnd] = 15; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionHeight] = 50; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 200; + node_0->layout.dimensions[CSSDimensionHeight] = 50; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 15; + node_1->layout.dimensions[CSSDimensionWidth] = 170; + node_1->layout.dimensions[CSSDimensionHeight] = 50; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_prefer_start_end_margin) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 200; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionHeight] = 50; + node_1->style.margin[CSSPositionLeft] = 5; + node_1->style.margin[CSSPositionRight] = 5; + node_1->style.margin[CSSPositionStart] = 15; + node_1->style.margin[CSSPositionEnd] = 15; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 200; + node_0->layout.dimensions[CSSDimensionHeight] = 50; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 15; + node_1->layout.dimensions[CSSDimensionWidth] = 170; + node_1->layout.dimensions[CSSDimensionHeight] = 50; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_prefer_start_end_border) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 200; + node_0->style.border[CSSPositionLeft] = 5; + node_0->style.border[CSSPositionRight] = 5; + node_0->style.border[CSSPositionStart] = 15; + node_0->style.border[CSSPositionEnd] = 15; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionHeight] = 50; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 200; + node_0->layout.dimensions[CSSDimensionHeight] = 50; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 15; + node_1->layout.dimensions[CSSDimensionWidth] = 170; + node_1->layout.dimensions[CSSDimensionHeight] = 50; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_with_start_end_padding) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 200; + node_0->style.padding[CSSPositionStart] = 15; + node_0->style.padding[CSSPositionEnd] = 5; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionHeight] = 50; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 200; + node_0->layout.dimensions[CSSDimensionHeight] = 50; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 15; + node_1->layout.dimensions[CSSDimensionWidth] = 180; + node_1->layout.dimensions[CSSDimensionHeight] = 50; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_with_start_end_padding_rtl) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.direction = CSSDirectionRTL; + node_0->style.dimensions[CSSDimensionWidth] = 200; + node_0->style.padding[CSSPositionStart] = 15; + node_0->style.padding[CSSPositionEnd] = 5; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionHeight] = 50; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 200; + node_0->layout.dimensions[CSSDimensionHeight] = 50; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 5; + node_1->layout.dimensions[CSSDimensionWidth] = 180; + node_1->layout.dimensions[CSSDimensionHeight] = 50; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_with_start_end_margin) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 200; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionHeight] = 50; + node_1->style.margin[CSSPositionStart] = 15; + node_1->style.margin[CSSPositionEnd] = 5; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 200; + node_0->layout.dimensions[CSSDimensionHeight] = 50; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 15; + node_1->layout.dimensions[CSSDimensionWidth] = 180; + node_1->layout.dimensions[CSSDimensionHeight] = 50; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_with_start_end_margin_rtl) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 200; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.direction = CSSDirectionRTL; + node_1->style.dimensions[CSSDimensionHeight] = 50; + node_1->style.margin[CSSPositionStart] = 15; + node_1->style.margin[CSSPositionEnd] = 5; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 200; + node_0->layout.dimensions[CSSDimensionHeight] = 50; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 5; + node_1->layout.dimensions[CSSDimensionWidth] = 180; + node_1->layout.dimensions[CSSDimensionHeight] = 50; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_with_start_end_border) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 200; + node_0->style.border[CSSPositionStart] = 15; + node_0->style.border[CSSPositionEnd] = 5; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionHeight] = 50; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 200; + node_0->layout.dimensions[CSSDimensionHeight] = 50; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 15; + node_1->layout.dimensions[CSSDimensionWidth] = 180; + node_1->layout.dimensions[CSSDimensionHeight] = 50; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_with_start_end_border_rtl) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.direction = CSSDirectionRTL; + node_0->style.dimensions[CSSDimensionWidth] = 200; + node_0->style.border[CSSPositionStart] = 15; + node_0->style.border[CSSPositionEnd] = 5; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionHeight] = 50; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 200; + node_0->layout.dimensions[CSSDimensionHeight] = 50; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 5; + node_1->layout.dimensions[CSSDimensionWidth] = 180; + node_1->layout.dimensions[CSSDimensionHeight] = 50; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_with_zero_width) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 200; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 0; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 200; + node_0->layout.dimensions[CSSDimensionHeight] = 0; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_propagate_size_contraints_from_flex_parent) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.alignItems = CSSAlignFlexStart; + node_0->style.dimensions[CSSDimensionWidth] = 100; + node_0->style.dimensions[CSSDimensionHeight] = 10; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 50; + node_1->style.dimensions[CSSDimensionHeight] = 10; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.flexDirection = CSSFlexDirectionColumn; + node_1->style.alignItems = CSSAlignFlexStart; + node_1->style.flex = 1; + node_1->style.dimensions[CSSDimensionHeight] = 10; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->style.flex = 1; + node_2->style.dimensions[CSSDimensionHeight] = 10; + node_2->measure = measure; + node_2->context = (char *) MEASURE_WITH_MATCH_PARENT; + } + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 100; + node_0->layout.dimensions[CSSDimensionHeight] = 10; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 50; + node_1->layout.dimensions[CSSDimensionHeight] = 10; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 50; + node_1->layout.dimensions[CSSDimensionWidth] = 50; + node_1->layout.dimensions[CSSDimensionHeight] = 10; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 0; + node_2->layout.position[CSSPositionLeft] = 0; + node_2->layout.dimensions[CSSDimensionWidth] = 50; + node_2->layout.dimensions[CSSDimensionHeight] = 10; + } + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_content_of_item_stretched_late) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.alignItems = CSSAlignStretch; + node_0->style.dimensions[CSSDimensionWidth] = 150; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flexDirection = CSSFlexDirectionRow; + node_1->style.margin[CSSPositionLeft] = 10; + node_1->style.margin[CSSPositionTop] = 10; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->style.flexDirection = CSSFlexDirectionRow; + init_css_node_children(node_2, 1); + { + CSSNode *node_3; + node_3 = CSSNodeGetChild(node_2, 0); + node_3->style.alignSelf = CSSAlignCenter; + } + } + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionHeight] = 150; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 150; + node_0->layout.dimensions[CSSDimensionHeight] = 150; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 10; + node_1->layout.position[CSSPositionLeft] = 10; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 140; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 0; + node_2->layout.position[CSSPositionLeft] = 0; + node_2->layout.dimensions[CSSDimensionWidth] = 0; + node_2->layout.dimensions[CSSDimensionHeight] = 140; + init_css_node_children(node_2, 1); + { + CSSNode *node_3; + node_3 = CSSNodeGetChild(node_2, 0); + node_3->layout.position[CSSPositionTop] = 70; + node_3->layout.position[CSSPositionLeft] = 0; + node_3->layout.dimensions[CSSDimensionWidth] = 0; + node_3->layout.dimensions[CSSDimensionHeight] = 0; + } + } + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 10; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 150; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_with_sibling_dependent_position) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->style.dimensions[CSSDimensionWidth] = 200; + node_2->style.dimensions[CSSDimensionHeight] = 200; + } + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.margin[CSSPositionLeft] = 10; + node_1->style.margin[CSSPositionTop] = 10; + init_css_node_children(node_1, 1); + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 200; + node_0->layout.dimensions[CSSDimensionHeight] = 210; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 200; + node_1->layout.dimensions[CSSDimensionHeight] = 200; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 0; + node_2->layout.position[CSSPositionLeft] = 0; + node_2->layout.dimensions[CSSDimensionWidth] = 200; + node_2->layout.dimensions[CSSDimensionHeight] = 200; + } + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 210; + node_1->layout.position[CSSPositionLeft] = 10; + node_1->layout.dimensions[CSSDimensionWidth] = 190; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 0; + node_2->layout.position[CSSPositionLeft] = 0; + node_2->layout.dimensions[CSSDimensionWidth] = 190; + node_2->layout.dimensions[CSSDimensionHeight] = 0; + } + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_node_undefined_cross_axis_and_alignSelf_stretch) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionRow; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.alignSelf = CSSAlignFlexStart; + node_1->style.margin[CSSPositionLeft] = 10; + node_1->style.margin[CSSPositionTop] = 10; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.alignSelf = CSSAlignStretch; + node_1->style.dimensions[CSSDimensionWidth] = 1; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->style.dimensions[CSSDimensionHeight] = 150; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 11; + node_0->layout.dimensions[CSSDimensionHeight] = 150; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 10; + node_1->layout.position[CSSPositionLeft] = 10; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 0; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 10; + node_1->layout.dimensions[CSSDimensionWidth] = 1; + node_1->layout.dimensions[CSSDimensionHeight] = 150; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 11; + node_1->layout.dimensions[CSSDimensionWidth] = 0; + node_1->layout.dimensions[CSSDimensionHeight] = 150; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_center_items_within_stretched_layout) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionRow; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->style.dimensions[CSSDimensionWidth] = 100; + node_2->style.dimensions[CSSDimensionHeight] = 100; + } + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionWidth] = 100; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->style.flexDirection = CSSFlexDirectionColumn; + node_2->style.alignItems = CSSAlignCenter; + init_css_node_children(node_2, 1); + { + CSSNode *node_3; + node_3 = CSSNodeGetChild(node_2, 0); + node_3->style.dimensions[CSSDimensionWidth] = 50; + node_3->style.dimensions[CSSDimensionHeight] = 50; + } + } + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 200; + node_0->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 2); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 0; + node_2->layout.position[CSSPositionLeft] = 0; + node_2->layout.dimensions[CSSDimensionWidth] = 100; + node_2->layout.dimensions[CSSDimensionHeight] = 100; + } + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 100; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 0; + node_2->layout.position[CSSPositionLeft] = 0; + node_2->layout.dimensions[CSSDimensionWidth] = 100; + node_2->layout.dimensions[CSSDimensionHeight] = 50; + init_css_node_children(node_2, 1); + { + CSSNode *node_3; + node_3 = CSSNodeGetChild(node_2, 0); + node_3->layout.position[CSSPositionTop] = 0; + node_3->layout.position[CSSPositionLeft] = 25; + node_3->layout.dimensions[CSSDimensionWidth] = 50; + node_3->layout.dimensions[CSSDimensionHeight] = 50; + } + } + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_not_shrink_column_node_when_there_is_space_left_over) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 100; + node_0->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flex = -1; + node_1->style.dimensions[CSSDimensionWidth] = 100; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->style.dimensions[CSSDimensionWidth] = 100; + node_2->style.dimensions[CSSDimensionHeight] = 25; + } + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 100; + node_0->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 25; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 0; + node_2->layout.position[CSSPositionLeft] = 0; + node_2->layout.dimensions[CSSDimensionWidth] = 100; + node_2->layout.dimensions[CSSDimensionHeight] = 25; + } + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_shrink_column_node_when_there_is_no_space_left_over) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 100; + node_0->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flex = -1; + node_1->style.dimensions[CSSDimensionWidth] = 100; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->style.dimensions[CSSDimensionWidth] = 100; + node_2->style.dimensions[CSSDimensionHeight] = 200; + } + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 100; + node_0->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 0; + node_2->layout.position[CSSPositionLeft] = 0; + node_2->layout.dimensions[CSSDimensionWidth] = 100; + node_2->layout.dimensions[CSSDimensionHeight] = 200; + } + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_not_shrink_column_node_with_siblings_when_there_is_space_left_over) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 100; + node_0->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 25; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.flex = -1; + node_1->style.dimensions[CSSDimensionWidth] = 100; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->style.dimensions[CSSDimensionWidth] = 100; + node_2->style.dimensions[CSSDimensionHeight] = 30; + } + node_1 = CSSNodeGetChild(node_0, 2); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 15; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 100; + node_0->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 25; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 25; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 30; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 0; + node_2->layout.position[CSSPositionLeft] = 0; + node_2->layout.dimensions[CSSDimensionWidth] = 100; + node_2->layout.dimensions[CSSDimensionHeight] = 30; + } + node_1 = CSSNodeGetChild(node_0, 2); + node_1->layout.position[CSSPositionTop] = 55; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 15; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_shrink_column_node_with_siblings_when_there_is_no_space_left_over) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 100; + node_0->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 25; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.flex = -1; + node_1->style.dimensions[CSSDimensionWidth] = 100; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->style.dimensions[CSSDimensionWidth] = 100; + node_2->style.dimensions[CSSDimensionHeight] = 80; + } + node_1 = CSSNodeGetChild(node_0, 2); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 15; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 100; + node_0->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 25; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 25; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 60; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 0; + node_2->layout.position[CSSPositionLeft] = 0; + node_2->layout.dimensions[CSSDimensionWidth] = 100; + node_2->layout.dimensions[CSSDimensionHeight] = 80; + } + node_1 = CSSNodeGetChild(node_0, 2); + node_1->layout.position[CSSPositionTop] = 85; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 15; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_shrink_column_nodes_proporional_to_their_main_size_when_there_is_no_space_left_over) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.dimensions[CSSDimensionWidth] = 100; + node_0->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flex = -1; + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 30; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 40; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->style.flex = -1; + node_1->style.dimensions[CSSDimensionWidth] = 100; + node_1->style.dimensions[CSSDimensionHeight] = 50; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 100; + node_0->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 22.5; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 22.5; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 40; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->layout.position[CSSPositionTop] = 62.5; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 37.5; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_not_shrink_visible_row_node_when_there_is_space_left_over) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.dimensions[CSSDimensionWidth] = 100; + node_0->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flex = -1; + node_1->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->style.dimensions[CSSDimensionWidth] = 25; + node_2->style.dimensions[CSSDimensionHeight] = 100; + } + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 100; + node_0->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 25; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 0; + node_2->layout.position[CSSPositionLeft] = 0; + node_2->layout.dimensions[CSSDimensionWidth] = 25; + node_2->layout.dimensions[CSSDimensionHeight] = 100; + } + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_shrink_visible_row_node_when_there_is_no_space_left_over) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.dimensions[CSSDimensionWidth] = 100; + node_0->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flex = -1; + node_1->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->style.dimensions[CSSDimensionWidth] = 200; + node_2->style.dimensions[CSSDimensionHeight] = 100; + } + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 100; + node_0->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 0; + node_2->layout.position[CSSPositionLeft] = 0; + node_2->layout.dimensions[CSSDimensionWidth] = 200; + node_2->layout.dimensions[CSSDimensionHeight] = 100; + } + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_not_shrink_visible_row_node_with_siblings_when_there_is_space_left_over) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.dimensions[CSSDimensionWidth] = 100; + node_0->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 25; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.flex = -1; + node_1->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->style.dimensions[CSSDimensionWidth] = 30; + node_2->style.dimensions[CSSDimensionHeight] = 100; + } + node_1 = CSSNodeGetChild(node_0, 2); + node_1->style.dimensions[CSSDimensionWidth] = 15; + node_1->style.dimensions[CSSDimensionHeight] = 100; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 100; + node_0->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 25; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 25; + node_1->layout.dimensions[CSSDimensionWidth] = 30; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 0; + node_2->layout.position[CSSPositionLeft] = 0; + node_2->layout.dimensions[CSSDimensionWidth] = 30; + node_2->layout.dimensions[CSSDimensionHeight] = 100; + } + node_1 = CSSNodeGetChild(node_0, 2); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 55; + node_1->layout.dimensions[CSSDimensionWidth] = 15; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_shrink_visible_row_node_with_siblings_when_there_is_no_space_left_over) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.dimensions[CSSDimensionWidth] = 100; + node_0->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 25; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.flex = -1; + node_1->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->style.dimensions[CSSDimensionWidth] = 80; + node_2->style.dimensions[CSSDimensionHeight] = 100; + } + node_1 = CSSNodeGetChild(node_0, 2); + node_1->style.dimensions[CSSDimensionWidth] = 15; + node_1->style.dimensions[CSSDimensionHeight] = 100; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 100; + node_0->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 25; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 25; + node_1->layout.dimensions[CSSDimensionWidth] = 60; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 0; + node_2->layout.position[CSSPositionLeft] = 0; + node_2->layout.dimensions[CSSDimensionWidth] = 80; + node_2->layout.dimensions[CSSDimensionHeight] = 100; + } + node_1 = CSSNodeGetChild(node_0, 2); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 85; + node_1->layout.dimensions[CSSDimensionWidth] = 15; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_shrink_visible_row_nodes_when_there_is_no_space_left_over) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.dimensions[CSSDimensionWidth] = 100; + node_0->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.flex = -1; + node_1->style.dimensions[CSSDimensionWidth] = 30; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionWidth] = 40; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->style.flex = -1; + node_1->style.dimensions[CSSDimensionWidth] = 50; + node_1->style.dimensions[CSSDimensionHeight] = 100; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 100; + node_0->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 22.5; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 22.5; + node_1->layout.dimensions[CSSDimensionWidth] = 40; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 62.5; + node_1->layout.dimensions[CSSDimensionWidth] = 37.5; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_not_shrink_hidden_row_node_when_there_is_space_left_over) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.dimensions[CSSDimensionWidth] = 100; + node_0->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.overflow = CSSOverflowHidden; + node_1->style.flex = -1; + node_1->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->style.dimensions[CSSDimensionWidth] = 25; + node_2->style.dimensions[CSSDimensionHeight] = 100; + } + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 100; + node_0->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 25; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 0; + node_2->layout.position[CSSPositionLeft] = 0; + node_2->layout.dimensions[CSSDimensionWidth] = 25; + node_2->layout.dimensions[CSSDimensionHeight] = 100; + } + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_shrink_hidden_row_node_when_there_is_no_space_left_over) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.dimensions[CSSDimensionWidth] = 100; + node_0->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.overflow = CSSOverflowHidden; + node_1->style.flex = -1; + node_1->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->style.dimensions[CSSDimensionWidth] = 200; + node_2->style.dimensions[CSSDimensionHeight] = 100; + } + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 100; + node_0->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 1); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 0; + node_2->layout.position[CSSPositionLeft] = 0; + node_2->layout.dimensions[CSSDimensionWidth] = 200; + node_2->layout.dimensions[CSSDimensionHeight] = 100; + } + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_not_shrink_hidden_row_node_with_siblings_when_there_is_space_left_over) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.dimensions[CSSDimensionWidth] = 100; + node_0->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 25; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.overflow = CSSOverflowHidden; + node_1->style.flex = -1; + node_1->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->style.dimensions[CSSDimensionWidth] = 30; + node_2->style.dimensions[CSSDimensionHeight] = 100; + } + node_1 = CSSNodeGetChild(node_0, 2); + node_1->style.dimensions[CSSDimensionWidth] = 15; + node_1->style.dimensions[CSSDimensionHeight] = 100; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 100; + node_0->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 25; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 25; + node_1->layout.dimensions[CSSDimensionWidth] = 30; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 0; + node_2->layout.position[CSSPositionLeft] = 0; + node_2->layout.dimensions[CSSDimensionWidth] = 30; + node_2->layout.dimensions[CSSDimensionHeight] = 100; + } + node_1 = CSSNodeGetChild(node_0, 2); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 55; + node_1->layout.dimensions[CSSDimensionWidth] = 15; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_shrink_hidden_row_node_with_siblings_when_there_is_no_space_left_over) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.dimensions[CSSDimensionWidth] = 100; + node_0->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 25; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.overflow = CSSOverflowHidden; + node_1->style.flex = -1; + node_1->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->style.dimensions[CSSDimensionWidth] = 80; + node_2->style.dimensions[CSSDimensionHeight] = 100; + } + node_1 = CSSNodeGetChild(node_0, 2); + node_1->style.dimensions[CSSDimensionWidth] = 15; + node_1->style.dimensions[CSSDimensionHeight] = 100; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 100; + node_0->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 25; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 25; + node_1->layout.dimensions[CSSDimensionWidth] = 60; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 0; + node_2->layout.position[CSSPositionLeft] = 0; + node_2->layout.dimensions[CSSDimensionWidth] = 80; + node_2->layout.dimensions[CSSDimensionHeight] = 100; + } + node_1 = CSSNodeGetChild(node_0, 2); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 85; + node_1->layout.dimensions[CSSDimensionWidth] = 15; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_shrink_hidden_row_nodes_propertional_to_main_size_when_there_is_no_space_left_over) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.dimensions[CSSDimensionWidth] = 100; + node_0->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.overflow = CSSOverflowHidden; + node_1->style.flex = -1; + node_1->style.dimensions[CSSDimensionWidth] = 30; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionWidth] = 40; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->style.overflow = CSSOverflowHidden; + node_1->style.flex = -1; + node_1->style.dimensions[CSSDimensionWidth] = 50; + node_1->style.dimensions[CSSDimensionHeight] = 100; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 100; + node_0->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 22.5; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 22.5; + node_1->layout.dimensions[CSSDimensionWidth] = 40; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 62.5; + node_1->layout.dimensions[CSSDimensionWidth] = 37.5; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_not_shrink_text_node_with_siblings_when_there_is_space_left_over) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.dimensions[CSSDimensionWidth] = 213; + node_0->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 25; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.flexDirection = CSSFlexDirectionRow; + node_1->style.alignItems = CSSAlignFlexStart; + node_1->style.flex = -1; + node_1->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->measure = measure; + node_2->context = (char *) LONG_TEXT; + } + node_1 = CSSNodeGetChild(node_0, 2); + node_1->style.dimensions[CSSDimensionWidth] = 15; + node_1->style.dimensions[CSSDimensionHeight] = 100; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 213; + node_0->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 25; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 25; + node_1->layout.dimensions[CSSDimensionWidth] = BIG_WIDTH; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 0; + node_2->layout.position[CSSPositionLeft] = 0; + node_2->layout.dimensions[CSSDimensionWidth] = BIG_WIDTH; + node_2->layout.dimensions[CSSDimensionHeight] = SMALL_HEIGHT; + } + node_1 = CSSNodeGetChild(node_0, 2); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 197; + node_1->layout.dimensions[CSSDimensionWidth] = 15; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_shrink_text_node_with_siblings_when_there_is_no_space_left_over) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.dimensions[CSSDimensionWidth] = 140; + node_0->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 25; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.flexDirection = CSSFlexDirectionRow; + node_1->style.alignItems = CSSAlignFlexStart; + node_1->style.flex = -1; + node_1->style.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->style.flex = -1; + node_2->measure = measure; + node_2->context = (char *) LONG_TEXT; + } + node_1 = CSSNodeGetChild(node_0, 2); + node_1->style.dimensions[CSSDimensionWidth] = 15; + node_1->style.dimensions[CSSDimensionHeight] = 100; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 140; + node_0->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_0, 3); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 0; + node_1->layout.dimensions[CSSDimensionWidth] = 25; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 25; + node_1->layout.dimensions[CSSDimensionWidth] = 100; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + init_css_node_children(node_1, 1); + { + CSSNode *node_2; + node_2 = CSSNodeGetChild(node_1, 0); + node_2->layout.position[CSSPositionTop] = 0; + node_2->layout.position[CSSPositionLeft] = 0; + node_2->layout.dimensions[CSSDimensionWidth] = 100; + node_2->layout.dimensions[CSSDimensionHeight] = BIG_HEIGHT; + } + node_1 = CSSNodeGetChild(node_0, 2); + node_1->layout.position[CSSPositionTop] = 0; + node_1->layout.position[CSSPositionLeft] = 125; + node_1->layout.dimensions[CSSDimensionWidth] = 15; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_should_layout_with_alignContent_stretch_and_alignItems_flex_start) { + CSSNode *root_node = new_test_css_node(); + { + CSSNode *node_0 = root_node; + node_0->style.flexDirection = CSSFlexDirectionRow; + node_0->style.alignContent = CSSAlignStretch; + node_0->style.alignItems = CSSAlignFlexStart; + node_0->style.flexWrap = CSSWrapTypeWrap; + node_0->style.dimensions[CSSDimensionWidth] = 300; + node_0->style.dimensions[CSSDimensionHeight] = 380; + init_css_node_children(node_0, 15); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->style.dimensions[CSSDimensionWidth] = 50; + node_1->style.dimensions[CSSDimensionHeight] = 50; + node_1->style.margin[CSSPositionLeft] = 10; + node_1->style.margin[CSSPositionTop] = 10; + node_1->style.margin[CSSPositionRight] = 10; + node_1->style.margin[CSSPositionBottom] = 10; + node_1->style.margin[CSSPositionStart] = 10; + node_1->style.margin[CSSPositionEnd] = 10; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->style.dimensions[CSSDimensionWidth] = 50; + node_1->style.dimensions[CSSDimensionHeight] = 50; + node_1->style.margin[CSSPositionLeft] = 10; + node_1->style.margin[CSSPositionTop] = 10; + node_1->style.margin[CSSPositionRight] = 10; + node_1->style.margin[CSSPositionBottom] = 10; + node_1->style.margin[CSSPositionStart] = 10; + node_1->style.margin[CSSPositionEnd] = 10; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->style.dimensions[CSSDimensionWidth] = 50; + node_1->style.dimensions[CSSDimensionHeight] = 50; + node_1->style.margin[CSSPositionLeft] = 10; + node_1->style.margin[CSSPositionTop] = 10; + node_1->style.margin[CSSPositionRight] = 10; + node_1->style.margin[CSSPositionBottom] = 10; + node_1->style.margin[CSSPositionStart] = 10; + node_1->style.margin[CSSPositionEnd] = 10; + node_1 = CSSNodeGetChild(node_0, 3); + node_1->style.dimensions[CSSDimensionWidth] = 50; + node_1->style.dimensions[CSSDimensionHeight] = 50; + node_1->style.margin[CSSPositionLeft] = 10; + node_1->style.margin[CSSPositionTop] = 10; + node_1->style.margin[CSSPositionRight] = 10; + node_1->style.margin[CSSPositionBottom] = 10; + node_1->style.margin[CSSPositionStart] = 10; + node_1->style.margin[CSSPositionEnd] = 10; + node_1 = CSSNodeGetChild(node_0, 4); + node_1->style.dimensions[CSSDimensionWidth] = 50; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1->style.margin[CSSPositionLeft] = 10; + node_1->style.margin[CSSPositionTop] = 10; + node_1->style.margin[CSSPositionRight] = 10; + node_1->style.margin[CSSPositionBottom] = 10; + node_1->style.margin[CSSPositionStart] = 10; + node_1->style.margin[CSSPositionEnd] = 10; + node_1 = CSSNodeGetChild(node_0, 5); + node_1->style.alignSelf = CSSAlignFlexStart; + node_1->style.dimensions[CSSDimensionWidth] = 50; + node_1->style.dimensions[CSSDimensionHeight] = 50; + node_1->style.margin[CSSPositionLeft] = 10; + node_1->style.margin[CSSPositionTop] = 10; + node_1->style.margin[CSSPositionRight] = 10; + node_1->style.margin[CSSPositionBottom] = 10; + node_1->style.margin[CSSPositionStart] = 10; + node_1->style.margin[CSSPositionEnd] = 10; + node_1 = CSSNodeGetChild(node_0, 6); + node_1->style.dimensions[CSSDimensionWidth] = 50; + node_1->style.dimensions[CSSDimensionHeight] = 50; + node_1->style.margin[CSSPositionLeft] = 10; + node_1->style.margin[CSSPositionTop] = 10; + node_1->style.margin[CSSPositionRight] = 10; + node_1->style.margin[CSSPositionBottom] = 10; + node_1->style.margin[CSSPositionStart] = 10; + node_1->style.margin[CSSPositionEnd] = 10; + node_1 = CSSNodeGetChild(node_0, 7); + node_1->style.dimensions[CSSDimensionWidth] = 50; + node_1->style.dimensions[CSSDimensionHeight] = 100; + node_1->style.margin[CSSPositionLeft] = 10; + node_1->style.margin[CSSPositionTop] = 10; + node_1->style.margin[CSSPositionRight] = 10; + node_1->style.margin[CSSPositionBottom] = 10; + node_1->style.margin[CSSPositionStart] = 10; + node_1->style.margin[CSSPositionEnd] = 10; + node_1 = CSSNodeGetChild(node_0, 8); + node_1->style.dimensions[CSSDimensionWidth] = 50; + node_1->style.dimensions[CSSDimensionHeight] = 50; + node_1->style.margin[CSSPositionLeft] = 10; + node_1->style.margin[CSSPositionTop] = 10; + node_1->style.margin[CSSPositionRight] = 10; + node_1->style.margin[CSSPositionBottom] = 10; + node_1->style.margin[CSSPositionStart] = 10; + node_1->style.margin[CSSPositionEnd] = 10; + node_1 = CSSNodeGetChild(node_0, 9); + node_1->style.dimensions[CSSDimensionWidth] = 50; + node_1->style.dimensions[CSSDimensionHeight] = 50; + node_1->style.margin[CSSPositionLeft] = 10; + node_1->style.margin[CSSPositionTop] = 10; + node_1->style.margin[CSSPositionRight] = 10; + node_1->style.margin[CSSPositionBottom] = 10; + node_1->style.margin[CSSPositionStart] = 10; + node_1->style.margin[CSSPositionEnd] = 10; + node_1 = CSSNodeGetChild(node_0, 10); + node_1->style.alignSelf = CSSAlignFlexStart; + node_1->style.dimensions[CSSDimensionWidth] = 50; + node_1->style.dimensions[CSSDimensionHeight] = 50; + node_1->style.margin[CSSPositionLeft] = 10; + node_1->style.margin[CSSPositionTop] = 10; + node_1->style.margin[CSSPositionRight] = 10; + node_1->style.margin[CSSPositionBottom] = 10; + node_1->style.margin[CSSPositionStart] = 10; + node_1->style.margin[CSSPositionEnd] = 10; + node_1 = CSSNodeGetChild(node_0, 11); + node_1->style.dimensions[CSSDimensionWidth] = 50; + node_1->style.dimensions[CSSDimensionHeight] = 50; + node_1->style.margin[CSSPositionLeft] = 10; + node_1->style.margin[CSSPositionTop] = 10; + node_1->style.margin[CSSPositionRight] = 10; + node_1->style.margin[CSSPositionBottom] = 10; + node_1->style.margin[CSSPositionStart] = 10; + node_1->style.margin[CSSPositionEnd] = 10; + node_1 = CSSNodeGetChild(node_0, 12); + node_1->style.dimensions[CSSDimensionWidth] = 50; + node_1->style.dimensions[CSSDimensionHeight] = 50; + node_1->style.margin[CSSPositionLeft] = 10; + node_1->style.margin[CSSPositionTop] = 10; + node_1->style.margin[CSSPositionRight] = 10; + node_1->style.margin[CSSPositionBottom] = 10; + node_1->style.margin[CSSPositionStart] = 10; + node_1->style.margin[CSSPositionEnd] = 10; + node_1 = CSSNodeGetChild(node_0, 13); + node_1->style.alignSelf = CSSAlignFlexStart; + node_1->style.dimensions[CSSDimensionWidth] = 50; + node_1->style.dimensions[CSSDimensionHeight] = 50; + node_1->style.margin[CSSPositionLeft] = 10; + node_1->style.margin[CSSPositionTop] = 10; + node_1->style.margin[CSSPositionRight] = 10; + node_1->style.margin[CSSPositionBottom] = 10; + node_1->style.margin[CSSPositionStart] = 10; + node_1->style.margin[CSSPositionEnd] = 10; + node_1 = CSSNodeGetChild(node_0, 14); + node_1->style.dimensions[CSSDimensionWidth] = 50; + node_1->style.dimensions[CSSDimensionHeight] = 50; + node_1->style.margin[CSSPositionLeft] = 10; + node_1->style.margin[CSSPositionTop] = 10; + node_1->style.margin[CSSPositionRight] = 10; + node_1->style.margin[CSSPositionBottom] = 10; + node_1->style.margin[CSSPositionStart] = 10; + node_1->style.margin[CSSPositionEnd] = 10; + } + } + + CSSNode *root_layout = new_test_css_node(); + { + CSSNode *node_0 = root_layout; + node_0->layout.position[CSSPositionTop] = 0; + node_0->layout.position[CSSPositionLeft] = 0; + node_0->layout.dimensions[CSSDimensionWidth] = 300; + node_0->layout.dimensions[CSSDimensionHeight] = 380; + init_css_node_children(node_0, 15); + { + CSSNode *node_1; + node_1 = CSSNodeGetChild(node_0, 0); + node_1->layout.position[CSSPositionTop] = 10; + node_1->layout.position[CSSPositionLeft] = 10; + node_1->layout.dimensions[CSSDimensionWidth] = 50; + node_1->layout.dimensions[CSSDimensionHeight] = 50; + node_1 = CSSNodeGetChild(node_0, 1); + node_1->layout.position[CSSPositionTop] = 10; + node_1->layout.position[CSSPositionLeft] = 80; + node_1->layout.dimensions[CSSDimensionWidth] = 50; + node_1->layout.dimensions[CSSDimensionHeight] = 50; + node_1 = CSSNodeGetChild(node_0, 2); + node_1->layout.position[CSSPositionTop] = 10; + node_1->layout.position[CSSPositionLeft] = 150; + node_1->layout.dimensions[CSSDimensionWidth] = 50; + node_1->layout.dimensions[CSSDimensionHeight] = 50; + node_1 = CSSNodeGetChild(node_0, 3); + node_1->layout.position[CSSPositionTop] = 10; + node_1->layout.position[CSSPositionLeft] = 220; + node_1->layout.dimensions[CSSDimensionWidth] = 50; + node_1->layout.dimensions[CSSDimensionHeight] = 50; + node_1 = CSSNodeGetChild(node_0, 4); + node_1->layout.position[CSSPositionTop] = 92.5; + node_1->layout.position[CSSPositionLeft] = 10; + node_1->layout.dimensions[CSSDimensionWidth] = 50; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 5); + node_1->layout.position[CSSPositionTop] = 92.5; + node_1->layout.position[CSSPositionLeft] = 80; + node_1->layout.dimensions[CSSDimensionWidth] = 50; + node_1->layout.dimensions[CSSDimensionHeight] = 50; + node_1 = CSSNodeGetChild(node_0, 6); + node_1->layout.position[CSSPositionTop] = 92.5; + node_1->layout.position[CSSPositionLeft] = 150; + node_1->layout.dimensions[CSSDimensionWidth] = 50; + node_1->layout.dimensions[CSSDimensionHeight] = 50; + node_1 = CSSNodeGetChild(node_0, 7); + node_1->layout.position[CSSPositionTop] = 92.5; + node_1->layout.position[CSSPositionLeft] = 220; + node_1->layout.dimensions[CSSDimensionWidth] = 50; + node_1->layout.dimensions[CSSDimensionHeight] = 100; + node_1 = CSSNodeGetChild(node_0, 8); + node_1->layout.position[CSSPositionTop] = 225; + node_1->layout.position[CSSPositionLeft] = 10; + node_1->layout.dimensions[CSSDimensionWidth] = 50; + node_1->layout.dimensions[CSSDimensionHeight] = 50; + node_1 = CSSNodeGetChild(node_0, 9); + node_1->layout.position[CSSPositionTop] = 225; + node_1->layout.position[CSSPositionLeft] = 80; + node_1->layout.dimensions[CSSDimensionWidth] = 50; + node_1->layout.dimensions[CSSDimensionHeight] = 50; + node_1 = CSSNodeGetChild(node_0, 10); + node_1->layout.position[CSSPositionTop] = 225; + node_1->layout.position[CSSPositionLeft] = 150; + node_1->layout.dimensions[CSSDimensionWidth] = 50; + node_1->layout.dimensions[CSSDimensionHeight] = 50; + node_1 = CSSNodeGetChild(node_0, 11); + node_1->layout.position[CSSPositionTop] = 225; + node_1->layout.position[CSSPositionLeft] = 220; + node_1->layout.dimensions[CSSDimensionWidth] = 50; + node_1->layout.dimensions[CSSDimensionHeight] = 50; + node_1 = CSSNodeGetChild(node_0, 12); + node_1->layout.position[CSSPositionTop] = 307.5; + node_1->layout.position[CSSPositionLeft] = 10; + node_1->layout.dimensions[CSSDimensionWidth] = 50; + node_1->layout.dimensions[CSSDimensionHeight] = 50; + node_1 = CSSNodeGetChild(node_0, 13); + node_1->layout.position[CSSPositionTop] = 307.5; + node_1->layout.position[CSSPositionLeft] = 80; + node_1->layout.dimensions[CSSDimensionWidth] = 50; + node_1->layout.dimensions[CSSDimensionHeight] = 50; + node_1 = CSSNodeGetChild(node_0, 14); + node_1->layout.position[CSSPositionTop] = 307.5; + node_1->layout.position[CSSPositionLeft] = 150; + node_1->layout.dimensions[CSSDimensionWidth] = 50; + node_1->layout.dimensions[CSSDimensionHeight] = 50; + } + } + + ASSERT_TRUE(test(root_node, root_layout)); +} + +TEST(CSSLayoutTest, test_dirty_node) { + CSSNode *root_node = new_test_css_node(); + ASSERT_FALSE(root_node->isDirty); + + CSSNodeStyleSetWidth(root_node, 100); + CSSNodeStyleSetHeight(root_node, 100); + ASSERT_TRUE(root_node->isDirty); + + CSSNodeCalculateLayout(root_node, 100, 100, CSSDirectionLTR); + ASSERT_FALSE(root_node->isDirty); +} diff --git a/tests/CSSLayoutTestUtils/CSSLayoutTestUtils.c b/tests/CSSLayoutTestUtils/CSSLayoutTestUtils.c new file mode 100644 index 00000000..0fa00f0e --- /dev/null +++ b/tests/CSSLayoutTestUtils/CSSLayoutTestUtils.c @@ -0,0 +1,121 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#include + +#include "CSSLayoutTestUtils.h" + +#ifdef _MSC_VER +#include +#define isnan _isnan + +/* define fmaxf & fminf if < VC12 */ +#if _MSC_VER < 1800 +__forceinline const float fmaxf(const float a, const float b) { + return (a > b) ? a : b; +} +__forceinline const float fminf(const float a, const float b) { + return (a < b) ? a : b; +} +#endif +#endif + +static bool eq(float a, float b) { + return fabs(a - b) < 0.0001; +} + +static bool are_layout_equal(CSSNode *a, CSSNode *b) { + if (!eq(a->layout.dimensions[CSSDimensionWidth], b->layout.dimensions[CSSDimensionWidth]) || + !eq(a->layout.dimensions[CSSDimensionHeight], b->layout.dimensions[CSSDimensionHeight]) || + !eq(a->layout.position[CSSPositionTop], b->layout.position[CSSPositionTop]) || + !eq(a->layout.position[CSSPositionLeft], b->layout.position[CSSPositionLeft]) || + !eq(CSSNodeChildCount(a), CSSNodeChildCount(b))) { + return false; + } + for (int i = 0; i < CSSNodeChildCount(a); ++i) { + if (!are_layout_equal(CSSNodeGetChild(a, i), CSSNodeGetChild(b, i))) { + return false; + } + } + return true; +} + +CSSSize measure(void *context, float width, CSSMeasureMode widthMode, float height, CSSMeasureMode heightMode) { + const char *text = (const char *)context; + CSSSize result; + if (strcmp(text, SMALL_TEXT) == 0) { + if (widthMode == CSSMeasureModeUndefined) { + width = 1000000; + } + result.width = fminf(SMALL_WIDTH, width); + result.height = SMALL_WIDTH > width ? BIG_HEIGHT : SMALL_HEIGHT; + return result; + } + if (strcmp(text, LONG_TEXT) == 0) { + if (widthMode == CSSMeasureModeUndefined) { + width = 1000000; + } + result.width = fminf(BIG_WIDTH, width); + result.height = BIG_WIDTH > width ? BIG_HEIGHT : SMALL_HEIGHT; + return result; + } + + if (strcmp(text, MEASURE_WITH_RATIO_2) == 0) { + if (widthMode == CSSMeasureModeExactly) { + result.width = width; + result.height = width * 2; + } else if (heightMode == CSSMeasureModeExactly) { + result.width = height * 2; + result.height = height; + } else if (widthMode == CSSMeasureModeAtMost) { + result.width = width; + result.height = width * 2; + } else if (heightMode == CSSMeasureModeAtMost) { + result.width = height * 2; + result.height = height; + } else { + result.width = 99999; + result.height = 99999; + } + return result; + } + + if (strcmp(text, MEASURE_WITH_MATCH_PARENT) == 0) { + if (widthMode == CSSMeasureModeUndefined) { + width = 99999; + } + if (heightMode == CSSMeasureModeUndefined) { + height = 99999; + } + result.width = width; + result.height = height; + return result; + } + + // Should not go here + result.width = CSSUndefined; + result.height = CSSUndefined; + return result; +} + +bool test(CSSNode *style, CSSNode *expected_layout) { + CSSNodeCalculateLayout(style, CSSUndefined, CSSUndefined, (CSSDirection)-1); + return are_layout_equal(style, expected_layout); +} + +CSSNode *new_test_css_node(void) { + CSSNode *node = CSSNodeNew(); + return node; +} + +void init_css_node_children(CSSNode *node, int childCount) { + for (int i = 0; i < childCount; ++i) { + CSSNodeInsertChild(node, new_test_css_node(), 0); + } +} diff --git a/tests/CSSLayoutTestUtils/CSSLayoutTestUtils.h b/tests/CSSLayoutTestUtils/CSSLayoutTestUtils.h new file mode 100644 index 00000000..11d410f6 --- /dev/null +++ b/tests/CSSLayoutTestUtils/CSSLayoutTestUtils.h @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#ifndef __CSS_LAYOUT_TEST_UTILS_H +#define __CSS_LAYOUT_TEST_UTILS_H + +#include +#include +#include + +#ifndef __cplusplus +#include +#endif + +#include +#include +#include + +#define SMALL_WIDTH 35 +#define SMALL_HEIGHT 18 +#define BIG_WIDTH 172 +#define BIG_HEIGHT 36 +#define SMALL_TEXT "small" +#define LONG_TEXT "loooooooooong with space" +#define MEASURE_WITH_RATIO_2 "measureWithRatio2" +#define MEASURE_WITH_MATCH_PARENT "measureWithMatchParent" + +CSS_EXTERN_C_BEGIN + +bool test(CSSNode *style, CSSNode *expected_layout); +CSSSize measure(void *context, float width, CSSMeasureMode widthMode, float height, CSSMeasureMode heightMode); +void init_css_node_children(CSSNode *node, int childCount); +CSSNode *new_test_css_node(void); + +CSS_EXTERN_C_END + +#endif diff --git a/tests/Layout-consts-test.js b/tests/Layout-consts-test.js deleted file mode 100644 index 7c489778..00000000 --- a/tests/Layout-consts-test.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ -/* globals layoutTestUtils */ - -var textSizes = layoutTestUtils.textSizes; -var preDefinedTextSizes = layoutTestUtils.preDefinedTextSizes; - -describe('Layout tests consts', function() { - it('keeps browser text measurements in sync with predefined consts', function() { - expect(preDefinedTextSizes).toEqual( - textSizes, - 'Looks like browser has updated its text measurements functions. ' + - 'You need to update `preDefinedTextSizes` in Layout-test-utils.js' - ); - }); -}); diff --git a/tests/Layout-random-test.js b/tests/Layout-random-test.js deleted file mode 100644 index 355a2779..00000000 --- a/tests/Layout-random-test.js +++ /dev/null @@ -1,122 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ -/* globals layoutTestUtils */ -var testRandomLayout = layoutTestUtils.testRandomLayout; -var computeLayout = layoutTestUtils.computeLayout; -var computeDOMLayout = layoutTestUtils.computeDOMLayout; -var reduceTest = layoutTestUtils.reduceTest; - -describe('Random layout', function() { - - function RNG(seed) { - this.state = seed; - } - RNG.prototype.nextFloat = function() { - // LCG using GCC's constants - this.state = (1103515245 * this.state + 12345) % 0x80000000; - return this.state / (0x80000000 - 1); - }; - - var rng = new RNG(0); - function randMinMax(node, chance, attribute, min, max) { - if (rng.nextFloat() < chance) { - if (attribute === 'right' || attribute === 'bottom') { - return; - } - node.style[attribute] = Math.floor(rng.nextFloat() * (max - min)) + min; - } - } - function randEnum(node, chance, attribute, enumValues) { - if (rng.nextFloat() < chance) { - node.style[attribute] = enumValues[Math.floor(rng.nextFloat() * enumValues.length)]; - } - } - - function randSpacing(node, chance, type, suffix, min, max) { - randMinMax(node, chance, type + suffix, min, max); - randMinMax(node, chance, type + 'Left' + suffix, min, max); - randMinMax(node, chance, type + 'Top' + suffix, min, max); - randMinMax(node, chance, type + 'Right' + suffix, min, max); - randMinMax(node, chance, type + 'Bottom' + suffix, min, max); - } - function generateRandomNode() { - var node = {style: {}}; - randMinMax(node, 0.5, 'width', -100, 1000); - randMinMax(node, 0.5, 'height', -100, 1000); - randMinMax(node, 0.5, 'minWidth', -100, 1000); - randMinMax(node, 0.5, 'minHeight', -100, 1000); - randMinMax(node, 0.5, 'maxWidth', -100, 1000); - randMinMax(node, 0.5, 'maxHeight', -100, 1000); - randMinMax(node, 0.5, 'top', -10, 10); - randMinMax(node, 0.5, 'left', -10, 10); - randMinMax(node, 0.5, 'right', -10, 10); - randMinMax(node, 0.5, 'bottom', -10, 10); - randSpacing(node, 0.5, 'margin', '', -10, 20); - randSpacing(node, 0.5, 'padding', '', -10, 20); - randSpacing(node, 0.5, 'border', 'Width', -4, 4); - randMinMax(node, 0.5, 'flex', -10, 10); - randEnum(node, 0.5, 'flexDirection', ['column', 'row']); - randEnum(node, 0.5, 'justifyContent', ['flex-start', 'center', 'flex-end', 'space-between', 'space-around']); - randEnum(node, 0.5, 'alignItems', ['flex-start', 'center', 'flex-end', 'stretch']); - randEnum(node, 0.5, 'alignSelf', ['flex-start', 'center', 'flex-end', 'stretch']); - randEnum(node, 0.5, 'alignContent', ['flex-start', 'center', 'flex-end', 'stretch']); - randEnum(node, 0.5, 'position', ['relative', 'absolute']); - randEnum(node, 0.5, 'flexWrap', ['nowrap', 'wrap']); - //randEnum(node, 0.5, 'measure', [text(texts.small), text(texts.big)]); - - // Chrome is doing some very weird things with this. Probably not worth supporting - if (node.style.flex === 0) { - delete node.style.flex; - } - - if (node.style.measure) { - // align-items: stretch on a text node makes it wrap in a different way. - // We don't yet support this use case - delete node.style.alignItems; - - // Text that is position: absolute behaves very strangely - delete node.style.position; - } - - function randChildren(node, chance) { - while (rng.nextFloat() < chance) { - if (!node.children) { - node.children = []; - } - node.children.push(generateRandomNode()); - } - } - - randChildren(node, 0.4); - return node; - } - - function checkRandomLayout(i, node) { - it('should layout randomly #' + i + '.', function(node) { - if (JSON.stringify(computeLayout(node)) !== JSON.stringify(computeDOMLayout(node))) { - node = reduceTest(node); - } - - testRandomLayout(node, i); - }.bind(this, node)); - } - - for (var i = 0; i < 100; ++i) { - var node = generateRandomNode(); - // The iframe's body has a natural width of 300 that it doesn't really make - // to replicate in the test suite. The easiest workaround is not to test - // alignSelf, position and flex properties on the root element. - delete node.style.alignSelf; - delete node.style.flex; - delete node.style.position; - - checkRandomLayout.call(this, i, node); - } - -}); diff --git a/tests/Layout-test.c b/tests/Layout-test.c deleted file mode 100644 index 18fe70dc..00000000 --- a/tests/Layout-test.c +++ /dev/null @@ -1,9382 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ -#include "../Layout.h" -#include "../Layout-test-utils.h" - -// @generated by transpile.html - -int main() -{ - /** START_GENERATED **/ - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 100; - node_0->style.dimensions[CSS_HEIGHT] = 200; - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 100; - node_0->layout.dimensions[CSS_HEIGHT] = 200; - } - - test("should layout a single node with width and height", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 500; - node_1->style.dimensions[CSS_HEIGHT] = 500; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_WIDTH] = 250; - node_1->style.dimensions[CSS_HEIGHT] = 250; - node_1 = node_0->get_child(node_0->context, 2); - node_1->style.dimensions[CSS_WIDTH] = 125; - node_1->style.dimensions[CSS_HEIGHT] = 125; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 500; - node_1->layout.dimensions[CSS_HEIGHT] = 500; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 500; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 250; - node_1->layout.dimensions[CSS_HEIGHT] = 250; - node_1 = node_0->get_child(node_0->context, 2); - node_1->layout.position[CSS_TOP] = 750; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 125; - node_1->layout.dimensions[CSS_HEIGHT] = 125; - } - } - - test("should layout node with children", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN_REVERSE; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 500; - node_1->style.dimensions[CSS_HEIGHT] = 500; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_WIDTH] = 250; - node_1->style.dimensions[CSS_HEIGHT] = 250; - node_1 = node_0->get_child(node_0->context, 2); - node_1->style.dimensions[CSS_WIDTH] = 125; - node_1->style.dimensions[CSS_HEIGHT] = 125; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 500; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 500; - node_1->layout.dimensions[CSS_HEIGHT] = 500; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 250; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 250; - node_1->layout.dimensions[CSS_HEIGHT] = 250; - node_1 = node_0->get_child(node_0->context, 2); - node_1->layout.position[CSS_TOP] = 125; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 125; - node_1->layout.dimensions[CSS_HEIGHT] = 125; - } - } - - test("should layout node with children in reverse", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 500; - node_1->style.dimensions[CSS_HEIGHT] = 500; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_WIDTH] = 500; - node_1->style.dimensions[CSS_HEIGHT] = 500; - init_css_node_children(node_1, 2); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.dimensions[CSS_WIDTH] = 250; - node_2->style.dimensions[CSS_HEIGHT] = 250; - node_2 = node_1->get_child(node_1->context, 1); - node_2->style.dimensions[CSS_WIDTH] = 250; - node_2->style.dimensions[CSS_HEIGHT] = 250; - } - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 500; - node_1->layout.dimensions[CSS_HEIGHT] = 500; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 500; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 500; - node_1->layout.dimensions[CSS_HEIGHT] = 500; - init_css_node_children(node_1, 2); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 0; - node_2->layout.position[CSS_LEFT] = 0; - node_2->layout.dimensions[CSS_WIDTH] = 250; - node_2->layout.dimensions[CSS_HEIGHT] = 250; - node_2 = node_1->get_child(node_1->context, 1); - node_2->layout.position[CSS_TOP] = 250; - node_2->layout.position[CSS_LEFT] = 0; - node_2->layout.dimensions[CSS_WIDTH] = 250; - node_2->layout.dimensions[CSS_HEIGHT] = 250; - } - } - } - - test("should layout node with nested children", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN_REVERSE; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 500; - node_1->style.dimensions[CSS_HEIGHT] = 500; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN_REVERSE; - node_1->style.dimensions[CSS_WIDTH] = 500; - node_1->style.dimensions[CSS_HEIGHT] = 500; - init_css_node_children(node_1, 2); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.dimensions[CSS_WIDTH] = 250; - node_2->style.dimensions[CSS_HEIGHT] = 250; - node_2 = node_1->get_child(node_1->context, 1); - node_2->style.dimensions[CSS_WIDTH] = 250; - node_2->style.dimensions[CSS_HEIGHT] = 250; - } - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 500; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 500; - node_1->layout.dimensions[CSS_HEIGHT] = 500; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 500; - node_1->layout.dimensions[CSS_HEIGHT] = 500; - init_css_node_children(node_1, 2); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 250; - node_2->layout.position[CSS_LEFT] = 0; - node_2->layout.dimensions[CSS_WIDTH] = 250; - node_2->layout.dimensions[CSS_HEIGHT] = 250; - node_2 = node_1->get_child(node_1->context, 1); - node_2->layout.position[CSS_TOP] = 0; - node_2->layout.position[CSS_LEFT] = 0; - node_2->layout.dimensions[CSS_WIDTH] = 250; - node_2->layout.dimensions[CSS_HEIGHT] = 250; - } - } - } - - test("should layout node with nested children in reverse", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 100; - node_0->style.dimensions[CSS_HEIGHT] = 200; - node_0->style.margin[CSS_LEFT] = 10; - node_0->style.margin[CSS_TOP] = 10; - node_0->style.margin[CSS_RIGHT] = 10; - node_0->style.margin[CSS_BOTTOM] = 10; - node_0->style.margin[CSS_START] = 10; - node_0->style.margin[CSS_END] = 10; - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 10; - node_0->layout.position[CSS_LEFT] = 10; - node_0->layout.dimensions[CSS_WIDTH] = 100; - node_0->layout.dimensions[CSS_HEIGHT] = 200; - } - - test("should layout node with margin", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - node_0->style.margin[CSS_LEFT] = 10; - node_0->style.margin[CSS_TOP] = 10; - node_0->style.margin[CSS_RIGHT] = 10; - node_0->style.margin[CSS_BOTTOM] = 10; - node_0->style.margin[CSS_START] = 10; - node_0->style.margin[CSS_END] = 10; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1->style.margin[CSS_LEFT] = 50; - node_1->style.margin[CSS_TOP] = 50; - node_1->style.margin[CSS_RIGHT] = 50; - node_1->style.margin[CSS_BOTTOM] = 50; - node_1->style.margin[CSS_START] = 50; - node_1->style.margin[CSS_END] = 50; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1->style.margin[CSS_LEFT] = 25; - node_1->style.margin[CSS_TOP] = 25; - node_1->style.margin[CSS_RIGHT] = 25; - node_1->style.margin[CSS_BOTTOM] = 25; - node_1->style.margin[CSS_START] = 25; - node_1->style.margin[CSS_END] = 25; - node_1 = node_0->get_child(node_0->context, 2); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1->style.margin[CSS_LEFT] = 10; - node_1->style.margin[CSS_TOP] = 10; - node_1->style.margin[CSS_RIGHT] = 10; - node_1->style.margin[CSS_BOTTOM] = 10; - node_1->style.margin[CSS_START] = 10; - node_1->style.margin[CSS_END] = 10; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 10; - node_0->layout.position[CSS_LEFT] = 10; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 50; - node_1->layout.position[CSS_LEFT] = 50; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 225; - node_1->layout.position[CSS_LEFT] = 25; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 2); - node_1->layout.position[CSS_TOP] = 360; - node_1->layout.position[CSS_LEFT] = 10; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - } - } - - test("should layout node with several children", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN_REVERSE; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - node_0->style.margin[CSS_LEFT] = 10; - node_0->style.margin[CSS_TOP] = 10; - node_0->style.margin[CSS_RIGHT] = 10; - node_0->style.margin[CSS_BOTTOM] = 10; - node_0->style.margin[CSS_START] = 10; - node_0->style.margin[CSS_END] = 10; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1->style.margin[CSS_LEFT] = 50; - node_1->style.margin[CSS_TOP] = 50; - node_1->style.margin[CSS_RIGHT] = 50; - node_1->style.margin[CSS_BOTTOM] = 50; - node_1->style.margin[CSS_START] = 50; - node_1->style.margin[CSS_END] = 50; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1->style.margin[CSS_LEFT] = 25; - node_1->style.margin[CSS_TOP] = 25; - node_1->style.margin[CSS_RIGHT] = 25; - node_1->style.margin[CSS_BOTTOM] = 25; - node_1->style.margin[CSS_START] = 25; - node_1->style.margin[CSS_END] = 25; - node_1 = node_0->get_child(node_0->context, 2); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1->style.margin[CSS_LEFT] = 10; - node_1->style.margin[CSS_TOP] = 10; - node_1->style.margin[CSS_RIGHT] = 10; - node_1->style.margin[CSS_BOTTOM] = 10; - node_1->style.margin[CSS_START] = 10; - node_1->style.margin[CSS_END] = 10; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 10; - node_0->layout.position[CSS_LEFT] = 10; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 850; - node_1->layout.position[CSS_LEFT] = 50; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 675; - node_1->layout.position[CSS_LEFT] = 25; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 2); - node_1->layout.position[CSS_TOP] = 540; - node_1->layout.position[CSS_LEFT] = 10; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - } - } - - test("should layout node with several children in reverse", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.direction = CSS_DIRECTION_RTL; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW_REVERSE; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 200; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_WIDTH] = 300; - node_1->style.dimensions[CSS_HEIGHT] = 150; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 100; - node_1->layout.dimensions[CSS_WIDTH] = 300; - node_1->layout.dimensions[CSS_HEIGHT] = 150; - } - } - - test("should layout rtl with reverse correctly", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 200; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_WIDTH] = 300; - node_1->style.dimensions[CSS_HEIGHT] = 150; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 100; - node_1->layout.dimensions[CSS_WIDTH] = 300; - node_1->layout.dimensions[CSS_HEIGHT] = 150; - } - } - - test("should layout node with row flex direction", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.direction = CSS_DIRECTION_RTL; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 200; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_WIDTH] = 300; - node_1->style.dimensions[CSS_HEIGHT] = 150; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 900; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 600; - node_1->layout.dimensions[CSS_WIDTH] = 300; - node_1->layout.dimensions[CSS_HEIGHT] = 150; - } - } - - test("should layout node with row flex direction in rtl", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 300; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 200; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_WIDTH] = 300; - node_1->style.dimensions[CSS_HEIGHT] = 150; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 300; - node_0->layout.dimensions[CSS_HEIGHT] = 350; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 200; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 300; - node_1->layout.dimensions[CSS_HEIGHT] = 150; - } - } - - test("should layout node based on children main dimensions", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN_REVERSE; - node_0->style.dimensions[CSS_WIDTH] = 300; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 200; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_WIDTH] = 300; - node_1->style.dimensions[CSS_HEIGHT] = 150; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 300; - node_0->layout.dimensions[CSS_HEIGHT] = 350; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 150; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 300; - node_1->layout.dimensions[CSS_HEIGHT] = 150; - } - } - - test("should layout node based on children main dimensions in reverse", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 200; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.flex = 1; - node_1->style.dimensions[CSS_WIDTH] = 100; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 200; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 800; - } - } - - test("should layout node with just flex", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN_REVERSE; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 200; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.flex = 1; - node_1->style.dimensions[CSS_WIDTH] = 100; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 800; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 800; - } - } - - test("should layout node with just flex in reverse", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex = 1; - node_1->style.dimensions[CSS_WIDTH] = 1000; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.flex = 1; - node_2->style.dimensions[CSS_WIDTH] = 1000; - init_css_node_children(node_2, 1); - { - css_node_t *node_3; - node_3 = node_2->get_child(node_2->context, 0); - node_3->style.flex = 1; - node_3->style.dimensions[CSS_WIDTH] = 1000; - } - } - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 1000; - node_1->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 0; - node_2->layout.position[CSS_LEFT] = 0; - node_2->layout.dimensions[CSS_WIDTH] = 1000; - node_2->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_2, 1); - { - css_node_t *node_3; - node_3 = node_2->get_child(node_2->context, 0); - node_3->layout.position[CSS_TOP] = 0; - node_3->layout.position[CSS_LEFT] = 0; - node_3->layout.dimensions[CSS_WIDTH] = 1000; - node_3->layout.dimensions[CSS_HEIGHT] = 1000; - } - } - } - } - - test("should layout node with flex recursively", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN_REVERSE; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN_REVERSE; - node_1->style.flex = 1; - node_1->style.dimensions[CSS_WIDTH] = 1000; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN_REVERSE; - node_2->style.flex = 1; - node_2->style.dimensions[CSS_WIDTH] = 1000; - init_css_node_children(node_2, 1); - { - css_node_t *node_3; - node_3 = node_2->get_child(node_2->context, 0); - node_3->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN_REVERSE; - node_3->style.flex = 1; - node_3->style.dimensions[CSS_WIDTH] = 1000; - } - } - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 1000; - node_1->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 0; - node_2->layout.position[CSS_LEFT] = 0; - node_2->layout.dimensions[CSS_WIDTH] = 1000; - node_2->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_2, 1); - { - css_node_t *node_3; - node_3 = node_2->get_child(node_2->context, 0); - node_3->layout.position[CSS_TOP] = 0; - node_3->layout.position[CSS_LEFT] = 0; - node_3->layout.dimensions[CSS_WIDTH] = 1000; - node_3->layout.dimensions[CSS_HEIGHT] = 1000; - } - } - } - } - - test("should layout node with flex recursively in reverse", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - node_0->style.margin[CSS_LEFT] = 5; - node_0->style.margin[CSS_TOP] = 10; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1->style.margin[CSS_LEFT] = 15; - node_1->style.margin[CSS_TOP] = 50; - node_1->style.margin[CSS_BOTTOM] = 20; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1->style.margin[CSS_LEFT] = 30; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 10; - node_0->layout.position[CSS_LEFT] = 5; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 50; - node_1->layout.position[CSS_LEFT] = 15; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 170; - node_1->layout.position[CSS_LEFT] = 30; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - } - } - - test("should layout node with targeted margin", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN_REVERSE; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - node_0->style.margin[CSS_LEFT] = 5; - node_0->style.margin[CSS_TOP] = 10; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1->style.margin[CSS_LEFT] = 15; - node_1->style.margin[CSS_TOP] = 50; - node_1->style.margin[CSS_BOTTOM] = 20; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1->style.margin[CSS_LEFT] = 30; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 10; - node_0->layout.position[CSS_LEFT] = 5; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 880; - node_1->layout.position[CSS_LEFT] = 15; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 730; - node_1->layout.position[CSS_LEFT] = 30; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - } - } - - test("should layout node with targeted margin in reverse", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.justify_content = CSS_JUSTIFY_FLEX_START; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 100; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - } - } - - test("should layout node with justifyContent: flex-start", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN_REVERSE; - node_0->style.justify_content = CSS_JUSTIFY_FLEX_START; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 900; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 800; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - } - } - - test("should layout node with justifyContent: flex-start in reverse", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.justify_content = CSS_JUSTIFY_FLEX_END; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 800; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 900; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - } - } - - test("should layout node with justifyContent: flex-end", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN_REVERSE; - node_0->style.justify_content = CSS_JUSTIFY_FLEX_END; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 100; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - } - } - - test("should layout node with justifyContent: flex-end in reverse", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.justify_content = CSS_JUSTIFY_SPACE_BETWEEN; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 900; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - } - } - - test("should layout node with justifyContent: space-between", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN_REVERSE; - node_0->style.justify_content = CSS_JUSTIFY_SPACE_BETWEEN; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 900; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - } - } - - test("should layout node with justifyContent: space-between in reverse", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.justify_content = CSS_JUSTIFY_SPACE_AROUND; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 200; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 700; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - } - } - - test("should layout node with justifyContent: space-around", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN_REVERSE; - node_0->style.justify_content = CSS_JUSTIFY_SPACE_AROUND; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 700; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 200; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - } - } - - test("should layout node with justifyContent: space-around in reverse", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.justify_content = CSS_JUSTIFY_CENTER; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 400; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 500; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - } - } - - test("should layout node with justifyContent: center", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN_REVERSE; - node_0->style.justify_content = CSS_JUSTIFY_CENTER; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 500; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 400; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - } - } - - test("should layout node with justifyContent: center in reverse", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex = 1; - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 1000; - } - } - - test("should layout node with flex override height", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.align_items = CSS_ALIGN_FLEX_START; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 200; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 200; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 100; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - } - } - - test("should layout node with alignItems: flex-start", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN_REVERSE; - node_0->style.align_items = CSS_ALIGN_FLEX_START; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 200; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 900; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 200; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 800; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - } - } - - test("should layout node with alignItems: flex-start in reverse", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.align_items = CSS_ALIGN_CENTER; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 200; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 400; - node_1->layout.dimensions[CSS_WIDTH] = 200; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 100; - node_1->layout.position[CSS_LEFT] = 450; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - } - } - - test("should layout node with alignItems: center", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN_REVERSE; - node_0->style.align_items = CSS_ALIGN_CENTER; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 200; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 900; - node_1->layout.position[CSS_LEFT] = 400; - node_1->layout.dimensions[CSS_WIDTH] = 200; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 800; - node_1->layout.position[CSS_LEFT] = 450; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - } - } - - test("should layout node with alignItems: center in reverse", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.align_items = CSS_ALIGN_FLEX_END; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 200; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 800; - node_1->layout.dimensions[CSS_WIDTH] = 200; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 100; - node_1->layout.position[CSS_LEFT] = 900; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - } - } - - test("should layout node with alignItems: flex-end", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN_REVERSE; - node_0->style.align_items = CSS_ALIGN_FLEX_END; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 200; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 900; - node_1->layout.position[CSS_LEFT] = 800; - node_1->layout.dimensions[CSS_WIDTH] = 200; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 800; - node_1->layout.position[CSS_LEFT] = 900; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - } - } - - test("should layout node with alignItems: flex-end in reverse", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.align_items = CSS_ALIGN_FLEX_END; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 200; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.align_self = CSS_ALIGN_CENTER; - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 800; - node_1->layout.dimensions[CSS_WIDTH] = 200; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 100; - node_1->layout.position[CSS_LEFT] = 450; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - } - } - - test("should layout node with alignSelf overrides alignItems", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN_REVERSE; - node_0->style.align_items = CSS_ALIGN_FLEX_END; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 200; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.align_self = CSS_ALIGN_CENTER; - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 900; - node_1->layout.position[CSS_LEFT] = 800; - node_1->layout.dimensions[CSS_WIDTH] = 200; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 800; - node_1->layout.position[CSS_LEFT] = 450; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - } - } - - test("should layout node with alignSelf overrides alignItems in reverse", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.align_items = CSS_ALIGN_STRETCH; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_HEIGHT] = 100; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 1000; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - } - } - - test("should layout node with alignItem: stretch", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN_REVERSE; - node_0->style.align_items = CSS_ALIGN_STRETCH; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_HEIGHT] = 100; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 900; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 1000; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - } - } - - test("should layout node with alignItem: stretch in reverse", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 0; - node_0->layout.dimensions[CSS_HEIGHT] = 0; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout empty node", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN_REVERSE; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 0; - node_0->layout.dimensions[CSS_HEIGHT] = 0; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout empty node in reverse", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.margin[CSS_LEFT] = 5; - node_1->style.margin[CSS_TOP] = 5; - node_1->style.margin[CSS_RIGHT] = 5; - node_1->style.margin[CSS_BOTTOM] = 5; - node_1->style.margin[CSS_START] = 5; - node_1->style.margin[CSS_END] = 5; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 10; - node_0->layout.dimensions[CSS_HEIGHT] = 10; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 5; - node_1->layout.position[CSS_LEFT] = 5; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout child with margin", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN_REVERSE; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.margin[CSS_LEFT] = 5; - node_1->style.margin[CSS_TOP] = 5; - node_1->style.margin[CSS_RIGHT] = 5; - node_1->style.margin[CSS_BOTTOM] = 5; - node_1->style.margin[CSS_START] = 5; - node_1->style.margin[CSS_END] = 5; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 10; - node_0->layout.dimensions[CSS_HEIGHT] = 10; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 5; - node_1->layout.position[CSS_LEFT] = 5; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout child with margin in reverse", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_HEIGHT] = 200; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 0; - node_0->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 100; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - } - } - - test("should not shrink children if not enough space", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN_REVERSE; - node_0->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_HEIGHT] = 200; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 0; - node_0->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = -200; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - } - } - - test("should not shrink children if not enough space in reverse", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.justify_content = CSS_JUSTIFY_CENTER; - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 0; - node_0->layout.dimensions[CSS_HEIGHT] = 0; - } - - test("should layout for center", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.justify_content = CSS_JUSTIFY_FLEX_END; - node_0->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.margin[CSS_TOP] = 10; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 0; - node_0->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 100; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout flex-end taking into account margin", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN_REVERSE; - node_0->style.justify_content = CSS_JUSTIFY_FLEX_END; - node_0->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.margin[CSS_TOP] = 10; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 0; - node_0->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 10; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout flex-end taking into account margin in reverse", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.align_items = CSS_ALIGN_FLEX_END; - init_css_node_children(node_1, 2); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.margin[CSS_LEFT] = 10; - node_2->style.margin[CSS_TOP] = 10; - node_2->style.margin[CSS_RIGHT] = 10; - node_2->style.margin[CSS_BOTTOM] = 10; - node_2->style.margin[CSS_START] = 10; - node_2->style.margin[CSS_END] = 10; - node_2 = node_1->get_child(node_1->context, 1); - node_2->style.dimensions[CSS_HEIGHT] = 100; - } - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 20; - node_0->layout.dimensions[CSS_HEIGHT] = 120; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 20; - node_1->layout.dimensions[CSS_HEIGHT] = 120; - init_css_node_children(node_1, 2); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 10; - node_2->layout.position[CSS_LEFT] = 10; - node_2->layout.dimensions[CSS_WIDTH] = 0; - node_2->layout.dimensions[CSS_HEIGHT] = 0; - node_2 = node_1->get_child(node_1->context, 1); - node_2->layout.position[CSS_TOP] = 20; - node_2->layout.position[CSS_LEFT] = 20; - node_2->layout.dimensions[CSS_WIDTH] = 0; - node_2->layout.dimensions[CSS_HEIGHT] = 100; - } - } - } - - test("should layout alignItems with margin", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN_REVERSE; - node_1->style.align_items = CSS_ALIGN_FLEX_END; - init_css_node_children(node_1, 2); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.margin[CSS_LEFT] = 10; - node_2->style.margin[CSS_TOP] = 10; - node_2->style.margin[CSS_RIGHT] = 10; - node_2->style.margin[CSS_BOTTOM] = 10; - node_2->style.margin[CSS_START] = 10; - node_2->style.margin[CSS_END] = 10; - node_2 = node_1->get_child(node_1->context, 1); - node_2->style.dimensions[CSS_HEIGHT] = 100; - } - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 20; - node_0->layout.dimensions[CSS_HEIGHT] = 120; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 20; - node_1->layout.dimensions[CSS_HEIGHT] = 120; - init_css_node_children(node_1, 2); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 110; - node_2->layout.position[CSS_LEFT] = 10; - node_2->layout.dimensions[CSS_WIDTH] = 0; - node_2->layout.dimensions[CSS_HEIGHT] = 0; - node_2 = node_1->get_child(node_1->context, 1); - node_2->layout.position[CSS_TOP] = 0; - node_2->layout.position[CSS_LEFT] = 20; - node_2->layout.dimensions[CSS_WIDTH] = 0; - node_2->layout.dimensions[CSS_HEIGHT] = 100; - } - } - } - - test("should layout alignItems with margin in reverse", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex = 1; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 0; - node_0->layout.dimensions[CSS_HEIGHT] = 0; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout flex inside of an empty element", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.align_items = CSS_ALIGN_STRETCH; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.margin[CSS_LEFT] = 10; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 10; - node_0->layout.dimensions[CSS_HEIGHT] = 0; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 10; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout alignItems stretch and margin", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN_REVERSE; - node_0->style.align_items = CSS_ALIGN_STRETCH; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.margin[CSS_LEFT] = 10; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 10; - node_0->layout.dimensions[CSS_HEIGHT] = 0; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 10; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout alignItems stretch and margin in reverse", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.padding[CSS_LEFT] = 5; - node_0->style.padding[CSS_TOP] = 5; - node_0->style.padding[CSS_RIGHT] = 5; - node_0->style.padding[CSS_BOTTOM] = 5; - node_0->style.padding[CSS_START] = 5; - node_0->style.padding[CSS_END] = 5; - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 10; - node_0->layout.dimensions[CSS_HEIGHT] = 10; - } - - test("should layout node with padding", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.padding[CSS_LEFT] = 5; - node_0->style.padding[CSS_TOP] = 5; - node_0->style.padding[CSS_RIGHT] = 5; - node_0->style.padding[CSS_BOTTOM] = 5; - node_0->style.padding[CSS_START] = 5; - node_0->style.padding[CSS_END] = 5; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 10; - node_0->layout.dimensions[CSS_HEIGHT] = 10; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 5; - node_1->layout.position[CSS_LEFT] = 5; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout node with padding and a child", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.padding[CSS_LEFT] = 5; - node_0->style.padding[CSS_TOP] = 5; - node_0->style.padding[CSS_RIGHT] = 5; - node_0->style.padding[CSS_BOTTOM] = 5; - node_0->style.padding[CSS_START] = 5; - node_0->style.padding[CSS_END] = 5; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.margin[CSS_LEFT] = 5; - node_1->style.margin[CSS_TOP] = 5; - node_1->style.margin[CSS_RIGHT] = 5; - node_1->style.margin[CSS_BOTTOM] = 5; - node_1->style.margin[CSS_START] = 5; - node_1->style.margin[CSS_END] = 5; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 20; - node_0->layout.dimensions[CSS_HEIGHT] = 20; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 10; - node_1->layout.position[CSS_LEFT] = 10; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout node with padding and a child with margin", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.align_self = CSS_ALIGN_STRETCH; - node_1->style.padding[CSS_LEFT] = 10; - node_1->style.padding[CSS_TOP] = 10; - node_1->style.padding[CSS_RIGHT] = 10; - node_1->style.padding[CSS_BOTTOM] = 10; - node_1->style.padding[CSS_START] = 10; - node_1->style.padding[CSS_END] = 10; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 20; - node_0->layout.dimensions[CSS_HEIGHT] = 20; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 20; - node_1->layout.dimensions[CSS_HEIGHT] = 20; - } - } - - test("should layout node with padding and stretch", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.padding[CSS_LEFT] = 50; - node_0->style.padding[CSS_TOP] = 50; - node_0->style.padding[CSS_RIGHT] = 50; - node_0->style.padding[CSS_BOTTOM] = 50; - node_0->style.padding[CSS_START] = 50; - node_0->style.padding[CSS_END] = 50; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.align_self = CSS_ALIGN_STRETCH; - node_1->style.padding[CSS_LEFT] = 10; - node_1->style.padding[CSS_TOP] = 10; - node_1->style.padding[CSS_RIGHT] = 10; - node_1->style.padding[CSS_BOTTOM] = 10; - node_1->style.padding[CSS_START] = 10; - node_1->style.padding[CSS_END] = 10; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 120; - node_0->layout.dimensions[CSS_HEIGHT] = 120; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 50; - node_1->layout.position[CSS_LEFT] = 50; - node_1->layout.dimensions[CSS_WIDTH] = 20; - node_1->layout.dimensions[CSS_HEIGHT] = 20; - } - } - - test("should layout node with inner & outer padding and stretch", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.align_self = CSS_ALIGN_STRETCH; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.margin[CSS_LEFT] = 16; - node_2->style.margin[CSS_TOP] = 16; - node_2->style.margin[CSS_RIGHT] = 16; - node_2->style.margin[CSS_BOTTOM] = 16; - node_2->style.margin[CSS_START] = 16; - node_2->style.margin[CSS_END] = 16; - } - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 32; - node_0->layout.dimensions[CSS_HEIGHT] = 32; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 32; - node_1->layout.dimensions[CSS_HEIGHT] = 32; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 16; - node_2->layout.position[CSS_LEFT] = 16; - node_2->layout.dimensions[CSS_WIDTH] = 0; - node_2->layout.dimensions[CSS_HEIGHT] = 0; - } - } - } - - test("should layout node with stretch and child with margin", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.position[CSS_LEFT] = 5; - node_0->style.position[CSS_TOP] = 5; - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 5; - node_0->layout.position[CSS_LEFT] = 5; - node_0->layout.dimensions[CSS_WIDTH] = 0; - node_0->layout.dimensions[CSS_HEIGHT] = 0; - } - - test("should layout node with top and left", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.justify_content = CSS_JUSTIFY_SPACE_AROUND; - node_0->style.dimensions[CSS_HEIGHT] = 10; - node_0->style.padding[CSS_TOP] = 5; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 0; - node_0->layout.dimensions[CSS_HEIGHT] = 10; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 7.5; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout node with height, padding and space-around", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.position[CSS_BOTTOM] = 5; - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = -5; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 0; - node_0->layout.dimensions[CSS_HEIGHT] = 0; - } - - test("should layout node with bottom", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.position[CSS_TOP] = 10; - node_0->style.position[CSS_BOTTOM] = 5; - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 10; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 0; - node_0->layout.dimensions[CSS_HEIGHT] = 0; - } - - test("should layout node with both top and bottom", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.dimensions[CSS_WIDTH] = 500; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex = 1; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.position_type = CSS_POSITION_ABSOLUTE; - node_1->style.dimensions[CSS_WIDTH] = 50; - node_1 = node_0->get_child(node_0->context, 2); - node_1->style.flex = 1; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 500; - node_0->layout.dimensions[CSS_HEIGHT] = 0; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 250; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 250; - node_1->layout.dimensions[CSS_WIDTH] = 50; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - node_1 = node_0->get_child(node_0->context, 2); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 250; - node_1->layout.dimensions[CSS_WIDTH] = 250; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout node with position: absolute", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.position_type = CSS_POSITION_ABSOLUTE; - node_1->style.margin[CSS_RIGHT] = 15; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 0; - node_0->layout.dimensions[CSS_HEIGHT] = 0; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout node with child with position: absolute and margin", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.align_self = CSS_ALIGN_CENTER; - node_1->style.position_type = CSS_POSITION_ABSOLUTE; - node_1->style.padding[CSS_RIGHT] = 12; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 0; - node_0->layout.dimensions[CSS_HEIGHT] = 0; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 12; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout node with position: absolute, padding and alignSelf: center", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_HEIGHT] = 5; - node_0->style.padding[CSS_BOTTOM] = 20; - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 0; - node_0->layout.dimensions[CSS_HEIGHT] = 20; - } - - test("should work with height smaller than paddingBottom", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 5; - node_0->style.padding[CSS_LEFT] = 20; - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 20; - node_0->layout.dimensions[CSS_HEIGHT] = 0; - } - - test("should work with width smaller than paddingLeft", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.dimensions[CSS_WIDTH] = 400; - } - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.align_self = CSS_ALIGN_STRETCH; - node_1->style.dimensions[CSS_WIDTH] = 200; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 400; - node_0->layout.dimensions[CSS_HEIGHT] = 0; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 400; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 0; - node_2->layout.position[CSS_LEFT] = 0; - node_2->layout.dimensions[CSS_WIDTH] = 400; - node_2->layout.dimensions[CSS_HEIGHT] = 0; - } - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 200; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout node with specified width and stretch", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.padding[CSS_LEFT] = 5; - node_0->style.padding[CSS_TOP] = 5; - node_0->style.padding[CSS_RIGHT] = 5; - node_0->style.padding[CSS_BOTTOM] = 5; - node_0->style.padding[CSS_START] = 5; - node_0->style.padding[CSS_END] = 5; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.position_type = CSS_POSITION_ABSOLUTE; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 10; - node_0->layout.dimensions[CSS_HEIGHT] = 10; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 5; - node_1->layout.position[CSS_LEFT] = 5; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout node with padding and child with position absolute", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.position_type = CSS_POSITION_ABSOLUTE; - node_1->style.position[CSS_LEFT] = 10; - node_1->style.position[CSS_TOP] = 10; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 0; - node_0->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 10; - node_1->layout.position[CSS_LEFT] = 10; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout node with position absolute, top and left", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.padding[CSS_LEFT] = 20; - node_0->style.padding[CSS_TOP] = 20; - node_0->style.padding[CSS_RIGHT] = 20; - node_0->style.padding[CSS_BOTTOM] = 20; - node_0->style.padding[CSS_START] = 20; - node_0->style.padding[CSS_END] = 20; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.position_type = CSS_POSITION_ABSOLUTE; - node_1->style.position[CSS_LEFT] = 5; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 40; - node_0->layout.dimensions[CSS_HEIGHT] = 40; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 20; - node_1->layout.position[CSS_LEFT] = 5; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout node with padding and child position absolute, left", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.position_type = CSS_POSITION_ABSOLUTE; - node_1->style.margin[CSS_TOP] = 5; - node_1->style.position[CSS_TOP] = 5; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 0; - node_0->layout.dimensions[CSS_HEIGHT] = 0; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 10; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout node with position: absolute, top and marginTop", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.position_type = CSS_POSITION_ABSOLUTE; - node_1->style.margin[CSS_LEFT] = 5; - node_1->style.position[CSS_LEFT] = 5; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 0; - node_0->layout.dimensions[CSS_HEIGHT] = 0; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 10; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout node with position: absolute, left and marginLeft", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.justify_content = CSS_JUSTIFY_SPACE_AROUND; - node_0->style.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.position_type = CSS_POSITION_ABSOLUTE; - node_1 = node_0->get_child(node_0->context, 1); - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 0; - node_0->layout.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 100; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 100; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout node with space-around and child position absolute", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN_REVERSE; - node_0->style.justify_content = CSS_JUSTIFY_SPACE_AROUND; - node_0->style.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.position_type = CSS_POSITION_ABSOLUTE; - node_1 = node_0->get_child(node_0->context, 1); - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 0; - node_0->layout.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 100; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 100; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout node with space-around and child position absolute in reverse", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.dimensions[CSS_WIDTH] = 700; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex = 1; - node_1->style.margin[CSS_LEFT] = 5; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 700; - node_0->layout.dimensions[CSS_HEIGHT] = 0; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 5; - node_1->layout.dimensions[CSS_WIDTH] = 695; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout node with flex and main margin", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.direction = CSS_DIRECTION_RTL; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.dimensions[CSS_WIDTH] = 700; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex = 1; - node_1->style.margin[CSS_RIGHT] = 5; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 700; - node_0->layout.dimensions[CSS_HEIGHT] = 0; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 695; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout node with flex and main margin in rtl", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.dimensions[CSS_WIDTH] = 700; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex = 1; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.flex = 1; - node_1->style.padding[CSS_RIGHT] = 5; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 700; - node_0->layout.dimensions[CSS_HEIGHT] = 0; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 347.5; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 347.5; - node_1->layout.dimensions[CSS_WIDTH] = 352.5; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout node with multiple flex and padding", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.direction = CSS_DIRECTION_RTL; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.dimensions[CSS_WIDTH] = 700; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex = 1; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.flex = 1; - node_1->style.padding[CSS_LEFT] = 5; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 700; - node_0->layout.dimensions[CSS_HEIGHT] = 0; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 352.5; - node_1->layout.dimensions[CSS_WIDTH] = 347.5; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 352.5; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout node with multiple flex and padding in rtl", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.dimensions[CSS_WIDTH] = 700; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex = 1; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.flex = 1; - node_1->style.margin[CSS_LEFT] = 5; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 700; - node_0->layout.dimensions[CSS_HEIGHT] = 0; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 347.5; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 352.5; - node_1->layout.dimensions[CSS_WIDTH] = 347.5; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout node with multiple flex and margin", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.direction = CSS_DIRECTION_RTL; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.dimensions[CSS_WIDTH] = 700; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex = 1; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.flex = 1; - node_1->style.margin[CSS_RIGHT] = 5; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 700; - node_0->layout.dimensions[CSS_HEIGHT] = 0; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 352.5; - node_1->layout.dimensions[CSS_WIDTH] = 347.5; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 347.5; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout node with multiple flex and margin in rtl", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_HEIGHT] = 300; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_HEIGHT] = 600; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.flex = 1; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 0; - node_0->layout.dimensions[CSS_HEIGHT] = 300; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 600; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 600; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout node with flex and overflow", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.dimensions[CSS_WIDTH] = 600; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.position_type = CSS_POSITION_ABSOLUTE; - node_1->style.flex = 1; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 600; - node_0->layout.dimensions[CSS_HEIGHT] = 0; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout node with flex and position absolute", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.direction = CSS_DIRECTION_RTL; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.dimensions[CSS_WIDTH] = 600; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.position_type = CSS_POSITION_ABSOLUTE; - node_1->style.flex = 1; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 600; - node_0->layout.dimensions[CSS_HEIGHT] = 0; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 600; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout node with flex and position absolute in rtl", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_HEIGHT] = 500; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex = 1; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.position_type = CSS_POSITION_ABSOLUTE; - node_1->style.flex = 1; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 0; - node_0->layout.dimensions[CSS_HEIGHT] = 500; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 500; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 500; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout node with double flex and position absolute", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.border[CSS_LEFT] = 5; - node_0->style.border[CSS_TOP] = 5; - node_0->style.border[CSS_RIGHT] = 5; - node_0->style.border[CSS_BOTTOM] = 5; - node_0->style.border[CSS_START] = 5; - node_0->style.border[CSS_END] = 5; - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 10; - node_0->layout.dimensions[CSS_HEIGHT] = 10; - } - - test("should layout node with borderWidth", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.border[CSS_TOP] = 1; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.position_type = CSS_POSITION_ABSOLUTE; - node_1->style.position[CSS_TOP] = -1; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 0; - node_0->layout.dimensions[CSS_HEIGHT] = 1; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout node with borderWidth and position: absolute, top", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.border[CSS_LEFT] = 1; - node_0->style.border[CSS_TOP] = 1; - node_0->style.border[CSS_RIGHT] = 1; - node_0->style.border[CSS_BOTTOM] = 1; - node_0->style.border[CSS_START] = 1; - node_0->style.border[CSS_END] = 1; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.position_type = CSS_POSITION_ABSOLUTE; - node_1->style.position[CSS_LEFT] = 5; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 2; - node_0->layout.dimensions[CSS_HEIGHT] = 2; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 1; - node_1->layout.position[CSS_LEFT] = 6; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout node with borderWidth and position: absolute, top. cross axis", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 50; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.align_self = CSS_ALIGN_STRETCH; - node_1->style.margin[CSS_LEFT] = 20; - node_1->style.padding[CSS_LEFT] = 20; - node_1->style.padding[CSS_TOP] = 20; - node_1->style.padding[CSS_RIGHT] = 20; - node_1->style.padding[CSS_BOTTOM] = 20; - node_1->style.padding[CSS_START] = 20; - node_1->style.padding[CSS_END] = 20; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 50; - node_0->layout.dimensions[CSS_HEIGHT] = 40; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 20; - node_1->layout.dimensions[CSS_WIDTH] = 40; - node_1->layout.dimensions[CSS_HEIGHT] = 40; - } - } - - test("should correctly take into account min padding for stretch", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = -31; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.border[CSS_RIGHT] = 5; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 5; - node_0->layout.dimensions[CSS_HEIGHT] = 0; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 5; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout node with negative width", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.border[CSS_RIGHT] = 1; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.margin[CSS_RIGHT] = -8; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1; - node_0->layout.dimensions[CSS_HEIGHT] = 0; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should handle negative margin and min padding correctly", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.direction = CSS_DIRECTION_RTL; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.border[CSS_LEFT] = 1; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.margin[CSS_LEFT] = -8; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1; - node_0->layout.dimensions[CSS_HEIGHT] = 0; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 1; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should handle negative margin and min padding correctly in rtl", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->measure = measure; - node_0->context = "small"; - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 35; - node_0->layout.dimensions[CSS_HEIGHT] = 18; - } - - test("should layout node with just text", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 100; - node_0->measure = measure; - node_0->context = "measureWithRatio2"; - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 100; - node_0->layout.dimensions[CSS_HEIGHT] = 200; - } - - test("should layout node with fixed width and custom measure function", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_HEIGHT] = 100; - node_0->measure = measure; - node_0->context = "measureWithRatio2"; - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 200; - node_0->layout.dimensions[CSS_HEIGHT] = 100; - } - - test("should layout node with fixed height and custom measure function", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 100; - node_0->style.dimensions[CSS_HEIGHT] = 100; - node_0->measure = measure; - node_0->context = "measureWithRatio2"; - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 100; - node_0->layout.dimensions[CSS_HEIGHT] = 100; - } - - test("should layout node with fixed height and fixed width, ignoring custom measure function", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->measure = measure; - node_0->context = "measureWithRatio2"; - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 99999; - node_0->layout.dimensions[CSS_HEIGHT] = 99999; - } - - test("should layout node with no fixed dimension and custom measure function", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN; - node_0->style.dimensions[CSS_WIDTH] = 320; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->measure = measure; - node_1->context = "measureWithRatio2"; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_1->style.overflow = CSS_OVERFLOW_HIDDEN; - node_1->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_1, 2); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->measure = measure; - node_2->context = "measureWithRatio2"; - node_2 = node_1->get_child(node_1->context, 1); - node_2->measure = measure; - node_2->context = "measureWithRatio2"; - } - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 320; - node_0->layout.dimensions[CSS_HEIGHT] = 740; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 320; - node_1->layout.dimensions[CSS_HEIGHT] = 640; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 640; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 320; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_1, 2); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 0; - node_2->layout.position[CSS_LEFT] = 0; - node_2->layout.dimensions[CSS_WIDTH] = 200; - node_2->layout.dimensions[CSS_HEIGHT] = 100; - node_2 = node_1->get_child(node_1->context, 1); - node_2->layout.position[CSS_TOP] = 0; - node_2->layout.position[CSS_LEFT] = 200; - node_2->layout.dimensions[CSS_WIDTH] = 200; - node_2->layout.dimensions[CSS_HEIGHT] = 100; - } - } - } - - test("should layout node with nested stacks and custom measure function", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 10; - node_0->measure = measure; - node_0->context = "small"; - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 10; - node_0->layout.dimensions[CSS_HEIGHT] = 18; - } - - test("should layout node with text and width", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->measure = measure; - node_0->context = "loooooooooong with space"; - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 172; - node_0->layout.dimensions[CSS_HEIGHT] = 18; - } - - test("should layout node with text, padding and margin", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 300; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.align_self = CSS_ALIGN_STRETCH; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.align_self = CSS_ALIGN_STRETCH; - } - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 300; - node_0->layout.dimensions[CSS_HEIGHT] = 0; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 300; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 0; - node_2->layout.position[CSS_LEFT] = 0; - node_2->layout.dimensions[CSS_WIDTH] = 300; - node_2->layout.dimensions[CSS_HEIGHT] = 0; - } - } - } - - test("should layout node with nested alignSelf: stretch", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_1->style.dimensions[CSS_WIDTH] = 500; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.flex = 1; - node_2->measure = measure; - node_2->context = "loooooooooong with space"; - } - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 500; - node_0->layout.dimensions[CSS_HEIGHT] = 18; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 500; - node_1->layout.dimensions[CSS_HEIGHT] = 18; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 0; - node_2->layout.position[CSS_LEFT] = 0; - node_2->layout.dimensions[CSS_WIDTH] = 500; - node_2->layout.dimensions[CSS_HEIGHT] = 18; - } - } - } - - test("should layout node with text and flex", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.direction = CSS_DIRECTION_RTL; - node_1->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_1->style.dimensions[CSS_WIDTH] = 500; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.flex = 1; - node_2->measure = measure; - node_2->context = "loooooooooong with space"; - } - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 500; - node_0->layout.dimensions[CSS_HEIGHT] = 18; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 500; - node_1->layout.dimensions[CSS_HEIGHT] = 18; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 0; - node_2->layout.position[CSS_LEFT] = 0; - node_2->layout.dimensions[CSS_WIDTH] = 500; - node_2->layout.dimensions[CSS_HEIGHT] = 18; - } - } - } - - test("should layout node with text and flex in rtl", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 130; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.align_items = CSS_ALIGN_STRETCH; - node_1->style.align_self = CSS_ALIGN_STRETCH; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->measure = measure; - node_2->context = "loooooooooong with space"; - } - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 130; - node_0->layout.dimensions[CSS_HEIGHT] = 36; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 130; - node_1->layout.dimensions[CSS_HEIGHT] = 36; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 0; - node_2->layout.position[CSS_LEFT] = 0; - node_2->layout.dimensions[CSS_WIDTH] = 130; - node_2->layout.dimensions[CSS_HEIGHT] = 36; - } - } - } - - test("should layout node with text and stretch", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 200; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.align_items = CSS_ALIGN_STRETCH; - node_1->style.align_self = CSS_ALIGN_STRETCH; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.dimensions[CSS_WIDTH] = 130; - node_2->measure = measure; - node_2->context = "loooooooooong with space"; - } - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 200; - node_0->layout.dimensions[CSS_HEIGHT] = 36; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 200; - node_1->layout.dimensions[CSS_HEIGHT] = 36; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 0; - node_2->layout.position[CSS_LEFT] = 0; - node_2->layout.dimensions[CSS_WIDTH] = 130; - node_2->layout.dimensions[CSS_HEIGHT] = 36; - } - } - } - - test("should layout node with text stretch and width", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.align_self = CSS_ALIGN_FLEX_START; - node_0->style.dimensions[CSS_WIDTH] = 100; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.align_self = CSS_ALIGN_FLEX_START; - node_1->measure = measure; - node_1->context = "loooooooooong with space"; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 100; - node_0->layout.dimensions[CSS_HEIGHT] = 36; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 36; - } - } - - test("should layout node with text bounded by parent", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.align_self = CSS_ALIGN_FLEX_START; - node_0->style.dimensions[CSS_WIDTH] = 100; - node_0->style.padding[CSS_LEFT] = 10; - node_0->style.padding[CSS_TOP] = 10; - node_0->style.padding[CSS_RIGHT] = 10; - node_0->style.padding[CSS_BOTTOM] = 10; - node_0->style.padding[CSS_START] = 10; - node_0->style.padding[CSS_END] = 10; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.align_self = CSS_ALIGN_FLEX_START; - node_1->style.margin[CSS_LEFT] = 10; - node_1->style.margin[CSS_TOP] = 10; - node_1->style.margin[CSS_RIGHT] = 10; - node_1->style.margin[CSS_BOTTOM] = 10; - node_1->style.margin[CSS_START] = 10; - node_1->style.margin[CSS_END] = 10; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->measure = measure; - node_2->context = "loooooooooong with space"; - } - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 100; - node_0->layout.dimensions[CSS_HEIGHT] = 76; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 20; - node_1->layout.position[CSS_LEFT] = 20; - node_1->layout.dimensions[CSS_WIDTH] = 60; - node_1->layout.dimensions[CSS_HEIGHT] = 36; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 0; - node_2->layout.position[CSS_LEFT] = 0; - node_2->layout.dimensions[CSS_WIDTH] = 100; - node_2->layout.dimensions[CSS_HEIGHT] = 36; - } - } - } - - test("should layout node with text bounded by grand-parent", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.justify_content = CSS_JUSTIFY_SPACE_BETWEEN; - node_0->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_HEIGHT] = 900; - node_1 = node_0->get_child(node_0->context, 1); - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 0; - node_0->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 900; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 900; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout space-between when remaining space is negative", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN_REVERSE; - node_0->style.justify_content = CSS_JUSTIFY_SPACE_BETWEEN; - node_0->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_HEIGHT] = 900; - node_1 = node_0->get_child(node_0->context, 1); - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 0; - node_0->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = -800; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 900; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = -800; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout space-between when remaining space is negative in reverse", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.justify_content = CSS_JUSTIFY_FLEX_END; - node_0->style.dimensions[CSS_WIDTH] = 200; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 900; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 200; - node_0->layout.dimensions[CSS_HEIGHT] = 0; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = -700; - node_1->layout.dimensions[CSS_WIDTH] = 900; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout flex-end when remaining space is negative", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.direction = CSS_DIRECTION_RTL; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.justify_content = CSS_JUSTIFY_FLEX_END; - node_0->style.dimensions[CSS_WIDTH] = 200; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 900; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 200; - node_0->layout.dimensions[CSS_HEIGHT] = 0; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 900; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout flex-end when remaining space is negative in rtl", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_1->style.dimensions[CSS_WIDTH] = 200; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.margin[CSS_LEFT] = 20; - node_2->style.margin[CSS_TOP] = 20; - node_2->style.margin[CSS_RIGHT] = 20; - node_2->style.margin[CSS_BOTTOM] = 20; - node_2->style.margin[CSS_START] = 20; - node_2->style.margin[CSS_END] = 20; - node_2->measure = measure; - node_2->context = "loooooooooong with space"; - } - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 200; - node_0->layout.dimensions[CSS_HEIGHT] = 58; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 200; - node_1->layout.dimensions[CSS_HEIGHT] = 58; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 20; - node_2->layout.position[CSS_LEFT] = 20; - node_2->layout.dimensions[CSS_WIDTH] = 172; - node_2->layout.dimensions[CSS_HEIGHT] = 18; - } - } - } - - test("should layout text with flexDirection row", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.direction = CSS_DIRECTION_RTL; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_1->style.dimensions[CSS_WIDTH] = 200; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.margin[CSS_LEFT] = 20; - node_2->style.margin[CSS_TOP] = 20; - node_2->style.margin[CSS_RIGHT] = 20; - node_2->style.margin[CSS_BOTTOM] = 20; - node_2->style.margin[CSS_START] = 20; - node_2->style.margin[CSS_END] = 20; - node_2->measure = measure; - node_2->context = "loooooooooong with space"; - } - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 200; - node_0->layout.dimensions[CSS_HEIGHT] = 58; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 200; - node_1->layout.dimensions[CSS_HEIGHT] = 58; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 20; - node_2->layout.position[CSS_LEFT] = 8; - node_2->layout.dimensions[CSS_WIDTH] = 172; - node_2->layout.dimensions[CSS_HEIGHT] = 18; - } - } - } - - test("should layout text with flexDirection row in rtl", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 200; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.margin[CSS_LEFT] = 20; - node_2->style.margin[CSS_TOP] = 20; - node_2->style.margin[CSS_RIGHT] = 20; - node_2->style.margin[CSS_BOTTOM] = 20; - node_2->style.margin[CSS_START] = 20; - node_2->style.margin[CSS_END] = 20; - node_2->measure = measure; - node_2->context = "loooooooooong with space"; - } - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 200; - node_0->layout.dimensions[CSS_HEIGHT] = 76; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 200; - node_1->layout.dimensions[CSS_HEIGHT] = 76; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 20; - node_2->layout.position[CSS_LEFT] = 20; - node_2->layout.dimensions[CSS_WIDTH] = 160; - node_2->layout.dimensions[CSS_HEIGHT] = 36; - } - } - } - - test("should layout with text and margin", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 100; - node_0->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.position_type = CSS_POSITION_ABSOLUTE; - node_1->style.position[CSS_LEFT] = 0; - node_1->style.position[CSS_TOP] = 0; - node_1->style.position[CSS_RIGHT] = 0; - node_1->style.position[CSS_BOTTOM] = 0; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 100; - node_0->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - } - } - - test("should layout with position absolute, top, left, bottom, right", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.align_self = CSS_ALIGN_FLEX_START; - node_0->style.dimensions[CSS_WIDTH] = 100; - node_0->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.align_self = CSS_ALIGN_FLEX_START; - node_1->style.flex = 2.5; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.align_self = CSS_ALIGN_FLEX_START; - node_1->style.flex = 7.5; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 100; - node_0->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 25; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 25; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 75; - } - } - - test("should layout with arbitrary flex", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN_REVERSE; - node_0->style.align_self = CSS_ALIGN_FLEX_START; - node_0->style.dimensions[CSS_WIDTH] = 100; - node_0->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.align_self = CSS_ALIGN_FLEX_START; - node_1->style.flex = 2.5; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.align_self = CSS_ALIGN_FLEX_START; - node_1->style.flex = 7.5; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 100; - node_0->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 75; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 25; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 75; - } - } - - test("should layout with arbitrary flex in reverse", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN_REVERSE; - node_0->style.align_self = CSS_ALIGN_FLEX_START; - node_0->style.dimensions[CSS_WIDTH] = 100; - node_0->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.align_self = CSS_ALIGN_FLEX_START; - node_1->style.flex = -2.5; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.align_self = CSS_ALIGN_FLEX_START; - node_1->style.flex = 0; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 100; - node_0->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 100; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 100; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout with negative flex in reverse", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 50; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.position_type = CSS_POSITION_ABSOLUTE; - node_1->style.position[CSS_LEFT] = 0; - node_1->style.position[CSS_RIGHT] = 0; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 50; - node_0->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 50; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 100; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 50; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout with position: absolute and another sibling", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.position_type = CSS_POSITION_ABSOLUTE; - node_1->style.position[CSS_TOP] = 0; - node_1->style.position[CSS_BOTTOM] = 20; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 0; - node_0->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 80; - } - } - - test("should calculate height properly with position: absolute top and bottom", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 200; - node_0->style.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.justify_content = CSS_JUSTIFY_CENTER; - node_1->style.position_type = CSS_POSITION_ABSOLUTE; - node_1->style.position[CSS_LEFT] = 0; - node_1->style.position[CSS_TOP] = 0; - node_1->style.position[CSS_RIGHT] = 0; - node_1->style.position[CSS_BOTTOM] = 0; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.dimensions[CSS_WIDTH] = 100; - node_2->style.dimensions[CSS_HEIGHT] = 100; - } - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 200; - node_0->layout.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 200; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 50; - node_2->layout.position[CSS_LEFT] = 0; - node_2->layout.dimensions[CSS_WIDTH] = 100; - node_2->layout.dimensions[CSS_HEIGHT] = 100; - } - } - } - - test("should layout with complicated position: absolute and justifyContent: center combo", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.position_type = CSS_POSITION_ABSOLUTE; - node_1->style.position[CSS_BOTTOM] = 0; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 0; - node_0->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 100; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should calculate top properly with position: absolute bottom", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 100; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.position_type = CSS_POSITION_ABSOLUTE; - node_1->style.position[CSS_RIGHT] = 0; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 100; - node_0->layout.dimensions[CSS_HEIGHT] = 0; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 100; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should calculate left properly with position: absolute right", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.position_type = CSS_POSITION_ABSOLUTE; - node_1->style.dimensions[CSS_HEIGHT] = 10; - node_1->style.position[CSS_BOTTOM] = 0; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 0; - node_0->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 90; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 10; - } - } - - test("should calculate top properly with position: absolute bottom and height", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 100; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.position_type = CSS_POSITION_ABSOLUTE; - node_1->style.dimensions[CSS_WIDTH] = 10; - node_1->style.position[CSS_RIGHT] = 0; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 100; - node_0->layout.dimensions[CSS_HEIGHT] = 0; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 90; - node_1->layout.dimensions[CSS_WIDTH] = 10; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should calculate left properly with position: absolute right and width", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.position_type = CSS_POSITION_ABSOLUTE; - node_1->style.dimensions[CSS_HEIGHT] = 10; - node_1->style.position[CSS_BOTTOM] = 0; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 0; - node_0->layout.dimensions[CSS_HEIGHT] = 0; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = -10; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 10; - } - } - - test("should calculate top properly with position: absolute right, width, and no parent dimensions", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.position_type = CSS_POSITION_ABSOLUTE; - node_1->style.dimensions[CSS_WIDTH] = 10; - node_1->style.position[CSS_RIGHT] = 0; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 0; - node_0->layout.dimensions[CSS_HEIGHT] = 0; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = -10; - node_1->layout.dimensions[CSS_WIDTH] = 10; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should calculate left properly with position: absolute right, width, and no parent dimensions", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.justify_content = CSS_JUSTIFY_SPACE_BETWEEN; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.border[CSS_BOTTOM] = 1; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 0; - node_0->layout.dimensions[CSS_HEIGHT] = 1; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 1; - } - } - - test("should layout border bottom inside of justify content space between container", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.justify_content = CSS_JUSTIFY_CENTER; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.margin[CSS_TOP] = -6; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 0; - node_0->layout.dimensions[CSS_HEIGHT] = 0; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = -3; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout negative margin top inside of justify content center container", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.justify_content = CSS_JUSTIFY_CENTER; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.margin[CSS_TOP] = 20; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 0; - node_0->layout.dimensions[CSS_HEIGHT] = 20; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 20; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout positive margin top inside of justify content center container", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.justify_content = CSS_JUSTIFY_FLEX_END; - node_0->style.border[CSS_BOTTOM] = 5; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 0; - node_0->layout.dimensions[CSS_HEIGHT] = 5; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout border bottom and flex end with an empty child", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 800; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.position[CSS_LEFT] = 5; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - } - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 800; - node_0->layout.dimensions[CSS_HEIGHT] = 0; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 5; - node_1->layout.dimensions[CSS_WIDTH] = 800; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 0; - node_2->layout.position[CSS_LEFT] = 0; - node_2->layout.dimensions[CSS_WIDTH] = 800; - node_2->layout.dimensions[CSS_HEIGHT] = 0; - } - } - } - - test("should layout with children of a contain with left", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.flex_wrap = CSS_WRAP; - node_0->style.dimensions[CSS_WIDTH] = 100; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 40; - node_1->style.dimensions[CSS_HEIGHT] = 10; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_WIDTH] = 40; - node_1->style.dimensions[CSS_HEIGHT] = 10; - node_1 = node_0->get_child(node_0->context, 2); - node_1->style.dimensions[CSS_WIDTH] = 40; - node_1->style.dimensions[CSS_HEIGHT] = 10; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 100; - node_0->layout.dimensions[CSS_HEIGHT] = 20; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 40; - node_1->layout.dimensions[CSS_HEIGHT] = 10; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 40; - node_1->layout.dimensions[CSS_WIDTH] = 40; - node_1->layout.dimensions[CSS_HEIGHT] = 10; - node_1 = node_0->get_child(node_0->context, 2); - node_1->layout.position[CSS_TOP] = 10; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 40; - node_1->layout.dimensions[CSS_HEIGHT] = 10; - } - } - - test("should layout flex-wrap", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.direction = CSS_DIRECTION_RTL; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.flex_wrap = CSS_WRAP; - node_0->style.dimensions[CSS_WIDTH] = 100; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 40; - node_1->style.dimensions[CSS_HEIGHT] = 10; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_WIDTH] = 40; - node_1->style.dimensions[CSS_HEIGHT] = 10; - node_1 = node_0->get_child(node_0->context, 2); - node_1->style.dimensions[CSS_WIDTH] = 40; - node_1->style.dimensions[CSS_HEIGHT] = 10; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 100; - node_0->layout.dimensions[CSS_HEIGHT] = 20; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 60; - node_1->layout.dimensions[CSS_WIDTH] = 40; - node_1->layout.dimensions[CSS_HEIGHT] = 10; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 20; - node_1->layout.dimensions[CSS_WIDTH] = 40; - node_1->layout.dimensions[CSS_HEIGHT] = 10; - node_1 = node_0->get_child(node_0->context, 2); - node_1->layout.position[CSS_TOP] = 10; - node_1->layout.position[CSS_LEFT] = 60; - node_1->layout.dimensions[CSS_WIDTH] = 40; - node_1->layout.dimensions[CSS_HEIGHT] = 10; - } - } - - test("should layout flex-wrap in rtl", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_wrap = CSS_WRAP; - node_0->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_HEIGHT] = 200; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 0; - node_0->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - } - } - - test("should layout flex wrap with a line bigger than container", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 100; - node_0->style.dimensions[CSS_HEIGHT] = 200; - node_0->style.maxDimensions[CSS_WIDTH] = 90; - node_0->style.maxDimensions[CSS_HEIGHT] = 190; - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 90; - node_0->layout.dimensions[CSS_HEIGHT] = 190; - } - - test("should use max bounds", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 100; - node_0->style.dimensions[CSS_HEIGHT] = 200; - node_0->style.minDimensions[CSS_WIDTH] = 110; - node_0->style.minDimensions[CSS_HEIGHT] = 210; - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 110; - node_0->layout.dimensions[CSS_HEIGHT] = 210; - } - - test("should use min bounds", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 100; - node_0->style.dimensions[CSS_HEIGHT] = 200; - node_0->style.maxDimensions[CSS_WIDTH] = 90; - node_0->style.maxDimensions[CSS_HEIGHT] = 190; - node_0->style.minDimensions[CSS_WIDTH] = 110; - node_0->style.minDimensions[CSS_HEIGHT] = 210; - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 110; - node_0->layout.dimensions[CSS_HEIGHT] = 210; - } - - test("should use min bounds over max bounds", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 100; - node_0->style.dimensions[CSS_HEIGHT] = 200; - node_0->style.maxDimensions[CSS_WIDTH] = 80; - node_0->style.maxDimensions[CSS_HEIGHT] = 180; - node_0->style.minDimensions[CSS_WIDTH] = 90; - node_0->style.minDimensions[CSS_HEIGHT] = 190; - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 90; - node_0->layout.dimensions[CSS_HEIGHT] = 190; - } - - test("should use min bounds over max bounds and natural width", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 100; - node_0->style.dimensions[CSS_HEIGHT] = 200; - node_0->style.minDimensions[CSS_WIDTH] = -10; - node_0->style.minDimensions[CSS_HEIGHT] = -20; - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 100; - node_0->layout.dimensions[CSS_HEIGHT] = 200; - } - - test("should ignore negative min bounds", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 100; - node_0->style.dimensions[CSS_HEIGHT] = 200; - node_0->style.maxDimensions[CSS_WIDTH] = -10; - node_0->style.maxDimensions[CSS_HEIGHT] = -20; - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 100; - node_0->layout.dimensions[CSS_HEIGHT] = 200; - } - - test("should ignore negative max bounds", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.maxDimensions[CSS_WIDTH] = 30; - node_0->style.maxDimensions[CSS_HEIGHT] = 10; - node_0->style.padding[CSS_LEFT] = 20; - node_0->style.padding[CSS_TOP] = 15; - node_0->style.padding[CSS_RIGHT] = 20; - node_0->style.padding[CSS_BOTTOM] = 15; - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 40; - node_0->layout.dimensions[CSS_HEIGHT] = 30; - } - - test("should use padded size over max bounds", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.minDimensions[CSS_WIDTH] = 50; - node_0->style.minDimensions[CSS_HEIGHT] = 40; - node_0->style.padding[CSS_LEFT] = 20; - node_0->style.padding[CSS_TOP] = 15; - node_0->style.padding[CSS_RIGHT] = 20; - node_0->style.padding[CSS_BOTTOM] = 15; - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 50; - node_0->layout.dimensions[CSS_HEIGHT] = 40; - } - - test("should use min size over padded size", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.dimensions[CSS_WIDTH] = 300; - node_0->style.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex = 1; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.flex = 1; - node_1->style.minDimensions[CSS_WIDTH] = 200; - node_1 = node_0->get_child(node_0->context, 2); - node_1->style.flex = 1; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 300; - node_0->layout.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 50; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 50; - node_1->layout.dimensions[CSS_WIDTH] = 200; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - node_1 = node_0->get_child(node_0->context, 2); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 250; - node_1->layout.dimensions[CSS_WIDTH] = 50; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - } - } - - test("should override flex direction size with min bounds", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.direction = CSS_DIRECTION_RTL; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.dimensions[CSS_WIDTH] = 300; - node_0->style.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex = 1; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.flex = 1; - node_1->style.minDimensions[CSS_WIDTH] = 200; - node_1 = node_0->get_child(node_0->context, 2); - node_1->style.flex = 1; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 300; - node_0->layout.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 250; - node_1->layout.dimensions[CSS_WIDTH] = 50; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 50; - node_1->layout.dimensions[CSS_WIDTH] = 200; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - node_1 = node_0->get_child(node_0->context, 2); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 50; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - } - } - - test("should override flex direction size with min bounds in rtl", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.dimensions[CSS_WIDTH] = 300; - node_0->style.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex = 1; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.flex = 1; - node_1->style.maxDimensions[CSS_WIDTH] = 110; - node_1->style.minDimensions[CSS_WIDTH] = 90; - node_1 = node_0->get_child(node_0->context, 2); - node_1->style.flex = 1; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 300; - node_0->layout.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 100; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - node_1 = node_0->get_child(node_0->context, 2); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 200; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - } - } - - test("should not override flex direction size within bounds", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.direction = CSS_DIRECTION_RTL; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.dimensions[CSS_WIDTH] = 300; - node_0->style.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex = 1; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.flex = 1; - node_1->style.maxDimensions[CSS_WIDTH] = 110; - node_1->style.minDimensions[CSS_WIDTH] = 90; - node_1 = node_0->get_child(node_0->context, 2); - node_1->style.flex = 1; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 300; - node_0->layout.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 200; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 100; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - node_1 = node_0->get_child(node_0->context, 2); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - } - } - - test("should not override flex direction size within bounds in rtl", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.dimensions[CSS_WIDTH] = 300; - node_0->style.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex = 1; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.flex = 1; - node_1->style.maxDimensions[CSS_WIDTH] = 60; - node_1 = node_0->get_child(node_0->context, 2); - node_1->style.flex = 1; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 300; - node_0->layout.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 120; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 120; - node_1->layout.dimensions[CSS_WIDTH] = 60; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - node_1 = node_0->get_child(node_0->context, 2); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 180; - node_1->layout.dimensions[CSS_WIDTH] = 120; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - } - } - - test("should override flex direction size with max bounds", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.direction = CSS_DIRECTION_RTL; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.dimensions[CSS_WIDTH] = 300; - node_0->style.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex = 1; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.flex = 1; - node_1->style.maxDimensions[CSS_WIDTH] = 60; - node_1 = node_0->get_child(node_0->context, 2); - node_1->style.flex = 1; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 300; - node_0->layout.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 180; - node_1->layout.dimensions[CSS_WIDTH] = 120; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 120; - node_1->layout.dimensions[CSS_WIDTH] = 60; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - node_1 = node_0->get_child(node_0->context, 2); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 120; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - } - } - - test("should override flex direction size with max bounds in rtl", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.dimensions[CSS_WIDTH] = 300; - node_0->style.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex = 1; - node_1->style.maxDimensions[CSS_WIDTH] = 60; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.flex = 1; - node_1->style.maxDimensions[CSS_WIDTH] = 60; - node_1 = node_0->get_child(node_0->context, 2); - node_1->style.flex = 1; - node_1->style.maxDimensions[CSS_WIDTH] = 60; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 300; - node_0->layout.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 60; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 60; - node_1->layout.dimensions[CSS_WIDTH] = 60; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - node_1 = node_0->get_child(node_0->context, 2); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 120; - node_1->layout.dimensions[CSS_WIDTH] = 60; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - } - } - - test("should ignore flex size if fully max bound", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.direction = CSS_DIRECTION_RTL; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.dimensions[CSS_WIDTH] = 300; - node_0->style.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex = 1; - node_1->style.maxDimensions[CSS_WIDTH] = 60; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.flex = 1; - node_1->style.maxDimensions[CSS_WIDTH] = 60; - node_1 = node_0->get_child(node_0->context, 2); - node_1->style.flex = 1; - node_1->style.maxDimensions[CSS_WIDTH] = 60; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 300; - node_0->layout.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 240; - node_1->layout.dimensions[CSS_WIDTH] = 60; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 180; - node_1->layout.dimensions[CSS_WIDTH] = 60; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - node_1 = node_0->get_child(node_0->context, 2); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 120; - node_1->layout.dimensions[CSS_WIDTH] = 60; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - } - } - - test("should ignore flex size if fully max bound in rtl", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.dimensions[CSS_WIDTH] = 300; - node_0->style.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex = 1; - node_1->style.minDimensions[CSS_WIDTH] = 120; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.flex = 1; - node_1->style.minDimensions[CSS_WIDTH] = 120; - node_1 = node_0->get_child(node_0->context, 2); - node_1->style.flex = 1; - node_1->style.minDimensions[CSS_WIDTH] = 120; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 300; - node_0->layout.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 120; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 120; - node_1->layout.dimensions[CSS_WIDTH] = 120; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - node_1 = node_0->get_child(node_0->context, 2); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 240; - node_1->layout.dimensions[CSS_WIDTH] = 120; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - } - } - - test("should ignore flex size if fully min bound", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.direction = CSS_DIRECTION_RTL; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.dimensions[CSS_WIDTH] = 300; - node_0->style.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex = 1; - node_1->style.minDimensions[CSS_WIDTH] = 120; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.flex = 1; - node_1->style.minDimensions[CSS_WIDTH] = 120; - node_1 = node_0->get_child(node_0->context, 2); - node_1->style.flex = 1; - node_1->style.minDimensions[CSS_WIDTH] = 120; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 300; - node_0->layout.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 180; - node_1->layout.dimensions[CSS_WIDTH] = 120; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 60; - node_1->layout.dimensions[CSS_WIDTH] = 120; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - node_1 = node_0->get_child(node_0->context, 2); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = -60; - node_1->layout.dimensions[CSS_WIDTH] = 120; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - } - } - - test("should ignore flex size if fully min bound in rtl", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 300; - node_0->style.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex = 1; - node_1->style.maxDimensions[CSS_WIDTH] = 310; - node_1->style.minDimensions[CSS_WIDTH] = 290; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 300; - node_0->layout.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 300; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - } - } - - test("should pre-fill child size within bounds", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 300; - node_0->style.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex = 1; - node_1->style.maxDimensions[CSS_WIDTH] = 290; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 300; - node_0->layout.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 290; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - } - } - - test("should pre-fill child size within max bound", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 300; - node_0->style.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex = 1; - node_1->style.minDimensions[CSS_WIDTH] = 310; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 300; - node_0->layout.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 310; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - } - } - - test("should pre-fill child size within min bounds", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.maxDimensions[CSS_WIDTH] = 300; - node_0->style.maxDimensions[CSS_HEIGHT] = 700; - node_0->style.minDimensions[CSS_WIDTH] = 100; - node_0->style.minDimensions[CSS_HEIGHT] = 500; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 200; - node_1->style.dimensions[CSS_HEIGHT] = 300; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_WIDTH] = 200; - node_1->style.dimensions[CSS_HEIGHT] = 300; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 200; - node_0->layout.dimensions[CSS_HEIGHT] = 600; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 200; - node_1->layout.dimensions[CSS_HEIGHT] = 300; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 300; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 200; - node_1->layout.dimensions[CSS_HEIGHT] = 300; - } - } - - test("should set parents size based on bounded children", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.maxDimensions[CSS_WIDTH] = 100; - node_0->style.maxDimensions[CSS_HEIGHT] = 500; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 200; - node_1->style.dimensions[CSS_HEIGHT] = 300; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_WIDTH] = 200; - node_1->style.dimensions[CSS_HEIGHT] = 300; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 100; - node_0->layout.dimensions[CSS_HEIGHT] = 500; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 200; - node_1->layout.dimensions[CSS_HEIGHT] = 300; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 300; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 200; - node_1->layout.dimensions[CSS_HEIGHT] = 300; - } - } - - test("should set parents size based on max bounded children", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.minDimensions[CSS_WIDTH] = 300; - node_0->style.minDimensions[CSS_HEIGHT] = 700; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 200; - node_1->style.dimensions[CSS_HEIGHT] = 300; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_WIDTH] = 200; - node_1->style.dimensions[CSS_HEIGHT] = 300; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 300; - node_0->layout.dimensions[CSS_HEIGHT] = 700; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 200; - node_1->layout.dimensions[CSS_HEIGHT] = 300; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 300; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 200; - node_1->layout.dimensions[CSS_HEIGHT] = 300; - } - } - - test("should set parents size based on min bounded children", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.align_items = CSS_ALIGN_STRETCH; - node_0->style.dimensions[CSS_WIDTH] = 1000; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1->style.maxDimensions[CSS_WIDTH] = 1100; - node_1->style.maxDimensions[CSS_HEIGHT] = 110; - node_1->style.minDimensions[CSS_WIDTH] = 900; - node_1->style.minDimensions[CSS_HEIGHT] = 90; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 1000; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - } - } - - test("should keep stretched size within bounds", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.align_items = CSS_ALIGN_STRETCH; - node_0->style.dimensions[CSS_WIDTH] = 1000; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1->style.maxDimensions[CSS_WIDTH] = 900; - node_1->style.maxDimensions[CSS_HEIGHT] = 90; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 90; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 900; - node_1->layout.dimensions[CSS_HEIGHT] = 90; - } - } - - test("should keep stretched size within max bounds", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.align_items = CSS_ALIGN_STRETCH; - node_0->style.dimensions[CSS_WIDTH] = 1000; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1->style.minDimensions[CSS_WIDTH] = 1100; - node_1->style.minDimensions[CSS_HEIGHT] = 110; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 110; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 1100; - node_1->layout.dimensions[CSS_HEIGHT] = 110; - } - } - - test("should keep stretched size within min bounds", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.dimensions[CSS_WIDTH] = 1000; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1->style.minDimensions[CSS_WIDTH] = 100; - node_1->style.minDimensions[CSS_HEIGHT] = 110; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 110; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 110; - } - } - - test("should keep cross axis size within min bounds", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.direction = CSS_DIRECTION_RTL; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.dimensions[CSS_WIDTH] = 1000; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1->style.minDimensions[CSS_WIDTH] = 100; - node_1->style.minDimensions[CSS_HEIGHT] = 110; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 110; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 900; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 110; - } - } - - test("should keep cross axis size within min bounds in rtl", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.position_type = CSS_POSITION_ABSOLUTE; - node_1->style.maxDimensions[CSS_WIDTH] = 500; - node_1->style.maxDimensions[CSS_HEIGHT] = 600; - node_1->style.position[CSS_LEFT] = 100; - node_1->style.position[CSS_TOP] = 100; - node_1->style.position[CSS_RIGHT] = 100; - node_1->style.position[CSS_BOTTOM] = 100; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 100; - node_1->layout.position[CSS_LEFT] = 100; - node_1->layout.dimensions[CSS_WIDTH] = 500; - node_1->layout.dimensions[CSS_HEIGHT] = 600; - } - } - - test("should layout node with position absolute, top and left and max bounds", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.position_type = CSS_POSITION_ABSOLUTE; - node_1->style.minDimensions[CSS_WIDTH] = 900; - node_1->style.minDimensions[CSS_HEIGHT] = 1000; - node_1->style.position[CSS_LEFT] = 100; - node_1->style.position[CSS_TOP] = 100; - node_1->style.position[CSS_RIGHT] = 100; - node_1->style.position[CSS_BOTTOM] = 100; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 100; - node_1->layout.position[CSS_LEFT] = 100; - node_1->layout.dimensions[CSS_WIDTH] = 900; - node_1->layout.dimensions[CSS_HEIGHT] = 1000; - } - } - - test("should layout node with position absolute, top and left and min bounds", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.justify_content = CSS_JUSTIFY_CENTER; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex = 1; - node_1->style.dimensions[CSS_HEIGHT] = 1000; - node_1->style.maxDimensions[CSS_WIDTH] = 600; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 200; - node_1->layout.dimensions[CSS_WIDTH] = 600; - node_1->layout.dimensions[CSS_HEIGHT] = 1000; - } - } - - test("should center flexible item with max size", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.dimensions[CSS_WIDTH] = 1000; - node_0->style.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex = 1; - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 1000; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.flex = 1; - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 1000; - node_1->style.maxDimensions[CSS_WIDTH] = 200; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 1000; - node_0->layout.dimensions[CSS_HEIGHT] = 1000; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 800; - node_1->layout.dimensions[CSS_HEIGHT] = 1000; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 800; - node_1->layout.dimensions[CSS_WIDTH] = 200; - node_1->layout.dimensions[CSS_HEIGHT] = 1000; - } - } - - test("should correctly size flexible items with flex basis and a max width", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 400; - node_0->style.dimensions[CSS_HEIGHT] = 400; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.position_type = CSS_POSITION_ABSOLUTE; - node_1->style.padding[CSS_LEFT] = 10; - node_1->style.padding[CSS_TOP] = 10; - node_1->style.padding[CSS_RIGHT] = 10; - node_1->style.padding[CSS_BOTTOM] = 10; - node_1->style.padding[CSS_START] = 10; - node_1->style.padding[CSS_END] = 10; - node_1->style.position[CSS_LEFT] = 100; - node_1->style.position[CSS_TOP] = 100; - node_1->style.position[CSS_RIGHT] = 100; - node_1->style.position[CSS_BOTTOM] = 100; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.position_type = CSS_POSITION_ABSOLUTE; - node_2->style.position[CSS_LEFT] = 10; - node_2->style.position[CSS_TOP] = 10; - node_2->style.position[CSS_RIGHT] = 10; - node_2->style.position[CSS_BOTTOM] = 10; - } - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 400; - node_0->layout.dimensions[CSS_HEIGHT] = 400; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 100; - node_1->layout.position[CSS_LEFT] = 100; - node_1->layout.dimensions[CSS_WIDTH] = 200; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 10; - node_2->layout.position[CSS_LEFT] = 10; - node_2->layout.dimensions[CSS_WIDTH] = 180; - node_2->layout.dimensions[CSS_HEIGHT] = 180; - } - } - } - - test("should layout absolutely positioned node with absolutely positioned padded parent", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 400; - node_0->style.dimensions[CSS_HEIGHT] = 400; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.position_type = CSS_POSITION_ABSOLUTE; - node_1->style.padding[CSS_LEFT] = 10; - node_1->style.padding[CSS_TOP] = 10; - node_1->style.padding[CSS_RIGHT] = 10; - node_1->style.padding[CSS_BOTTOM] = 10; - node_1->style.padding[CSS_START] = 10; - node_1->style.padding[CSS_END] = 10; - node_1->style.border[CSS_LEFT] = 1; - node_1->style.border[CSS_TOP] = 1; - node_1->style.border[CSS_RIGHT] = 1; - node_1->style.border[CSS_BOTTOM] = 1; - node_1->style.border[CSS_START] = 1; - node_1->style.border[CSS_END] = 1; - node_1->style.position[CSS_LEFT] = 100; - node_1->style.position[CSS_TOP] = 100; - node_1->style.position[CSS_RIGHT] = 100; - node_1->style.position[CSS_BOTTOM] = 100; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.position_type = CSS_POSITION_ABSOLUTE; - node_2->style.position[CSS_LEFT] = 10; - node_2->style.position[CSS_TOP] = 10; - node_2->style.position[CSS_RIGHT] = 10; - node_2->style.position[CSS_BOTTOM] = 10; - } - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 400; - node_0->layout.dimensions[CSS_HEIGHT] = 400; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 100; - node_1->layout.position[CSS_LEFT] = 100; - node_1->layout.dimensions[CSS_WIDTH] = 200; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 11; - node_2->layout.position[CSS_LEFT] = 11; - node_2->layout.dimensions[CSS_WIDTH] = 178; - node_2->layout.dimensions[CSS_HEIGHT] = 178; - } - } - } - - test("should layout absolutely positioned node with absolutely positioned padded and bordered parent", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 400; - node_0->style.dimensions[CSS_HEIGHT] = 400; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex = 1; - node_1->style.padding[CSS_LEFT] = 10; - node_1->style.padding[CSS_TOP] = 10; - node_1->style.padding[CSS_RIGHT] = 10; - node_1->style.padding[CSS_BOTTOM] = 10; - node_1->style.padding[CSS_START] = 10; - node_1->style.padding[CSS_END] = 10; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.position_type = CSS_POSITION_ABSOLUTE; - node_2->style.position[CSS_LEFT] = 10; - node_2->style.position[CSS_TOP] = 10; - node_2->style.position[CSS_RIGHT] = 10; - node_2->style.position[CSS_BOTTOM] = 10; - } - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 400; - node_0->layout.dimensions[CSS_HEIGHT] = 400; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 400; - node_1->layout.dimensions[CSS_HEIGHT] = 400; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 10; - node_2->layout.position[CSS_LEFT] = 10; - node_2->layout.dimensions[CSS_WIDTH] = 380; - node_2->layout.dimensions[CSS_HEIGHT] = 380; - } - } - } - - test("should layout absolutely positioned node with padded flex 1 parent", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.direction = CSS_DIRECTION_RTL; - node_0->style.dimensions[CSS_WIDTH] = 200; - node_0->style.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - init_css_node_children(node_1, 2); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.dimensions[CSS_WIDTH] = 50; - node_2->style.dimensions[CSS_HEIGHT] = 50; - node_2 = node_1->get_child(node_1->context, 1); - node_2->style.dimensions[CSS_WIDTH] = 50; - node_2->style.dimensions[CSS_HEIGHT] = 50; - } - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.direction = CSS_DIRECTION_LTR; - node_1->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - init_css_node_children(node_1, 2); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.dimensions[CSS_WIDTH] = 50; - node_2->style.dimensions[CSS_HEIGHT] = 50; - node_2 = node_1->get_child(node_1->context, 1); - node_2->style.dimensions[CSS_WIDTH] = 50; - node_2->style.dimensions[CSS_HEIGHT] = 50; - } - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 200; - node_0->layout.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 200; - node_1->layout.dimensions[CSS_HEIGHT] = 50; - init_css_node_children(node_1, 2); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 0; - node_2->layout.position[CSS_LEFT] = 150; - node_2->layout.dimensions[CSS_WIDTH] = 50; - node_2->layout.dimensions[CSS_HEIGHT] = 50; - node_2 = node_1->get_child(node_1->context, 1); - node_2->layout.position[CSS_TOP] = 0; - node_2->layout.position[CSS_LEFT] = 100; - node_2->layout.dimensions[CSS_WIDTH] = 50; - node_2->layout.dimensions[CSS_HEIGHT] = 50; - } - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 50; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 200; - node_1->layout.dimensions[CSS_HEIGHT] = 50; - init_css_node_children(node_1, 2); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 0; - node_2->layout.position[CSS_LEFT] = 0; - node_2->layout.dimensions[CSS_WIDTH] = 50; - node_2->layout.dimensions[CSS_HEIGHT] = 50; - node_2 = node_1->get_child(node_1->context, 1); - node_2->layout.position[CSS_TOP] = 0; - node_2->layout.position[CSS_LEFT] = 50; - node_2->layout.dimensions[CSS_WIDTH] = 50; - node_2->layout.dimensions[CSS_HEIGHT] = 50; - } - } - } - - test("should layout nested nodes with mixed directions", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.justify_content = CSS_JUSTIFY_SPACE_BETWEEN; - node_0->style.flex_wrap = CSS_WRAP; - node_0->style.dimensions[CSS_WIDTH] = 320; - node_0->style.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_0, 6); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 2); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 3); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 4); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 5); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 100; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 320; - node_0->layout.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_0, 6); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 110; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 2); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 220; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 3); - node_1->layout.position[CSS_TOP] = 100; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 4); - node_1->layout.position[CSS_TOP] = 100; - node_1->layout.position[CSS_LEFT] = 110; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 5); - node_1->layout.position[CSS_TOP] = 100; - node_1->layout.position[CSS_LEFT] = 220; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - } - } - - test("should correctly space wrapped nodes", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 200; - node_0->style.padding[CSS_LEFT] = 5; - node_0->style.padding[CSS_RIGHT] = 5; - node_0->style.padding[CSS_START] = 15; - node_0->style.padding[CSS_END] = 15; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_HEIGHT] = 50; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 200; - node_0->layout.dimensions[CSS_HEIGHT] = 50; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 15; - node_1->layout.dimensions[CSS_WIDTH] = 170; - node_1->layout.dimensions[CSS_HEIGHT] = 50; - } - } - - test("should give start/end padding precedence over left/right padding", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 200; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_HEIGHT] = 50; - node_1->style.margin[CSS_LEFT] = 5; - node_1->style.margin[CSS_RIGHT] = 5; - node_1->style.margin[CSS_START] = 15; - node_1->style.margin[CSS_END] = 15; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 200; - node_0->layout.dimensions[CSS_HEIGHT] = 50; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 15; - node_1->layout.dimensions[CSS_WIDTH] = 170; - node_1->layout.dimensions[CSS_HEIGHT] = 50; - } - } - - test("should give start/end margin precedence over left/right margin", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 200; - node_0->style.border[CSS_LEFT] = 5; - node_0->style.border[CSS_RIGHT] = 5; - node_0->style.border[CSS_START] = 15; - node_0->style.border[CSS_END] = 15; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_HEIGHT] = 50; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 200; - node_0->layout.dimensions[CSS_HEIGHT] = 50; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 15; - node_1->layout.dimensions[CSS_WIDTH] = 170; - node_1->layout.dimensions[CSS_HEIGHT] = 50; - } - } - - test("should give start/end border precedence over left/right border", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 200; - node_0->style.padding[CSS_START] = 15; - node_0->style.padding[CSS_END] = 5; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_HEIGHT] = 50; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 200; - node_0->layout.dimensions[CSS_HEIGHT] = 50; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 15; - node_1->layout.dimensions[CSS_WIDTH] = 180; - node_1->layout.dimensions[CSS_HEIGHT] = 50; - } - } - - test("should layout node with correct start/end padding", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.direction = CSS_DIRECTION_RTL; - node_0->style.dimensions[CSS_WIDTH] = 200; - node_0->style.padding[CSS_START] = 15; - node_0->style.padding[CSS_END] = 5; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_HEIGHT] = 50; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 200; - node_0->layout.dimensions[CSS_HEIGHT] = 50; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 5; - node_1->layout.dimensions[CSS_WIDTH] = 180; - node_1->layout.dimensions[CSS_HEIGHT] = 50; - } - } - - test("should layout node with correct start/end padding in rtl", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 200; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_HEIGHT] = 50; - node_1->style.margin[CSS_START] = 15; - node_1->style.margin[CSS_END] = 5; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 200; - node_0->layout.dimensions[CSS_HEIGHT] = 50; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 15; - node_1->layout.dimensions[CSS_WIDTH] = 180; - node_1->layout.dimensions[CSS_HEIGHT] = 50; - } - } - - test("should layout node with correct start/end margin", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 200; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.direction = CSS_DIRECTION_RTL; - node_1->style.dimensions[CSS_HEIGHT] = 50; - node_1->style.margin[CSS_START] = 15; - node_1->style.margin[CSS_END] = 5; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 200; - node_0->layout.dimensions[CSS_HEIGHT] = 50; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 5; - node_1->layout.dimensions[CSS_WIDTH] = 180; - node_1->layout.dimensions[CSS_HEIGHT] = 50; - } - } - - test("should layout node with correct start/end margin in rtl", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 200; - node_0->style.border[CSS_START] = 15; - node_0->style.border[CSS_END] = 5; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_HEIGHT] = 50; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 200; - node_0->layout.dimensions[CSS_HEIGHT] = 50; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 15; - node_1->layout.dimensions[CSS_WIDTH] = 180; - node_1->layout.dimensions[CSS_HEIGHT] = 50; - } - } - - test("should layout node with correct start/end border", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.direction = CSS_DIRECTION_RTL; - node_0->style.dimensions[CSS_WIDTH] = 200; - node_0->style.border[CSS_START] = 15; - node_0->style.border[CSS_END] = 5; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_HEIGHT] = 50; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 200; - node_0->layout.dimensions[CSS_HEIGHT] = 50; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 5; - node_1->layout.dimensions[CSS_WIDTH] = 180; - node_1->layout.dimensions[CSS_HEIGHT] = 50; - } - } - - test("should layout node with correct start/end border in rtl", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 200; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 0; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 200; - node_0->layout.dimensions[CSS_HEIGHT] = 0; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - } - } - - test("should layout node with a 0 width", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.align_items = CSS_ALIGN_FLEX_START; - node_0->style.dimensions[CSS_WIDTH] = 100; - node_0->style.dimensions[CSS_HEIGHT] = 10; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 50; - node_1->style.dimensions[CSS_HEIGHT] = 10; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN; - node_1->style.align_items = CSS_ALIGN_FLEX_START; - node_1->style.flex = 1; - node_1->style.dimensions[CSS_HEIGHT] = 10; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.flex = 1; - node_2->style.dimensions[CSS_HEIGHT] = 10; - node_2->measure = measure; - node_2->context = "measureWithMatchParent"; - } - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 100; - node_0->layout.dimensions[CSS_HEIGHT] = 10; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 50; - node_1->layout.dimensions[CSS_HEIGHT] = 10; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 50; - node_1->layout.dimensions[CSS_WIDTH] = 50; - node_1->layout.dimensions[CSS_HEIGHT] = 10; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 0; - node_2->layout.position[CSS_LEFT] = 0; - node_2->layout.dimensions[CSS_WIDTH] = 50; - node_2->layout.dimensions[CSS_HEIGHT] = 10; - } - } - } - - test("should correctly progagate size contraints from flexible parents", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.align_items = CSS_ALIGN_STRETCH; - node_0->style.dimensions[CSS_WIDTH] = 150; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_1->style.margin[CSS_LEFT] = 10; - node_1->style.margin[CSS_TOP] = 10; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - init_css_node_children(node_2, 1); - { - css_node_t *node_3; - node_3 = node_2->get_child(node_2->context, 0); - node_3->style.align_self = CSS_ALIGN_CENTER; - } - } - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_HEIGHT] = 150; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 150; - node_0->layout.dimensions[CSS_HEIGHT] = 150; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 10; - node_1->layout.position[CSS_LEFT] = 10; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 140; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 0; - node_2->layout.position[CSS_LEFT] = 0; - node_2->layout.dimensions[CSS_WIDTH] = 0; - node_2->layout.dimensions[CSS_HEIGHT] = 140; - init_css_node_children(node_2, 1); - { - css_node_t *node_3; - node_3 = node_2->get_child(node_2->context, 0); - node_3->layout.position[CSS_TOP] = 70; - node_3->layout.position[CSS_LEFT] = 0; - node_3->layout.dimensions[CSS_WIDTH] = 0; - node_3->layout.dimensions[CSS_HEIGHT] = 0; - } - } - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 10; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 150; - } - } - - test("should layout content of an item which is stretched late", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.dimensions[CSS_WIDTH] = 200; - node_2->style.dimensions[CSS_HEIGHT] = 200; - } - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.margin[CSS_LEFT] = 10; - node_1->style.margin[CSS_TOP] = 10; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - } - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 200; - node_0->layout.dimensions[CSS_HEIGHT] = 210; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 200; - node_1->layout.dimensions[CSS_HEIGHT] = 200; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 0; - node_2->layout.position[CSS_LEFT] = 0; - node_2->layout.dimensions[CSS_WIDTH] = 200; - node_2->layout.dimensions[CSS_HEIGHT] = 200; - } - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 210; - node_1->layout.position[CSS_LEFT] = 10; - node_1->layout.dimensions[CSS_WIDTH] = 190; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 0; - node_2->layout.position[CSS_LEFT] = 0; - node_2->layout.dimensions[CSS_WIDTH] = 190; - node_2->layout.dimensions[CSS_HEIGHT] = 0; - } - } - } - - test("should layout items whose positioning is determined by sibling tree branches", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.align_self = CSS_ALIGN_FLEX_START; - node_1->style.margin[CSS_LEFT] = 10; - node_1->style.margin[CSS_TOP] = 10; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.align_self = CSS_ALIGN_STRETCH; - node_1->style.dimensions[CSS_WIDTH] = 1; - node_1 = node_0->get_child(node_0->context, 2); - node_1->style.dimensions[CSS_HEIGHT] = 150; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 11; - node_0->layout.dimensions[CSS_HEIGHT] = 150; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 10; - node_1->layout.position[CSS_LEFT] = 10; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 0; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 10; - node_1->layout.dimensions[CSS_WIDTH] = 1; - node_1->layout.dimensions[CSS_HEIGHT] = 150; - node_1 = node_0->get_child(node_0->context, 2); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 11; - node_1->layout.dimensions[CSS_WIDTH] = 0; - node_1->layout.dimensions[CSS_HEIGHT] = 150; - } - } - - test("should layout child whose cross axis is undefined and whose alignSelf is stretch", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.dimensions[CSS_WIDTH] = 100; - node_2->style.dimensions[CSS_HEIGHT] = 100; - } - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_WIDTH] = 100; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN; - node_2->style.align_items = CSS_ALIGN_CENTER; - init_css_node_children(node_2, 1); - { - css_node_t *node_3; - node_3 = node_2->get_child(node_2->context, 0); - node_3->style.dimensions[CSS_WIDTH] = 50; - node_3->style.dimensions[CSS_HEIGHT] = 50; - } - } - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 200; - node_0->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 2); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 0; - node_2->layout.position[CSS_LEFT] = 0; - node_2->layout.dimensions[CSS_WIDTH] = 100; - node_2->layout.dimensions[CSS_HEIGHT] = 100; - } - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 100; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 0; - node_2->layout.position[CSS_LEFT] = 0; - node_2->layout.dimensions[CSS_WIDTH] = 100; - node_2->layout.dimensions[CSS_HEIGHT] = 50; - init_css_node_children(node_2, 1); - { - css_node_t *node_3; - node_3 = node_2->get_child(node_2->context, 0); - node_3->layout.position[CSS_TOP] = 0; - node_3->layout.position[CSS_LEFT] = 25; - node_3->layout.dimensions[CSS_WIDTH] = 50; - node_3->layout.dimensions[CSS_HEIGHT] = 50; - } - } - } - } - - test("should center items correctly inside a stretched layout", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 100; - node_0->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex = -1; - node_1->style.dimensions[CSS_WIDTH] = 100; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.dimensions[CSS_WIDTH] = 100; - node_2->style.dimensions[CSS_HEIGHT] = 25; - } - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 100; - node_0->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 25; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 0; - node_2->layout.position[CSS_LEFT] = 0; - node_2->layout.dimensions[CSS_WIDTH] = 100; - node_2->layout.dimensions[CSS_HEIGHT] = 25; - } - } - } - - test("should not shrink column node when there is space left over", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 100; - node_0->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex = -1; - node_1->style.dimensions[CSS_WIDTH] = 100; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.dimensions[CSS_WIDTH] = 100; - node_2->style.dimensions[CSS_HEIGHT] = 200; - } - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 100; - node_0->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 0; - node_2->layout.position[CSS_LEFT] = 0; - node_2->layout.dimensions[CSS_WIDTH] = 100; - node_2->layout.dimensions[CSS_HEIGHT] = 200; - } - } - } - - test("should shrink column node when there is not any space left over", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 100; - node_0->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 25; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.flex = -1; - node_1->style.dimensions[CSS_WIDTH] = 100; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.dimensions[CSS_WIDTH] = 100; - node_2->style.dimensions[CSS_HEIGHT] = 30; - } - node_1 = node_0->get_child(node_0->context, 2); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 15; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 100; - node_0->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 25; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 25; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 30; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 0; - node_2->layout.position[CSS_LEFT] = 0; - node_2->layout.dimensions[CSS_WIDTH] = 100; - node_2->layout.dimensions[CSS_HEIGHT] = 30; - } - node_1 = node_0->get_child(node_0->context, 2); - node_1->layout.position[CSS_TOP] = 55; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 15; - } - } - - test("should not shrink column node with siblings when there is space left over", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 100; - node_0->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 25; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.flex = -1; - node_1->style.dimensions[CSS_WIDTH] = 100; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.dimensions[CSS_WIDTH] = 100; - node_2->style.dimensions[CSS_HEIGHT] = 80; - } - node_1 = node_0->get_child(node_0->context, 2); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 15; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 100; - node_0->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 25; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 25; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 60; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 0; - node_2->layout.position[CSS_LEFT] = 0; - node_2->layout.dimensions[CSS_WIDTH] = 100; - node_2->layout.dimensions[CSS_HEIGHT] = 80; - } - node_1 = node_0->get_child(node_0->context, 2); - node_1->layout.position[CSS_TOP] = 85; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 15; - } - } - - test("should shrink column node with siblings when there is not any space left over", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.dimensions[CSS_WIDTH] = 100; - node_0->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex = -1; - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 30; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 40; - node_1 = node_0->get_child(node_0->context, 2); - node_1->style.flex = -1; - node_1->style.dimensions[CSS_WIDTH] = 100; - node_1->style.dimensions[CSS_HEIGHT] = 50; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 100; - node_0->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 22.5; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 22.5; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 40; - node_1 = node_0->get_child(node_0->context, 2); - node_1->layout.position[CSS_TOP] = 62.5; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 37.5; - } - } - - test("should shrink column nodes proportional to their main size when there is not any space left over", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.dimensions[CSS_WIDTH] = 100; - node_0->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex = -1; - node_1->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.dimensions[CSS_WIDTH] = 25; - node_2->style.dimensions[CSS_HEIGHT] = 100; - } - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 100; - node_0->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 25; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 0; - node_2->layout.position[CSS_LEFT] = 0; - node_2->layout.dimensions[CSS_WIDTH] = 25; - node_2->layout.dimensions[CSS_HEIGHT] = 100; - } - } - } - - test("should not shrink visible row node when there is space left over", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.dimensions[CSS_WIDTH] = 100; - node_0->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex = -1; - node_1->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.dimensions[CSS_WIDTH] = 200; - node_2->style.dimensions[CSS_HEIGHT] = 100; - } - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 100; - node_0->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 0; - node_2->layout.position[CSS_LEFT] = 0; - node_2->layout.dimensions[CSS_WIDTH] = 200; - node_2->layout.dimensions[CSS_HEIGHT] = 100; - } - } - } - - test("should shrink visible row node when there is not any space left over", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.dimensions[CSS_WIDTH] = 100; - node_0->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 25; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.flex = -1; - node_1->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.dimensions[CSS_WIDTH] = 30; - node_2->style.dimensions[CSS_HEIGHT] = 100; - } - node_1 = node_0->get_child(node_0->context, 2); - node_1->style.dimensions[CSS_WIDTH] = 15; - node_1->style.dimensions[CSS_HEIGHT] = 100; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 100; - node_0->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 25; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 25; - node_1->layout.dimensions[CSS_WIDTH] = 30; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 0; - node_2->layout.position[CSS_LEFT] = 0; - node_2->layout.dimensions[CSS_WIDTH] = 30; - node_2->layout.dimensions[CSS_HEIGHT] = 100; - } - node_1 = node_0->get_child(node_0->context, 2); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 55; - node_1->layout.dimensions[CSS_WIDTH] = 15; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - } - } - - test("should not shrink visible row node with siblings when there is space left over", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.dimensions[CSS_WIDTH] = 100; - node_0->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 25; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.flex = -1; - node_1->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.dimensions[CSS_WIDTH] = 80; - node_2->style.dimensions[CSS_HEIGHT] = 100; - } - node_1 = node_0->get_child(node_0->context, 2); - node_1->style.dimensions[CSS_WIDTH] = 15; - node_1->style.dimensions[CSS_HEIGHT] = 100; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 100; - node_0->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 25; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 25; - node_1->layout.dimensions[CSS_WIDTH] = 60; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 0; - node_2->layout.position[CSS_LEFT] = 0; - node_2->layout.dimensions[CSS_WIDTH] = 80; - node_2->layout.dimensions[CSS_HEIGHT] = 100; - } - node_1 = node_0->get_child(node_0->context, 2); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 85; - node_1->layout.dimensions[CSS_WIDTH] = 15; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - } - } - - test("should shrink visible row node with siblings when there is not any space left over", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.dimensions[CSS_WIDTH] = 100; - node_0->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.flex = -1; - node_1->style.dimensions[CSS_WIDTH] = 30; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_WIDTH] = 40; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 2); - node_1->style.flex = -1; - node_1->style.dimensions[CSS_WIDTH] = 50; - node_1->style.dimensions[CSS_HEIGHT] = 100; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 100; - node_0->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 22.5; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 22.5; - node_1->layout.dimensions[CSS_WIDTH] = 40; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 2); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 62.5; - node_1->layout.dimensions[CSS_WIDTH] = 37.5; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - } - } - - test("should shrink visible row nodes when there is not any space left over", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.dimensions[CSS_WIDTH] = 100; - node_0->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.overflow = CSS_OVERFLOW_HIDDEN; - node_1->style.flex = -1; - node_1->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.dimensions[CSS_WIDTH] = 25; - node_2->style.dimensions[CSS_HEIGHT] = 100; - } - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 100; - node_0->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 25; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 0; - node_2->layout.position[CSS_LEFT] = 0; - node_2->layout.dimensions[CSS_WIDTH] = 25; - node_2->layout.dimensions[CSS_HEIGHT] = 100; - } - } - } - - test("should not shrink hidden row node when there is space left over", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.dimensions[CSS_WIDTH] = 100; - node_0->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.overflow = CSS_OVERFLOW_HIDDEN; - node_1->style.flex = -1; - node_1->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.dimensions[CSS_WIDTH] = 200; - node_2->style.dimensions[CSS_HEIGHT] = 100; - } - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 100; - node_0->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 1); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 0; - node_2->layout.position[CSS_LEFT] = 0; - node_2->layout.dimensions[CSS_WIDTH] = 200; - node_2->layout.dimensions[CSS_HEIGHT] = 100; - } - } - } - - test("should shrink hidden row node when there is not any space left over", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.dimensions[CSS_WIDTH] = 100; - node_0->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 25; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.overflow = CSS_OVERFLOW_HIDDEN; - node_1->style.flex = -1; - node_1->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.dimensions[CSS_WIDTH] = 30; - node_2->style.dimensions[CSS_HEIGHT] = 100; - } - node_1 = node_0->get_child(node_0->context, 2); - node_1->style.dimensions[CSS_WIDTH] = 15; - node_1->style.dimensions[CSS_HEIGHT] = 100; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 100; - node_0->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 25; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 25; - node_1->layout.dimensions[CSS_WIDTH] = 30; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 0; - node_2->layout.position[CSS_LEFT] = 0; - node_2->layout.dimensions[CSS_WIDTH] = 30; - node_2->layout.dimensions[CSS_HEIGHT] = 100; - } - node_1 = node_0->get_child(node_0->context, 2); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 55; - node_1->layout.dimensions[CSS_WIDTH] = 15; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - } - } - - test("should not shrink hidden row node with siblings when there is space left over", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.dimensions[CSS_WIDTH] = 100; - node_0->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 25; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.overflow = CSS_OVERFLOW_HIDDEN; - node_1->style.flex = -1; - node_1->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.dimensions[CSS_WIDTH] = 80; - node_2->style.dimensions[CSS_HEIGHT] = 100; - } - node_1 = node_0->get_child(node_0->context, 2); - node_1->style.dimensions[CSS_WIDTH] = 15; - node_1->style.dimensions[CSS_HEIGHT] = 100; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 100; - node_0->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 25; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 25; - node_1->layout.dimensions[CSS_WIDTH] = 60; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 0; - node_2->layout.position[CSS_LEFT] = 0; - node_2->layout.dimensions[CSS_WIDTH] = 80; - node_2->layout.dimensions[CSS_HEIGHT] = 100; - } - node_1 = node_0->get_child(node_0->context, 2); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 85; - node_1->layout.dimensions[CSS_WIDTH] = 15; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - } - } - - test("should shrink hidden row node with siblings when there is not any space left over", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.dimensions[CSS_WIDTH] = 100; - node_0->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.overflow = CSS_OVERFLOW_HIDDEN; - node_1->style.flex = -1; - node_1->style.dimensions[CSS_WIDTH] = 30; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_WIDTH] = 40; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 2); - node_1->style.overflow = CSS_OVERFLOW_HIDDEN; - node_1->style.flex = -1; - node_1->style.dimensions[CSS_WIDTH] = 50; - node_1->style.dimensions[CSS_HEIGHT] = 100; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 100; - node_0->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 22.5; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 22.5; - node_1->layout.dimensions[CSS_WIDTH] = 40; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 2); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 62.5; - node_1->layout.dimensions[CSS_WIDTH] = 37.5; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - } - } - - test("should shrink hidden row nodes proportional to their main size when there is not any space left over", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.dimensions[CSS_WIDTH] = 213; - node_0->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 25; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_1->style.align_items = CSS_ALIGN_FLEX_START; - node_1->style.flex = -1; - node_1->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->measure = measure; - node_2->context = "loooooooooong with space"; - } - node_1 = node_0->get_child(node_0->context, 2); - node_1->style.dimensions[CSS_WIDTH] = 15; - node_1->style.dimensions[CSS_HEIGHT] = 100; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 213; - node_0->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 25; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 25; - node_1->layout.dimensions[CSS_WIDTH] = 172; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 0; - node_2->layout.position[CSS_LEFT] = 0; - node_2->layout.dimensions[CSS_WIDTH] = 172; - node_2->layout.dimensions[CSS_HEIGHT] = 18; - } - node_1 = node_0->get_child(node_0->context, 2); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 197; - node_1->layout.dimensions[CSS_WIDTH] = 15; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - } - } - - test("should not shrink text node with siblings when there is space left over", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.dimensions[CSS_WIDTH] = 140; - node_0->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 25; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_1->style.align_items = CSS_ALIGN_FLEX_START; - node_1->style.flex = -1; - node_1->style.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->style.flex = -1; - node_2->measure = measure; - node_2->context = "loooooooooong with space"; - } - node_1 = node_0->get_child(node_0->context, 2); - node_1->style.dimensions[CSS_WIDTH] = 15; - node_1->style.dimensions[CSS_HEIGHT] = 100; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 140; - node_0->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_0, 3); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 0; - node_1->layout.dimensions[CSS_WIDTH] = 25; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 25; - node_1->layout.dimensions[CSS_WIDTH] = 100; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - init_css_node_children(node_1, 1); - { - css_node_t *node_2; - node_2 = node_1->get_child(node_1->context, 0); - node_2->layout.position[CSS_TOP] = 0; - node_2->layout.position[CSS_LEFT] = 0; - node_2->layout.dimensions[CSS_WIDTH] = 100; - node_2->layout.dimensions[CSS_HEIGHT] = 36; - } - node_1 = node_0->get_child(node_0->context, 2); - node_1->layout.position[CSS_TOP] = 0; - node_1->layout.position[CSS_LEFT] = 125; - node_1->layout.dimensions[CSS_WIDTH] = 15; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - } - } - - test("should shrink text node with siblings when there is not any space left over", root_node, root_layout); - } - - { - css_node_t *root_node = new_test_css_node(); - { - css_node_t *node_0 = root_node; - node_0->style.flex_direction = CSS_FLEX_DIRECTION_ROW; - node_0->style.align_content = CSS_ALIGN_STRETCH; - node_0->style.align_items = CSS_ALIGN_FLEX_START; - node_0->style.flex_wrap = CSS_WRAP; - node_0->style.dimensions[CSS_WIDTH] = 300; - node_0->style.dimensions[CSS_HEIGHT] = 380; - init_css_node_children(node_0, 15); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->style.dimensions[CSS_WIDTH] = 50; - node_1->style.dimensions[CSS_HEIGHT] = 50; - node_1->style.margin[CSS_LEFT] = 10; - node_1->style.margin[CSS_TOP] = 10; - node_1->style.margin[CSS_RIGHT] = 10; - node_1->style.margin[CSS_BOTTOM] = 10; - node_1->style.margin[CSS_START] = 10; - node_1->style.margin[CSS_END] = 10; - node_1 = node_0->get_child(node_0->context, 1); - node_1->style.dimensions[CSS_WIDTH] = 50; - node_1->style.dimensions[CSS_HEIGHT] = 50; - node_1->style.margin[CSS_LEFT] = 10; - node_1->style.margin[CSS_TOP] = 10; - node_1->style.margin[CSS_RIGHT] = 10; - node_1->style.margin[CSS_BOTTOM] = 10; - node_1->style.margin[CSS_START] = 10; - node_1->style.margin[CSS_END] = 10; - node_1 = node_0->get_child(node_0->context, 2); - node_1->style.dimensions[CSS_WIDTH] = 50; - node_1->style.dimensions[CSS_HEIGHT] = 50; - node_1->style.margin[CSS_LEFT] = 10; - node_1->style.margin[CSS_TOP] = 10; - node_1->style.margin[CSS_RIGHT] = 10; - node_1->style.margin[CSS_BOTTOM] = 10; - node_1->style.margin[CSS_START] = 10; - node_1->style.margin[CSS_END] = 10; - node_1 = node_0->get_child(node_0->context, 3); - node_1->style.dimensions[CSS_WIDTH] = 50; - node_1->style.dimensions[CSS_HEIGHT] = 50; - node_1->style.margin[CSS_LEFT] = 10; - node_1->style.margin[CSS_TOP] = 10; - node_1->style.margin[CSS_RIGHT] = 10; - node_1->style.margin[CSS_BOTTOM] = 10; - node_1->style.margin[CSS_START] = 10; - node_1->style.margin[CSS_END] = 10; - node_1 = node_0->get_child(node_0->context, 4); - node_1->style.dimensions[CSS_WIDTH] = 50; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1->style.margin[CSS_LEFT] = 10; - node_1->style.margin[CSS_TOP] = 10; - node_1->style.margin[CSS_RIGHT] = 10; - node_1->style.margin[CSS_BOTTOM] = 10; - node_1->style.margin[CSS_START] = 10; - node_1->style.margin[CSS_END] = 10; - node_1 = node_0->get_child(node_0->context, 5); - node_1->style.align_self = CSS_ALIGN_FLEX_START; - node_1->style.dimensions[CSS_WIDTH] = 50; - node_1->style.dimensions[CSS_HEIGHT] = 50; - node_1->style.margin[CSS_LEFT] = 10; - node_1->style.margin[CSS_TOP] = 10; - node_1->style.margin[CSS_RIGHT] = 10; - node_1->style.margin[CSS_BOTTOM] = 10; - node_1->style.margin[CSS_START] = 10; - node_1->style.margin[CSS_END] = 10; - node_1 = node_0->get_child(node_0->context, 6); - node_1->style.dimensions[CSS_WIDTH] = 50; - node_1->style.dimensions[CSS_HEIGHT] = 50; - node_1->style.margin[CSS_LEFT] = 10; - node_1->style.margin[CSS_TOP] = 10; - node_1->style.margin[CSS_RIGHT] = 10; - node_1->style.margin[CSS_BOTTOM] = 10; - node_1->style.margin[CSS_START] = 10; - node_1->style.margin[CSS_END] = 10; - node_1 = node_0->get_child(node_0->context, 7); - node_1->style.dimensions[CSS_WIDTH] = 50; - node_1->style.dimensions[CSS_HEIGHT] = 100; - node_1->style.margin[CSS_LEFT] = 10; - node_1->style.margin[CSS_TOP] = 10; - node_1->style.margin[CSS_RIGHT] = 10; - node_1->style.margin[CSS_BOTTOM] = 10; - node_1->style.margin[CSS_START] = 10; - node_1->style.margin[CSS_END] = 10; - node_1 = node_0->get_child(node_0->context, 8); - node_1->style.dimensions[CSS_WIDTH] = 50; - node_1->style.dimensions[CSS_HEIGHT] = 50; - node_1->style.margin[CSS_LEFT] = 10; - node_1->style.margin[CSS_TOP] = 10; - node_1->style.margin[CSS_RIGHT] = 10; - node_1->style.margin[CSS_BOTTOM] = 10; - node_1->style.margin[CSS_START] = 10; - node_1->style.margin[CSS_END] = 10; - node_1 = node_0->get_child(node_0->context, 9); - node_1->style.dimensions[CSS_WIDTH] = 50; - node_1->style.dimensions[CSS_HEIGHT] = 50; - node_1->style.margin[CSS_LEFT] = 10; - node_1->style.margin[CSS_TOP] = 10; - node_1->style.margin[CSS_RIGHT] = 10; - node_1->style.margin[CSS_BOTTOM] = 10; - node_1->style.margin[CSS_START] = 10; - node_1->style.margin[CSS_END] = 10; - node_1 = node_0->get_child(node_0->context, 10); - node_1->style.align_self = CSS_ALIGN_FLEX_START; - node_1->style.dimensions[CSS_WIDTH] = 50; - node_1->style.dimensions[CSS_HEIGHT] = 50; - node_1->style.margin[CSS_LEFT] = 10; - node_1->style.margin[CSS_TOP] = 10; - node_1->style.margin[CSS_RIGHT] = 10; - node_1->style.margin[CSS_BOTTOM] = 10; - node_1->style.margin[CSS_START] = 10; - node_1->style.margin[CSS_END] = 10; - node_1 = node_0->get_child(node_0->context, 11); - node_1->style.dimensions[CSS_WIDTH] = 50; - node_1->style.dimensions[CSS_HEIGHT] = 50; - node_1->style.margin[CSS_LEFT] = 10; - node_1->style.margin[CSS_TOP] = 10; - node_1->style.margin[CSS_RIGHT] = 10; - node_1->style.margin[CSS_BOTTOM] = 10; - node_1->style.margin[CSS_START] = 10; - node_1->style.margin[CSS_END] = 10; - node_1 = node_0->get_child(node_0->context, 12); - node_1->style.dimensions[CSS_WIDTH] = 50; - node_1->style.dimensions[CSS_HEIGHT] = 50; - node_1->style.margin[CSS_LEFT] = 10; - node_1->style.margin[CSS_TOP] = 10; - node_1->style.margin[CSS_RIGHT] = 10; - node_1->style.margin[CSS_BOTTOM] = 10; - node_1->style.margin[CSS_START] = 10; - node_1->style.margin[CSS_END] = 10; - node_1 = node_0->get_child(node_0->context, 13); - node_1->style.align_self = CSS_ALIGN_FLEX_START; - node_1->style.dimensions[CSS_WIDTH] = 50; - node_1->style.dimensions[CSS_HEIGHT] = 50; - node_1->style.margin[CSS_LEFT] = 10; - node_1->style.margin[CSS_TOP] = 10; - node_1->style.margin[CSS_RIGHT] = 10; - node_1->style.margin[CSS_BOTTOM] = 10; - node_1->style.margin[CSS_START] = 10; - node_1->style.margin[CSS_END] = 10; - node_1 = node_0->get_child(node_0->context, 14); - node_1->style.dimensions[CSS_WIDTH] = 50; - node_1->style.dimensions[CSS_HEIGHT] = 50; - node_1->style.margin[CSS_LEFT] = 10; - node_1->style.margin[CSS_TOP] = 10; - node_1->style.margin[CSS_RIGHT] = 10; - node_1->style.margin[CSS_BOTTOM] = 10; - node_1->style.margin[CSS_START] = 10; - node_1->style.margin[CSS_END] = 10; - } - } - - css_node_t *root_layout = new_test_css_node(); - { - css_node_t *node_0 = root_layout; - node_0->layout.position[CSS_TOP] = 0; - node_0->layout.position[CSS_LEFT] = 0; - node_0->layout.dimensions[CSS_WIDTH] = 300; - node_0->layout.dimensions[CSS_HEIGHT] = 380; - init_css_node_children(node_0, 15); - { - css_node_t *node_1; - node_1 = node_0->get_child(node_0->context, 0); - node_1->layout.position[CSS_TOP] = 10; - node_1->layout.position[CSS_LEFT] = 10; - node_1->layout.dimensions[CSS_WIDTH] = 50; - node_1->layout.dimensions[CSS_HEIGHT] = 50; - node_1 = node_0->get_child(node_0->context, 1); - node_1->layout.position[CSS_TOP] = 10; - node_1->layout.position[CSS_LEFT] = 80; - node_1->layout.dimensions[CSS_WIDTH] = 50; - node_1->layout.dimensions[CSS_HEIGHT] = 50; - node_1 = node_0->get_child(node_0->context, 2); - node_1->layout.position[CSS_TOP] = 10; - node_1->layout.position[CSS_LEFT] = 150; - node_1->layout.dimensions[CSS_WIDTH] = 50; - node_1->layout.dimensions[CSS_HEIGHT] = 50; - node_1 = node_0->get_child(node_0->context, 3); - node_1->layout.position[CSS_TOP] = 10; - node_1->layout.position[CSS_LEFT] = 220; - node_1->layout.dimensions[CSS_WIDTH] = 50; - node_1->layout.dimensions[CSS_HEIGHT] = 50; - node_1 = node_0->get_child(node_0->context, 4); - node_1->layout.position[CSS_TOP] = 92.5; - node_1->layout.position[CSS_LEFT] = 10; - node_1->layout.dimensions[CSS_WIDTH] = 50; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 5); - node_1->layout.position[CSS_TOP] = 92.5; - node_1->layout.position[CSS_LEFT] = 80; - node_1->layout.dimensions[CSS_WIDTH] = 50; - node_1->layout.dimensions[CSS_HEIGHT] = 50; - node_1 = node_0->get_child(node_0->context, 6); - node_1->layout.position[CSS_TOP] = 92.5; - node_1->layout.position[CSS_LEFT] = 150; - node_1->layout.dimensions[CSS_WIDTH] = 50; - node_1->layout.dimensions[CSS_HEIGHT] = 50; - node_1 = node_0->get_child(node_0->context, 7); - node_1->layout.position[CSS_TOP] = 92.5; - node_1->layout.position[CSS_LEFT] = 220; - node_1->layout.dimensions[CSS_WIDTH] = 50; - node_1->layout.dimensions[CSS_HEIGHT] = 100; - node_1 = node_0->get_child(node_0->context, 8); - node_1->layout.position[CSS_TOP] = 225; - node_1->layout.position[CSS_LEFT] = 10; - node_1->layout.dimensions[CSS_WIDTH] = 50; - node_1->layout.dimensions[CSS_HEIGHT] = 50; - node_1 = node_0->get_child(node_0->context, 9); - node_1->layout.position[CSS_TOP] = 225; - node_1->layout.position[CSS_LEFT] = 80; - node_1->layout.dimensions[CSS_WIDTH] = 50; - node_1->layout.dimensions[CSS_HEIGHT] = 50; - node_1 = node_0->get_child(node_0->context, 10); - node_1->layout.position[CSS_TOP] = 225; - node_1->layout.position[CSS_LEFT] = 150; - node_1->layout.dimensions[CSS_WIDTH] = 50; - node_1->layout.dimensions[CSS_HEIGHT] = 50; - node_1 = node_0->get_child(node_0->context, 11); - node_1->layout.position[CSS_TOP] = 225; - node_1->layout.position[CSS_LEFT] = 220; - node_1->layout.dimensions[CSS_WIDTH] = 50; - node_1->layout.dimensions[CSS_HEIGHT] = 50; - node_1 = node_0->get_child(node_0->context, 12); - node_1->layout.position[CSS_TOP] = 307.5; - node_1->layout.position[CSS_LEFT] = 10; - node_1->layout.dimensions[CSS_WIDTH] = 50; - node_1->layout.dimensions[CSS_HEIGHT] = 50; - node_1 = node_0->get_child(node_0->context, 13); - node_1->layout.position[CSS_TOP] = 307.5; - node_1->layout.position[CSS_LEFT] = 80; - node_1->layout.dimensions[CSS_WIDTH] = 50; - node_1->layout.dimensions[CSS_HEIGHT] = 50; - node_1 = node_0->get_child(node_0->context, 14); - node_1->layout.position[CSS_TOP] = 307.5; - node_1->layout.position[CSS_LEFT] = 150; - node_1->layout.dimensions[CSS_WIDTH] = 50; - node_1->layout.dimensions[CSS_HEIGHT] = 50; - } - } - - test("should layout with alignContent: stretch, and alignItems: flex-start", root_node, root_layout); - } - /** END_GENERATED **/ - return tests_finished(); -} diff --git a/tests/Layout-test.js b/tests/Layout-test.js deleted file mode 100755 index 7599fd36..00000000 --- a/tests/Layout-test.js +++ /dev/null @@ -1,3049 +0,0 @@ -/** - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ -/* globals layoutTestUtils */ - -var testLayout = layoutTestUtils.testLayout; -var testLayoutAgainstDomOnly = layoutTestUtils.testLayoutAgainstDomOnly; -var testLayoutAgainstExpectedOnly = layoutTestUtils.testLayoutAgainstExpectedOnly; -var testFillNodes = layoutTestUtils.testFillNodes; -var testCanUseCachedMeasurement = layoutTestUtils.testCanUseCachedMeasurement; -var text = layoutTestUtils.text; -var texts = layoutTestUtils.texts; -var textSizes = layoutTestUtils.textSizes; -var measureWithRatio2 = layoutTestUtils.measureWithRatio2(); -var measureWithMatchParent = layoutTestUtils.measureWithMatchParent(); - -describe('Javascript Only', function() { - it('should fill root node with layout, style, and children', function() { - testFillNodes( - {}, - {layout: {width: undefined, height: undefined, top: 0, left: 0, right: 0, bottom: 0}, style: {}, children: []} - ); - }); - it('should fill root and child node with layout, style, and children', function() { - testFillNodes( - {children: [{}]}, - {layout: {width: undefined, height: undefined, top: 0, left: 0, right: 0, bottom: 0}, style: {}, children: [ - {layout: {width: undefined, height: undefined, top: 0, left: 0, right: 0, bottom: 0}, style: {}, children: []} - ]} - ); - }); - it('should not replace user-provided layout information', function() { - testFillNodes( - {layout: {width: 200}}, - {layout: {width: 200}, style: {}, children: []} - ); - }); - it('should only invoke measure function one time in simple layout', function() { - var measureInvocations = 0; - function measure(width, widthMode, height, heightMode) { - measureInvocations++; - return { width: 25, height: 25 }; - } - - testLayoutAgainstExpectedOnly( - {style: {width: 100, height: 100}, children: [ - {style: {measure: measure}} - ]}, - {width: 100, height: 100, top: 0, left: 0, children: [ - {width: 100, height: 25, top: 0, left: 0} - ]} - ); - - expect(measureInvocations).toEqual(1); - }); -}); - -describe('JavaScript Only: canUseCachedTextMeasurement', function() { - var measureModes = ['undefined', 'exactly', 'at-most']; - - var assertCanReuse = testCanUseCachedMeasurement.bind(null, true); - var assertCannotReuse = testCanUseCachedMeasurement.bind(null, false); - - it('should not reuse when width mode is "exactly" and available width != measurement', function() { - measureModes.forEach(function(widthMeasureMode) { - measureModes.forEach(function(heightMeasureMode) { - var computedWidth = 100; - var computedHeight = 200; - var availableWidth = widthMeasureMode === 'undefined' ? undefined : computedWidth; - var availableHeight = heightMeasureMode === 'undefined' ? undefined : computedHeight; - - var cacheEntry = { - availableWidth: availableWidth, widthMeasureMode: widthMeasureMode, computedWidth: computedWidth, - availableHeight: availableHeight, heightMeasureMode: heightMeasureMode, computedHeight: computedHeight - }; - - assertCannotReuse( - { - availableWidth: computedWidth - 1, widthMeasureMode: 'exactly', - availableHeight: availableHeight, heightMeasureMode: heightMeasureMode - }, - cacheEntry - ); - - assertCannotReuse( - { - availableWidth: computedWidth + 1, widthMeasureMode: 'exactly', - availableHeight: availableHeight, heightMeasureMode: heightMeasureMode - }, - cacheEntry - ); - }); - }); - }); - - it('should not reuse when height mode is "exactly" and available height != measurement', function() { - measureModes.forEach(function(widthMeasureMode) { - measureModes.forEach(function(heightMeasureMode) { - var computedWidth = 100; - var computedHeight = 200; - var availableWidth = widthMeasureMode === 'undefined' ? undefined : computedWidth; - var availableHeight = heightMeasureMode === 'undefined' ? undefined : computedHeight; - - var cacheEntry = { - availableWidth: availableWidth, widthMeasureMode: widthMeasureMode, computedWidth: computedWidth, - availableHeight: availableHeight, heightMeasureMode: heightMeasureMode, computedHeight: computedHeight - }; - - assertCannotReuse( - { - availableWidth: availableWidth, widthMeasureMode: widthMeasureMode, - availableHeight: computedHeight - 1, heightMeasureMode: 'exactly' - }, - cacheEntry - ); - - assertCannotReuse( - { - availableWidth: availableWidth, widthMeasureMode: widthMeasureMode, - availableHeight: computedHeight + 1, heightMeasureMode: 'exactly' - }, - cacheEntry - ); - }); - }); - }); - - it('should reuse exact matches', function() { - measureModes.forEach(function(widthMeasureMode) { - measureModes.forEach(function(heightMeasureMode) { - var availableWidth = widthMeasureMode === 'undefined' ? undefined : 100; - var availableHeight = heightMeasureMode === 'undefined' ? undefined : 200; - assertCanReuse( - { - availableWidth: availableWidth, widthMeasureMode: widthMeasureMode, - availableHeight: availableHeight, heightMeasureMode: heightMeasureMode - }, - { - availableWidth: availableWidth, widthMeasureMode: widthMeasureMode, computedWidth: 1, - availableHeight: availableHeight, heightMeasureMode: heightMeasureMode, computedHeight: 2 - } - ); - }); - }); - }); - - it('should reuse cache entry with unconstrained width when width mode is "exactly" and available width == measurement', function() { - measureModes.forEach(function(heightMeasureMode) { - var computedWidth = 100; - var computedHeight = 200; - var availableHeight = heightMeasureMode === 'undefined' ? undefined : computedHeight; - - assertCanReuse( - { - availableWidth: computedWidth, widthMeasureMode: 'exactly', - availableHeight: availableHeight, heightMeasureMode: heightMeasureMode - }, - { - availableWidth: undefined, widthMeasureMode: 'undefined', computedWidth: computedWidth, - availableHeight: availableHeight, heightMeasureMode: heightMeasureMode, computedHeight: computedHeight - } - ); - }); - }); - - it('should reuse cache entry with unconstrained height when height mode is "exactly" and height == measurement', function() { - measureModes.forEach(function(widthMeasureMode) { - var computedWidth = 100; - var computedHeight = 200; - var availableWidth = widthMeasureMode === 'undefined' ? undefined : computedWidth; - - assertCanReuse( - { - availableWidth: availableWidth, widthMeasureMode: widthMeasureMode, - availableHeight: computedHeight, heightMeasureMode: 'exactly' - }, - { - availableWidth: availableWidth, widthMeasureMode: widthMeasureMode, computedWidth: computedWidth, - availableHeight: undefined, heightMeasureMode: 'undefined', computedHeight: computedHeight - } - ); - }); - }); -}); - -describe('Layout', function() { - it('should layout a single node with width and height', function() { - testLayout({ - style: {width: 100, height: 200} - }, { - width: 100, height: 200, top: 0, left: 0 - }); - }); - - it('should layout node with children', function() { - testLayout( - {style: {width: 1000, height: 1000}, children: [ - {style: {width: 500, height: 500}}, - {style: {width: 250, height: 250}}, - {style: {width: 125, height: 125}} - ]}, - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 500, height: 500, top: 0, left: 0}, - {width: 250, height: 250, top: 500, left: 0}, - {width: 125, height: 125, top: 750, left: 0} - ]} - ); - }); - - it('should layout node with children in reverse', function() { - testLayout( - {style: {width: 1000, height: 1000, flexDirection: 'column-reverse'}, children: [ - {style: {width: 500, height: 500}}, - {style: {width: 250, height: 250}}, - {style: {width: 125, height: 125}} - ]}, - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 500, height: 500, top: 500, left: 0}, - {width: 250, height: 250, top: 250, left: 0}, - {width: 125, height: 125, top: 125, left: 0} - ]} - ); - }); - - it('should layout node with nested children', function() { - testLayout( - {style: {width: 1000, height: 1000}, children: [ - {style: {width: 500, height: 500}}, - {style: {width: 500, height: 500}, children: [ - {style: {width: 250, height: 250}}, - {style: {width: 250, height: 250}} - ]} - ]}, - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 500, height: 500, top: 0, left: 0}, - {width: 500, height: 500, top: 500, left: 0, children: [ - {width: 250, height: 250, top: 0, left: 0}, - {width: 250, height: 250, top: 250, left: 0} - ]} - ]} - ); - }); - - it('should layout node with nested children in reverse', function() { - testLayout( - {style: {width: 1000, height: 1000, flexDirection: 'column-reverse'}, children: [ - {style: {width: 500, height: 500}}, - {style: {width: 500, height: 500, flexDirection: 'column-reverse'}, children: [ - {style: {width: 250, height: 250}}, - {style: {width: 250, height: 250}} - ]} - ]}, - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 500, height: 500, top: 500, left: 0}, - {width: 500, height: 500, top: 0, left: 0, children: [ - {width: 250, height: 250, top: 250, left: 0}, - {width: 250, height: 250, top: 0, left: 0} - ]} - ]} - ); - }); - - it('should layout node with margin', function() { - testLayout( - {style: {width: 100, height: 200, margin: 10}}, - {width: 100, height: 200, top: 10, left: 10} - ); - }); - - it('should layout node with several children', function() { - testLayout( - {style: {width: 1000, height: 1000, margin: 10}, children: [ - {style: {width: 100, height: 100, margin: 50}}, - {style: {width: 100, height: 100, margin: 25}}, - {style: {width: 100, height: 100, margin: 10}} - ]}, - {width: 1000, height: 1000, top: 10, left: 10, children: [ - {width: 100, height: 100, top: 50, left: 50}, - {width: 100, height: 100, top: 225, left: 25}, - {width: 100, height: 100, top: 360, left: 10} - ]} - ); - }); - - it('should layout node with several children in reverse', function() { - testLayout( - {style: {width: 1000, height: 1000, flexDirection: 'column-reverse', margin: 10}, children: [ - {style: {width: 100, height: 100, margin: 50}}, - {style: {width: 100, height: 100, margin: 25}}, - {style: {width: 100, height: 100, margin: 10}} - ]}, - {width: 1000, height: 1000, top: 10, left: 10, children: [ - {width: 100, height: 100, top: 850, left: 50}, - {width: 100, height: 100, top: 675, left: 25}, - {width: 100, height: 100, top: 540, left: 10} - ]} - ); - }); - - it('should layout rtl with reverse correctly', function() { - testLayout( - {style: {width: 1000, height: 1000, direction: 'rtl', flexDirection: 'row-reverse'}, children: [ - {style: {width: 100, height: 200}}, - {style: {width: 300, height: 150}} - ]}, - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 100, height: 200, top: 0, left: 0}, - {width: 300, height: 150, top: 0, left: 100} - ]} - ); - }); - - it('should layout node with row flex direction', function() { - testLayout( - {style: {width: 1000, height: 1000, flexDirection: 'row'}, children: [ - {style: {width: 100, height: 200}}, - {style: {width: 300, height: 150}} - ]}, - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 100, height: 200, top: 0, left: 0}, - {width: 300, height: 150, top: 0, left: 100} - ]} - ); - }); - - it('should layout node with row flex direction in rtl', function() { - testLayout( - {style: {width: 1000, height: 1000, direction: 'rtl', flexDirection: 'row'}, children: [ - {style: {width: 100, height: 200}}, - {style: {width: 300, height: 150}} - ]}, - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 100, height: 200, top: 0, left: 900}, - {width: 300, height: 150, top: 0, left: 600} - ]} - ); - }); - - it('should layout node based on children main dimensions', function() { - testLayout( - {style: {width: 300}, children: [ - {style: {width: 100, height: 200}}, - {style: {width: 300, height: 150}} - ]}, - {width: 300, height: 350, top: 0, left: 0, children: [ - {width: 100, height: 200, top: 0, left: 0}, - {width: 300, height: 150, top: 200, left: 0} - ]} - ); - }); - - it('should layout node based on children main dimensions in reverse', function() { - testLayout( - {style: {width: 300, flexDirection: 'column-reverse'}, children: [ - {style: {width: 100, height: 200}}, - {style: {width: 300, height: 150}} - ]}, - {width: 300, height: 350, top: 0, left: 0, children: [ - {width: 100, height: 200, top: 150, left: 0}, - {width: 300, height: 150, top: 0, left: 0} - ]} - ); - }); - - it('should layout node with just flex', function() { - testLayout( - {style: {width: 1000, height: 1000}, children: [ - {style: {width: 100, height: 200}}, - {style: {width: 100, flex: 1}} - ]}, - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 100, height: 200, top: 0, left: 0}, - {width: 100, height: 800, top: 200, left: 0} - ]} - ); - }); - - it('should layout node with just flex in reverse', function() { - testLayout( - {style: {width: 1000, height: 1000, flexDirection: 'column-reverse'}, children: [ - {style: {width: 100, height: 200}}, - {style: {width: 100, flex: 1}} - ]}, - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 100, height: 200, top: 800, left: 0}, - {width: 100, height: 800, top: 0, left: 0} - ]} - ); - }); - - it('should layout node with flex recursively', function() { - testLayout( - {style: {width: 1000, height: 1000}, children: [ - {style: {width: 1000, flex: 1}, children: [ - {style: {width: 1000, flex: 1}, children: [ - {style: {width: 1000, flex: 1}} - ]} - ]} - ]}, - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 1000, height: 1000, top: 0, left: 0} - ]} - ]} - ]} - ); - }); - - it('should layout node with flex recursively in reverse', function() { - testLayout( - {style: {width: 1000, height: 1000, flexDirection: 'column-reverse'}, children: [ - {style: {width: 1000, flex: 1, flexDirection: 'column-reverse'}, children: [ - {style: {width: 1000, flex: 1, flexDirection: 'column-reverse'}, children: [ - {style: {width: 1000, flex: 1, flexDirection: 'column-reverse'}} - ]} - ]} - ]}, - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 1000, height: 1000, top: 0, left: 0} - ]} - ]} - ]} - ); - }); - - it('should layout node with targeted margin', function() { - testLayout( - {style: {width: 1000, height: 1000, marginTop: 10, marginLeft: 5}, children: [ - {style: {width: 100, height: 100, marginTop: 50, marginLeft: 15, marginBottom: 20}}, - {style: {width: 100, height: 100, marginLeft: 30}} - ]}, - {width: 1000, height: 1000, top: 10, left: 5, children: [ - {width: 100, height: 100, top: 50, left: 15}, - {width: 100, height: 100, top: 170, left: 30} - ]} - ); - }); - - it('should layout node with targeted margin in reverse', function() { - testLayout( - {style: {width: 1000, height: 1000, flexDirection: 'column-reverse', marginTop: 10, marginLeft: 5}, children: [ - {style: {width: 100, height: 100, marginTop: 50, marginLeft: 15, marginBottom: 20}}, - {style: {width: 100, height: 100, marginLeft: 30}} - ]}, - {width: 1000, height: 1000, top: 10, left: 5, children: [ - {width: 100, height: 100, top: 880, left: 15}, - {width: 100, height: 100, top: 730, left: 30} - ]} - ); - }); - - it('should layout node with justifyContent: flex-start', function() { - testLayout( - {style: {width: 1000, height: 1000, justifyContent: 'flex-start'}, children: [ - {style: {width: 100, height: 100}}, - {style: {width: 100, height: 100}} - ]}, - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 100, height: 100, top: 0, left: 0}, - {width: 100, height: 100, top: 100, left: 0} - ]} - ); - }); - - it('should layout node with justifyContent: flex-start in reverse', function() { - testLayout( - {style: {width: 1000, height: 1000, flexDirection: 'column-reverse', justifyContent: 'flex-start'}, children: [ - {style: {width: 100, height: 100}}, - {style: {width: 100, height: 100}} - ]}, - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 100, height: 100, top: 900, left: 0}, - {width: 100, height: 100, top: 800, left: 0} - ]} - ); - }); - - it('should layout node with justifyContent: flex-end', function() { - testLayout( - {style: {width: 1000, height: 1000, justifyContent: 'flex-end'}, children: [ - {style: {width: 100, height: 100}}, - {style: {width: 100, height: 100}} - ]}, - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 100, height: 100, top: 800, left: 0}, - {width: 100, height: 100, top: 900, left: 0} - ]} - ); - }); - - it('should layout node with justifyContent: flex-end in reverse', function() { - testLayout( - {style: {width: 1000, height: 1000, flexDirection: 'column-reverse', justifyContent: 'flex-end'}, children: [ - {style: {width: 100, height: 100}}, - {style: {width: 100, height: 100}} - ]}, - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 100, height: 100, top: 100, left: 0}, - {width: 100, height: 100, top: 0, left: 0} - ]} - ); - }); - - it('should layout node with justifyContent: space-between', function() { - testLayout( - {style: {width: 1000, height: 1000, justifyContent: 'space-between'}, children: [ - {style: {width: 100, height: 100}}, - {style: {width: 100, height: 100}} - ]}, - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 100, height: 100, top: 0, left: 0}, - {width: 100, height: 100, top: 900, left: 0} - ]} - ); - }); - - it('should layout node with justifyContent: space-between in reverse', function() { - testLayout( - {style: {width: 1000, height: 1000, flexDirection: 'column-reverse', justifyContent: 'space-between'}, children: [ - {style: {width: 100, height: 100}}, - {style: {width: 100, height: 100}} - ]}, - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 100, height: 100, top: 900, left: 0}, - {width: 100, height: 100, top: 0, left: 0} - ]} - ); - }); - - it('should layout node with justifyContent: space-around', function() { - testLayout( - {style: {width: 1000, height: 1000, justifyContent: 'space-around'}, children: [ - {style: {width: 100, height: 100}}, - {style: {width: 100, height: 100}} - ]}, - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 100, height: 100, top: 200, left: 0}, - {width: 100, height: 100, top: 700, left: 0} - ]} - ); - }); - - it('should layout node with justifyContent: space-around in reverse', function() { - testLayout( - {style: {width: 1000, height: 1000, flexDirection: 'column-reverse', justifyContent: 'space-around'}, children: [ - {style: {width: 100, height: 100}}, - {style: {width: 100, height: 100}} - ]}, - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 100, height: 100, top: 700, left: 0}, - {width: 100, height: 100, top: 200, left: 0} - ]} - ); - }); - - it('should layout node with justifyContent: center', function() { - testLayout( - {style: {width: 1000, height: 1000, justifyContent: 'center'}, children: [ - {style: {width: 100, height: 100}}, - {style: {width: 100, height: 100}} - ]}, - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 100, height: 100, top: 400, left: 0}, - {width: 100, height: 100, top: 500, left: 0} - ]} - ); - }); - - it('should layout node with justifyContent: center in reverse', function() { - testLayout( - {style: {width: 1000, height: 1000, flexDirection: 'column-reverse', justifyContent: 'center'}, children: [ - {style: {width: 100, height: 100}}, - {style: {width: 100, height: 100}} - ]}, - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 100, height: 100, top: 500, left: 0}, - {width: 100, height: 100, top: 400, left: 0} - ]} - ); - }); - - it('should layout node with flex override height', function() { - testLayout( - {style: {width: 1000, height: 1000}, children: [ - {style: {width: 100, height: 100, flex: 1}} - ]}, - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 100, height: 1000, top: 0, left: 0} - ]} - ); - }); - - it('should layout node with alignItems: flex-start', function() { - testLayout( - {style: {width: 1000, height: 1000, alignItems: 'flex-start'}, children: [ - {style: {width: 200, height: 100}}, - {style: {width: 100, height: 100}} - ]}, - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 200, height: 100, top: 0, left: 0}, - {width: 100, height: 100, top: 100, left: 0} - ]} - ); - }); - - it('should layout node with alignItems: flex-start in reverse', function() { - testLayout( - {style: {width: 1000, height: 1000, flexDirection: 'column-reverse', alignItems: 'flex-start'}, children: [ - {style: {width: 200, height: 100}}, - {style: {width: 100, height: 100}} - ]}, - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 200, height: 100, top: 900, left: 0}, - {width: 100, height: 100, top: 800, left: 0} - ]} - ); - }); - - it('should layout node with alignItems: center', function() { - testLayout( - {style: {width: 1000, height: 1000, alignItems: 'center'}, children: [ - {style: {width: 200, height: 100}}, - {style: {width: 100, height: 100}} - ]}, - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 200, height: 100, top: 0, left: 400}, - {width: 100, height: 100, top: 100, left: 450} - ]} - ); - }); - - it('should layout node with alignItems: center in reverse', function() { - testLayout( - {style: {width: 1000, height: 1000, flexDirection: 'column-reverse', alignItems: 'center'}, children: [ - {style: {width: 200, height: 100}}, - {style: {width: 100, height: 100}} - ]}, - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 200, height: 100, top: 900, left: 400}, - {width: 100, height: 100, top: 800, left: 450} - ]} - ); - }); - - it('should layout node with alignItems: flex-end', function() { - testLayout( - {style: {width: 1000, height: 1000, alignItems: 'flex-end'}, children: [ - {style: {width: 200, height: 100}}, - {style: {width: 100, height: 100}} - ]}, - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 200, height: 100, top: 0, left: 800}, - {width: 100, height: 100, top: 100, left: 900} - ]} - ); - }); - - it('should layout node with alignItems: flex-end in reverse', function() { - testLayout( - {style: {width: 1000, height: 1000, flexDirection: 'column-reverse', alignItems: 'flex-end'}, children: [ - {style: {width: 200, height: 100}}, - {style: {width: 100, height: 100}} - ]}, - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 200, height: 100, top: 900, left: 800}, - {width: 100, height: 100, top: 800, left: 900} - ]} - ); - }); - - it('should layout node with alignSelf overrides alignItems', function() { - testLayout( - {style: {width: 1000, height: 1000, alignItems: 'flex-end'}, children: [ - {style: {width: 200, height: 100}}, - {style: {width: 100, height: 100, alignSelf: 'center'}} - ]}, - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 200, height: 100, top: 0, left: 800}, - {width: 100, height: 100, top: 100, left: 450} - ]} - ); - }); - - it('should layout node with alignSelf overrides alignItems in reverse', function() { - testLayout( - {style: {width: 1000, height: 1000, flexDirection: 'column-reverse', alignItems: 'flex-end'}, children: [ - {style: {width: 200, height: 100}}, - {style: {width: 100, height: 100, alignSelf: 'center'}} - ]}, - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 200, height: 100, top: 900, left: 800}, - {width: 100, height: 100, top: 800, left: 450} - ]} - ); - }); - - it('should layout node with alignItem: stretch', function() { - testLayout( - {style: {width: 1000, height: 1000, alignItems: 'stretch'}, children: [ - {style: {height: 100}} - ]}, - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 1000, height: 100, top: 0, left: 0} - ]} - ); - }); - - it('should layout node with alignItem: stretch in reverse', function() { - testLayout( - {style: {width: 1000, height: 1000, flexDirection: 'column-reverse', alignItems: 'stretch'}, children: [ - {style: {height: 100}} - ]}, - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 1000, height: 100, top: 900, left: 0} - ]} - ); - }); - - it('should layout empty node', function() { - testLayout( - {style: {}, children: [ - {style: {}} - ]}, - {width: 0, height: 0, top: 0, left: 0, children: [ - {width: 0, height: 0, top: 0, left: 0} - ]} - ); - }); - - it('should layout empty node in reverse', function() { - testLayout( - {style: {flexDirection: 'column-reverse'}, children: [ - {style: {}} - ]}, - {width: 0, height: 0, top: 0, left: 0, children: [ - {width: 0, height: 0, top: 0, left: 0} - ]} - ); - }); - - it('should layout child with margin', function() { - testLayout( - {style: {}, children: [ - {style: {margin: 5}} - ]}, - {width: 10, height: 10, top: 0, left: 0, children: [ - {width: 0, height: 0, top: 5, left: 5} - ]} - ); - }); - - it('should layout child with margin in reverse', function() { - testLayout( - {style: {flexDirection: 'column-reverse'}, children: [ - {style: {margin: 5}} - ]}, - {width: 10, height: 10, top: 0, left: 0, children: [ - {width: 0, height: 0, top: 5, left: 5} - ]} - ); - }); - - it('should not shrink children if not enough space', function() { - testLayout( - {style: {height: 100}, children: [ - {style: {height: 100}}, - {style: {height: 200}} - ]}, - {width: 0, height: 100, top: 0, left: 0, children: [ - {width: 0, height: 100, top: 0, left: 0}, - {width: 0, height: 200, top: 100, left: 0} - ]} - ); - }); - - it('should not shrink children if not enough space in reverse', function() { - testLayout( - {style: {height: 100, flexDirection: 'column-reverse'}, children: [ - {style: {height: 100}}, - {style: {height: 200}} - ]}, - {width: 0, height: 100, top: 0, left: 0, children: [ - {width: 0, height: 100, top: 0, left: 0}, - {width: 0, height: 200, top: -200, left: 0} - ]} - ); - }); - - it('should layout for center', function() { - testLayout( - {style: {justifyContent: 'center'}}, - {width: 0, height: 0, top: 0, left: 0} - ); - }); - - it('should layout flex-end taking into account margin', function() { - testLayout( - {style: {height: 100, justifyContent: 'flex-end'}, children: [ - {style: {marginTop: 10}} - ]}, - {width: 0, height: 100, top: 0, left: 0, children: [ - {width: 0, height: 0, top: 100, left: 0} - ]} - ); - }); - - it('should layout flex-end taking into account margin in reverse', function() { - testLayout( - {style: {height: 100, flexDirection: 'column-reverse', justifyContent: 'flex-end'}, children: [ - {style: {marginTop: 10}} - ]}, - {width: 0, height: 100, top: 0, left: 0, children: [ - {width: 0, height: 0, top: 10, left: 0} - ]} - ); - }); - - it('should layout alignItems with margin', function() { - testLayout( - {style: {}, children: [ - {style: {alignItems: 'flex-end'}, children: [ - {style: {margin: 10}}, - {style: {height: 100}} - ]} - ]}, - {width: 20, height: 120, top: 0, left: 0, children: [ - {width: 20, height: 120, top: 0, left: 0, children: [ - {width: 0, height: 0, top: 10, left: 10}, - {width: 0, height: 100, top: 20, left: 20} - ]} - ]} - ); - }); - - it('should layout alignItems with margin in reverse', function() { - testLayout( - {style: {}, children: [ - {style: {flexDirection: 'column-reverse', alignItems: 'flex-end'}, children: [ - {style: {margin: 10}}, - {style: {height: 100}} - ]} - ]}, - {width: 20, height: 120, top: 0, left: 0, children: [ - {width: 20, height: 120, top: 0, left: 0, children: [ - {width: 0, height: 0, top: 110, left: 10}, - {width: 0, height: 100, top: 0, left: 20} - ]} - ]} - ); - }); - - it('should layout flex inside of an empty element', function() { - testLayout( - {style: {}, children: [ - {style: {flex: 1}} - ]}, - {width: 0, height: 0, top: 0, left: 0, children: [ - {width: 0, height: 0, top: 0, left: 0} - ]} - ); - }); - - it('should layout alignItems stretch and margin', function() { - testLayout( - {style: {alignItems: 'stretch'}, children: [ - {style: {marginLeft: 10}} - ]}, - {width: 10, height: 0, top: 0, left: 0, children: [ - {width: 0, height: 0, top: 0, left: 10} - ]} - ); - }); - - it('should layout alignItems stretch and margin in reverse', function() { - testLayout( - {style: {flexDirection: 'column-reverse', alignItems: 'stretch'}, children: [ - {style: {marginLeft: 10}} - ]}, - {width: 10, height: 0, top: 0, left: 0, children: [ - {width: 0, height: 0, top: 0, left: 10} - ]} - ); - }); - - it('should layout node with padding', function() { - testLayout( - {style: {padding: 5}}, - {width: 10, height: 10, top: 0, left: 0} - ); - }); - - it('should layout node with padding and a child', function() { - testLayout( - {style: {padding: 5}, children: [ - {style: {}} - ]}, - {width: 10, height: 10, top: 0, left: 0, children: [ - {width: 0, height: 0, top: 5, left: 5} - ]} - ); - }); - - it('should layout node with padding and a child with margin', function() { - testLayout( - {style: {padding: 5}, children: [ - {style: {margin: 5}} - ]}, - {width: 20, height: 20, top: 0, left: 0, children: [ - {width: 0, height: 0, top: 10, left: 10} - ]} - ); - }); - - it('should layout node with padding and stretch', function() { - testLayout( - {style: {}, children: [ - {style: {padding: 10, alignSelf: 'stretch'}} - ]}, - {width: 20, height: 20, top: 0, left: 0, children: [ - {width: 20, height: 20, top: 0, left: 0} - ]} - ); - }); - - it('should layout node with inner & outer padding and stretch', function() { - testLayout( - {style: {padding: 50}, children: [ - {style: {padding: 10, alignSelf: 'stretch'}} - ]}, - {width: 120, height: 120, top: 0, left: 0, children: [ - {width: 20, height: 20, top: 50, left: 50} - ]} - ); - }); - - it('should layout node with stretch and child with margin', function() { - testLayout( - {style: {}, children: [ - {style: {alignSelf: 'stretch'}, children: [ - {style: {margin: 16}} - ]} - ]}, - {width: 32, height: 32, top: 0, left: 0, children: [ - {width: 32, height: 32, top: 0, left: 0, children: [ - {width: 0, height: 0, top: 16, left: 16} - ]} - ]} - ); - }); - - it('should layout node with top and left', function() { - testLayout( - {style: {top: 5, left: 5}}, - {width: 0, height: 0, top: 5, left: 5} - ); - }); - - it('should layout node with height, padding and space-around', function() { - testLayout( - {style: {height: 10, paddingTop: 5, justifyContent: 'space-around'}, children: [ - {style: {}} - ]}, - {width: 0, height: 10, top: 0, left: 0, children: [ - {width: 0, height: 0, top: 7.5, left: 0} - ]} - ); - }); - - it('should layout node with bottom', function() { - testLayout( - {style: {bottom: 5}}, - {width: 0, height: 0, top: -5, left: 0} - ); - }); - - it('should layout node with both top and bottom', function() { - testLayout( - {style: {top: 10, bottom: 5}}, - {width: 0, height: 0, top: 10, left: 0} - ); - }); - - it('should layout node with position: absolute', function() { - testLayout( - {style: {width: 500, flexDirection: 'row'}, children: [ - {style: {flex: 1}}, - {style: {position: 'absolute', width: 50}}, - {style: {flex: 1}} - ]}, - {width: 500, height: 0, top: 0, left: 0, children: [ - {width: 250, height: 0, top: 0, left: 0}, - {width: 50, height: 0, top: 0, left: 250}, - {width: 250, height: 0, top: 0, left: 250} - ]} - ); - }); - - it('should layout node with child with position: absolute and margin', function() { - testLayout( - {style: {}, children: [ - {style: {marginRight: 15, position: 'absolute'}} - ]}, - {width: 0, height: 0, top: 0, left: 0, children: [ - {width: 0, height: 0, top: 0, left: 0} - ]} - ); - }); - - it('should layout node with position: absolute, padding and alignSelf: center', function() { - testLayout( - {style: {}, children: [ - {style: {paddingRight: 12, alignSelf: 'center', position: 'absolute'}} - ]}, - {width: 0, height: 0, top: 0, left: 0, children: [ - {width: 12, height: 0, top: 0, left: 0} - ]} - ); - }); - - it('should work with height smaller than paddingBottom', function() { - testLayout( - {style: {height: 5, paddingBottom: 20}}, - {width: 0, height: 20, top: 0, left: 0} - ); - }); - - it('should work with width smaller than paddingLeft', function() { - testLayout( - {style: {width: 5, paddingLeft: 20}}, - {width: 20, height: 0, top: 0, left: 0} - ); - }); - - it('should layout node with specified width and stretch', function() { - testLayout( - {style: {}, children: [{ - style: {}, children: [ - {style: {width: 400}} - ]}, - {style: {width: 200, alignSelf: 'stretch'}} - ]}, - {width: 400, height: 0, top: 0, left: 0, children: [ - {width: 400, height: 0, top: 0, left: 0, children: [ - {width: 400, height: 0, top: 0, left: 0} - ]}, - {width: 200, height: 0, top: 0, left: 0} - ]} - ); - }); - - it('should layout node with padding and child with position absolute', function() { - testLayout( - {style: {padding: 5}, children: [ - {style: {position: 'absolute'}} - ]}, - {width: 10, height: 10, top: 0, left: 0, children: [ - {width: 0, height: 0, top: 5, left: 5} - ]} - ); - }); - - it('should layout node with position absolute, top and left', function() { - testLayout( - {style: {}, children: [ - {style: {height: 100}}, - {style: {position: 'absolute', top: 10, left: 10}} - ]}, - {width: 0, height: 100, top: 0, left: 0, children: [ - {width: 0, height: 100, top: 0, left: 0}, - {width: 0, height: 0, top: 10, left: 10} - ]} - ); - }); - - it('should layout node with padding and child position absolute, left', function() { - testLayout( - {style: {padding: 20}, children: [ - {style: {left: 5, position: 'absolute'}} - ]}, - {width: 40, height: 40, top: 0, left: 0, children: [ - {width: 0, height: 0, top: 20, left: 5} - ]} - ); - }); - - it('should layout node with position: absolute, top and marginTop', function() { - testLayout( - {style: {}, children: [ - {style: {top: 5, marginTop: 5, position: 'absolute'}} - ]}, - {width: 0, height: 0, top: 0, left: 0, children: [ - {width: 0, height: 0, top: 10, left: 0} - ]} - ); - }); - - it('should layout node with position: absolute, left and marginLeft', function() { - testLayout( - {style: {}, children: [ - {style: {left: 5, marginLeft: 5, position: 'absolute'}} - ]}, - {width: 0, height: 0, top: 0, left: 0, children: [ - {width: 0, height: 0, top: 0, left: 10} - ]} - ); - }); - - it('should layout node with space-around and child position absolute', function() { - testLayout( - {style: {height: 200, justifyContent: 'space-around'}, children: [ - {style: {position: 'absolute'}}, - {style: {}} - ]}, - {width: 0, height: 200, top: 0, left: 0, children: [ - {width: 0, height: 0, top: 100, left: 0}, - {width: 0, height: 0, top: 100, left: 0} - ]} - ); - }); - - it('should layout node with space-around and child position absolute in reverse', function() { - testLayout( - {style: {height: 200, flexDirection: 'column-reverse', justifyContent: 'space-around'}, children: [ - {style: {position: 'absolute'}}, - {style: {}} - ]}, - {width: 0, height: 200, top: 0, left: 0, children: [ - {width: 0, height: 0, top: 100, left: 0}, - {width: 0, height: 0, top: 100, left: 0} - ]} - ); - }); - - it('should layout node with flex and main margin', function() { - testLayout( - {style: {width: 700, flexDirection: 'row'}, children: [ - {style: {marginLeft: 5, flex: 1}} - ]}, - {width: 700, height: 0, top: 0, left: 0, children: [ - {width: 695, height: 0, top: 0, left: 5} - ]} - ); - }); - - it('should layout node with flex and main margin in rtl', function() { - testLayout( - {style: {width: 700, direction: 'rtl', flexDirection: 'row'}, children: [ - {style: {marginRight: 5, flex: 1}} - ]}, - {width: 700, height: 0, top: 0, left: 0, children: [ - {width: 695, height: 0, top: 0, left: 0} - ]} - ); - }); - - it('should layout node with multiple flex and padding', function() { - testLayout( - {style: {width: 700, flexDirection: 'row'}, children: [ - {style: {flex: 1}}, - {style: {paddingRight: 5, flex: 1}} - ]}, - {width: 700, height: 0, top: 0, left: 0, children: [ - {width: 347.5, height: 0, top: 0, left: 0}, - {width: 352.5, height: 0, top: 0, left: 347.5} - ]} - ); - }); - - it('should layout node with multiple flex and padding in rtl', function() { - testLayout( - {style: {width: 700, direction: 'rtl', flexDirection: 'row'}, children: [ - {style: {flex: 1}}, - {style: {paddingLeft: 5, flex: 1}} - ]}, - {width: 700, height: 0, top: 0, left: 0, children: [ - {width: 347.5, height: 0, top: 0, left: 352.5}, - {width: 352.5, height: 0, top: 0, left: 0} - ]} - ); - }); - - it('should layout node with multiple flex and margin', function() { - testLayout( - {style: {width: 700, flexDirection: 'row'}, children: [ - {style: {flex: 1}}, - {style: {marginLeft: 5, flex: 1}} - ]}, - {width: 700, height: 0, top: 0, left: 0, children: [ - {width: 347.5, height: 0, top: 0, left: 0}, - {width: 347.5, height: 0, top: 0, left: 352.5} - ]} - ); - }); - - it('should layout node with multiple flex and margin in rtl', function() { - testLayout( - {style: {width: 700, direction: 'rtl', flexDirection: 'row'}, children: [ - {style: {flex: 1}}, - {style: {marginRight: 5, flex: 1}} - ]}, - {width: 700, height: 0, top: 0, left: 0, children: [ - {width: 347.5, height: 0, top: 0, left: 352.5}, - {width: 347.5, height: 0, top: 0, left: 0} - ]} - ); - }); - - it('should layout node with flex and overflow', function() { - testLayout( - {style: {height: 300}, children: [ - {style: {height: 600}}, - {style: {flex: 1}} - ]}, - {width: 0, height: 300, top: 0, left: 0, children: [ - {width: 0, height: 600, top: 0, left: 0}, - {width: 0, height: 0, top: 600, left: 0} - ]} - ); - }); - - it('should layout node with flex and position absolute', function() { - testLayout( - {style: {width: 600, flexDirection: 'row'}, children: [ - {style: {flex: 1, position: 'absolute'}} - ]}, - {width: 600, height: 0, top: 0, left: 0, children: [ - {width: 0, height: 0, top: 0, left: 0} - ]} - ); - }); - - it('should layout node with flex and position absolute in rtl', function() { - testLayout( - {style: {width: 600, direction: 'rtl', flexDirection: 'row'}, children: [ - {style: {flex: 1, position: 'absolute'}} - ]}, - {width: 600, height: 0, top: 0, left: 0, children: [ - {width: 0, height: 0, top: 0, left: 600} - ]} - ); - }); - - it('should layout node with double flex and position absolute', function() { - testLayout( - {style: {height: 500}, children: [ - {style: {flex: 1}}, - {style: {flex: 1, position: 'absolute'}} - ]}, - {width: 0, height: 500, top: 0, left: 0, children: [ - {width: 0, height: 500, top: 0, left: 0}, - {width: 0, height: 0, top: 500, left: 0} - ]} - ); - }); - - it('should layout node with borderWidth', function() { - testLayout( - {style: {borderWidth: 5}}, - {width: 10, height: 10, top: 0, left: 0} - ); - }); - - it('should layout node with borderWidth and position: absolute, top', function() { - testLayout( - {style: {borderTopWidth: 1}, children: [ - {style: {top: -1, position: 'absolute'}} - ]}, - {width: 0, height: 1, top: 0, left: 0, children: [ - {width: 0, height: 0, top: 0, left: 0} - ]} - ); - }); - - it('should layout node with borderWidth and position: absolute, top. cross axis', function() { - testLayout( - {style: {borderWidth: 1}, children: [ - {style: {left: 5, position: 'absolute'}} - ]}, - {width: 2, height: 2, top: 0, left: 0, children: [ - {width: 0, height: 0, top: 1, left: 6} - ]} - ); - }); - - it('should correctly take into account min padding for stretch', function() { - testLayout( - {style: {width: 50}, children: [ - {style: {marginLeft: 20, padding: 20, alignSelf: 'stretch'}} - ]}, - {width: 50, height: 40, top: 0, left: 0, children: [ - {width: 40, height: 40, top: 0, left: 20} - ]} - ); - }); - - it('should layout node with negative width', function() { - testLayout( - {style: {width: -31}, children: [ - {style: {borderRightWidth: 5}} - ]}, - {width: 5, height: 0, top: 0, left: 0, children: [ - {width: 5, height: 0, top: 0, left: 0} - ]} - ); - }); - - it('should handle negative margin and min padding correctly', function() { - testLayout( - {style: {borderRightWidth: 1, flexDirection: 'row'}, children: [ - {style: {marginRight: -8}} - ]}, - {width: 1, height: 0, top: 0, left: 0, children: [ - {width: 0, height: 0, top: 0, left: 0} - ]} - ); - }); - - it('should handle negative margin and min padding correctly in rtl', function() { - testLayout( - {style: {borderLeftWidth: 1, direction: 'rtl', flexDirection: 'row'}, children: [ - {style: {marginLeft: -8}} - ]}, - {width: 1, height: 0, top: 0, left: 0, children: [ - {width: 0, height: 0, top: 0, left: 1} - ]} - ); - }); - - it('should layout node with just text', function() { - testLayout( - {style: {measure: text(texts.small)}}, - {width: textSizes.smallWidth, height: textSizes.smallHeight, top: 0, left: 0} - ); - }); - - it('should layout node with fixed width and custom measure function', function() { - testLayoutAgainstExpectedOnly( - {style: { - measure: measureWithRatio2, - width: 100 - }}, - {width: 100, height: 200, top: 0, left: 0} - ); - }); - - it('should layout node with fixed height and custom measure function', function() { - testLayoutAgainstExpectedOnly( - {style: { - measure: measureWithRatio2, - height: 100 - }}, - {width: 200, height: 100, top: 0, left: 0} - ); - }); - - it('should layout node with fixed height and fixed width, ignoring custom measure function', function() { - testLayoutAgainstExpectedOnly( - {style: { - measure: measureWithRatio2, - width: 100, - height: 100 - }}, - {width: 100, height: 100, top: 0, left: 0} - ); - }); - - it('should layout node with no fixed dimension and custom measure function', function() { - testLayoutAgainstExpectedOnly( - {style: { - measure: measureWithRatio2, - }}, - {width: 99999, height: 99999, top: 0, left: 0} - ); - }); - - it('should layout node with nested stacks and custom measure function', function() { - testLayoutAgainstExpectedOnly( - {style: {width: 320, flexDirection: 'column'}, children: [ - {style: {measure: measureWithRatio2}}, - {style: {height: 100, flexDirection: 'row', overflow: 'hidden'}, children: [ - {style: {measure: measureWithRatio2}}, - {style: {measure: measureWithRatio2}} - ]}, - ]}, - {width: 320, height: 740, top: 0, left: 0, children: [ - {width: 320, height: 640, top: 0, left: 0}, - {width: 320, height: 100, top: 640, left: 0, children: [ - {width: 200, height: 100, top: 0, left: 0}, - {width: 200, height: 100, top: 0, left: 200} - ]}, - ]} - ); - }); - - it('should layout node with text and width', function() { - testLayout( - {style: {measure: text(texts.small), width: 10}}, - {width: 10, height: textSizes.smallHeight, top: 0, left: 0} - ); - }); - - it('should layout node with text, padding and margin', function() { - testLayout( - {style: {measure: text(texts.big)}}, - {width: textSizes.bigWidth, height: textSizes.smallHeight, top: 0, left: 0} - ); - }); - - it('should layout node with nested alignSelf: stretch', function() { - testLayout( - {style: {width: 300}, children: [ - {style: {alignSelf: 'stretch'}, children: [ - {style: {alignSelf: 'stretch'}} - ]} - ]}, - {width: 300, height: 0, top: 0, left: 0, children: [ - {width: 300, height: 0, top: 0, left: 0, children: [ - {width: 300, height: 0, top: 0, left: 0} - ]} - ]} - ); - }); - - it('should layout node with text and flex', function() { - testLayout( - {style: {}, children: [ - {style: {width: 500, flexDirection: 'row'}, children: [ - {style: {flex: 1, measure: text(texts.big)}} - ]} - ]}, - {width: 500, height: textSizes.smallHeight, top: 0, left: 0, children: [ - {width: 500, height: textSizes.smallHeight, top: 0, left: 0, children: [ - {width: 500, height: textSizes.smallHeight, top: 0, left: 0} - ]} - ]} - ); - }); - - it('should layout node with text and flex in rtl', function() { - testLayout( - {style: {}, children: [ - {style: {width: 500, direction: 'rtl', flexDirection: 'row'}, children: [ - {style: {flex: 1, measure: text(texts.big)}} - ]} - ]}, - {width: 500, height: textSizes.smallHeight, top: 0, left: 0, children: [ - {width: 500, height: textSizes.smallHeight, top: 0, left: 0, children: [ - {width: 500, height: textSizes.smallHeight, top: 0, left: 0} - ]} - ]} - ); - }); - - it('should layout node with text and stretch', function() { - testLayout( - {style: {width: 130}, children: [ - {style: {alignSelf: 'stretch', alignItems: 'stretch'}, children: [ - {style: {measure: text(texts.big)}} - ]} - ]}, - {width: 130, height: textSizes.bigHeight, top: 0, left: 0, children: [ - {width: 130, height: textSizes.bigHeight, top: 0, left: 0, children: [ - {width: 130, height: textSizes.bigHeight, top: 0, left: 0} - ]} - ]} - ); - }); - - it('should layout node with text stretch and width', function() { - testLayout( - {style: {width: 200}, children: [ - {style: {alignSelf: 'stretch', alignItems: 'stretch'}, children: [ - {style: {width: 130, measure: text(texts.big)}} - ]} - ]}, - {width: 200, height: textSizes.bigHeight, top: 0, left: 0, children: [ - {width: 200, height: textSizes.bigHeight, top: 0, left: 0, children: [ - {width: 130, height: textSizes.bigHeight, top: 0, left: 0} - ]} - ]} - ); - }); - - it('should layout node with text bounded by parent', function() { - testLayout( - {style: {width: 100, alignSelf: 'flex-start'}, children: [ - {style: {measure: text(texts.big), alignSelf: 'flex-start'}} - ]}, - {width: 100, height: textSizes.bigHeight, top: 0, left: 0, children: [ - {width: textSizes.bigMinWidth, height: textSizes.bigHeight, top: 0, left: 0} - ]} - ); - }); - - it('should layout node with text bounded by grand-parent', function() { - testLayoutAgainstExpectedOnly( - {style: {width: 100, padding: 10, alignSelf: 'flex-start'}, children: [ - {style: {margin: 10, alignSelf: 'flex-start'}, children: [ - {style: {measure: text(texts.big)}} - ]} - ]}, - {width: 100, height: 40 + textSizes.bigHeight, top: 0, left: 0, children: [ - // In the flexbox engine implementation, min width of text is not supported so we max - // out at the amount of available space (60) - {width: Math.min(60, textSizes.bigMinWidth), height: textSizes.bigHeight, top: 20, left: 20, children: [ - {width: textSizes.bigMinWidth, height: textSizes.bigHeight, top: 0, left: 0} - ]} - ]} - ); - }); - - it('should layout space-between when remaining space is negative', function() { - testLayout( - {style: {height: 100, justifyContent: 'space-between'}, children: [ - {style: {height: 900}}, - {style: {}} - ]}, - {width: 0, height: 100, top: 0, left: 0, children: [ - {width: 0, height: 900, top: 0, left: 0}, - {width: 0, height: 0, top: 900, left: 0} - ]} - ); - }); - - it('should layout space-between when remaining space is negative in reverse', function() { - testLayout( - {style: {height: 100, flexDirection: 'column-reverse', justifyContent: 'space-between'}, children: [ - {style: {height: 900}}, - {style: {}} - ]}, - {width: 0, height: 100, top: 0, left: 0, children: [ - {width: 0, height: 900, top: -800, left: 0}, - {width: 0, height: 0, top: -800, left: 0} - ]} - ); - }); - - it('should layout flex-end when remaining space is negative', function() { - testLayout( - {style: {width: 200, flexDirection: 'row', justifyContent: 'flex-end'}, children: [ - {style: {width: 900}} - ]}, - {width: 200, height: 0, top: 0, left: 0, children: [ - {width: 900, height: 0, top: 0, left: -700} - ]} - ); - }); - - it('should layout flex-end when remaining space is negative in rtl', function() { - testLayout( - {style: {width: 200, direction: 'rtl', flexDirection: 'row', justifyContent: 'flex-end'}, children: [ - {style: {width: 900}} - ]}, - {width: 200, height: 0, top: 0, left: 0, children: [ - {width: 900, height: 0, top: 0, left: 0} - ]} - ); - }); - - it('should layout text with flexDirection row', function() { - testLayout( - {style: {}, children: [ - {style: {width: 200, flexDirection: 'row'}, children: [ - {style: {margin: 20, measure: text(texts.big)}} - ]} - ]}, - {width: 200, height: textSizes.smallHeight + 40, top: 0, left: 0, children: [ - {width: 200, height: textSizes.smallHeight + 40, top: 0, left: 0, children: [ - {width: textSizes.bigWidth, height: textSizes.smallHeight, top: 20, left: 20} - ]} - ]} - ); - }); - - it('should layout text with flexDirection row in rtl', function() { - testLayout( - {style: { direction: 'rtl' }, children: [ - {style: {width: 200, flexDirection: 'row'}, children: [ - {style: {margin: 20, measure: text(texts.big)}} - ]} - ]}, - {width: 200, height: textSizes.smallHeight + 40, top: 0, left: 0, children: [ - {width: 200, height: textSizes.smallHeight + 40, top: 0, left: 0, children: [ - {width: textSizes.bigWidth, height: textSizes.smallHeight, top: 20, left: 8} - ]} - ]} - ); - }); - - it('should layout with text and margin', function() { - testLayout( - {style: {}, children: [ - {style: {width: 200}, children: [ - {style: {margin: 20, measure: text(texts.big)}} - ]} - ]}, - {width: 200, height: textSizes.bigHeight + 40, top: 0, left: 0, children: [ - {width: 200, height: textSizes.bigHeight + 40, top: 0, left: 0, children: [ - {width: 160, height: textSizes.bigHeight, top: 20, left: 20} - ]} - ]} - ); - }); - - it('should layout with position absolute, top, left, bottom, right', function() { - testLayout( - {style: {width: 100, height: 100}, children: [ - {style: {position: 'absolute', top: 0, left: 0, bottom: 0, right: 0}} - ]}, - {width: 100, height: 100, top: 0, left: 0, children: [ - {width: 100, height: 100, top: 0, left: 0} - ]} - ); - }); - - it('should layout with arbitrary flex', function() { - testLayout( - {style: {width: 100, height: 100, alignSelf: 'flex-start'}, children: [ - {style: {flex: 2.5, alignSelf: 'flex-start'}}, - {style: {flex: 7.5, alignSelf: 'flex-start'}} - ]}, - {width: 100, height: 100, top: 0, left: 0, children: [ - {width: 0, height: 25, top: 0, left: 0}, - {width: 0, height: 75, top: 25, left: 0} - ]} - ); - }); - - it('should layout with arbitrary flex in reverse', function() { - testLayout( - {style: {width: 100, height: 100, flexDirection: 'column-reverse', alignSelf: 'flex-start'}, children: [ - {style: {flex: 2.5, alignSelf: 'flex-start'}}, - {style: {flex: 7.5, alignSelf: 'flex-start'}} - ]}, - {width: 100, height: 100, top: 0, left: 0, children: [ - {width: 0, height: 25, top: 75, left: 0}, - {width: 0, height: 75, top: 0, left: 0} - ]} - ); - }); - - it('should layout with negative flex in reverse', function() { - testLayout( - {style: {width: 100, height: 100, flexDirection: 'column-reverse', alignSelf: 'flex-start'}, children: [ - {style: {flex: -2.5, alignSelf: 'flex-start'}}, - {style: {flex: 0, alignSelf: 'flex-start'}} - ]}, - {width: 100, height: 100, top: 0, left: 0, children: [ - {width: 0, height: 0, top: 100, left: 0}, - {width: 0, height: 0, top: 100, left: 0} - ]} - ); - }); - - it('should layout with position: absolute and another sibling', function() { - testLayout( - {style: {}, children: [ - {style: {width: 50, height: 100}}, - {style: {position: 'absolute', left: 0, right: 0}} - ]}, - {width: 50, height: 100, top: 0, left: 0, children: [ - {width: 50, height: 100, top: 0, left: 0}, - {width: 50, height: 0, top: 100, left: 0} - ]} - ); - }); - - it('should calculate height properly with position: absolute top and bottom', function() { - testLayout( - {style: {height: 100}, children: [ - {style: {position: 'absolute', top: 0, bottom: 20}} - ]}, - {width: 0, height: 100, top: 0, left: 0, children: [ - {width: 0, height: 80, top: 0, left: 0} - ]} - ); - }); - - it('should layout with complicated position: absolute and justifyContent: center combo', function() { - testLayout( - {style: {width: 200, height: 200}, children: [ - {style: {position: 'absolute', justifyContent: 'center', top: 0, left: 0, right: 0, bottom: 0}, children: [ - {style: {width: 100, height: 100}} - ]} - ]}, - {width: 200, height: 200, top: 0, left: 0, children: [ - {width: 200, height: 200, top: 0, left: 0, children: [ - {width: 100, height: 100, top: 50, left: 0} - ]} - ]} - ); - }); - - it('should calculate top properly with position: absolute bottom', function() { - testLayout( - {style: {height: 100}, children: [ - {style: {position: 'absolute', bottom: 0}} - ]}, - {width: 0, height: 100, top: 0, left: 0, children: [ - {width: 0, height: 0, top: 100, left: 0} - ]} - ); - }); - - it('should calculate left properly with position: absolute right', function() { - testLayout( - {style: {width: 100}, children: [ - {style: {position: 'absolute', right: 0}} - ]}, - {width: 100, height: 0, top: 0, left: 0, children: [ - {width: 0, height: 0, top: 0, left: 100} - ]} - ); - }); - - it('should calculate top properly with position: absolute bottom and height', function() { - testLayout( - {style: {height: 100}, children: [ - {style: {height: 10, position: 'absolute', bottom: 0}} - ]}, - {width: 0, height: 100, top: 0, left: 0, children: [ - {width: 0, height: 10, top: 90, left: 0} - ]} - ); - }); - - it('should calculate left properly with position: absolute right and width', function() { - testLayout( - {style: {width: 100}, children: [ - {style: {width: 10, position: 'absolute', right: 0}} - ]}, - {width: 100, height: 0, top: 0, left: 0, children: [ - {width: 10, height: 0, top: 0, left: 90} - ]} - ); - }); - - it('should calculate top properly with position: absolute right, width, and no parent dimensions', function() { - testLayout( - {style: {}, children: [ - {style: {height: 10, position: 'absolute', bottom: 0}} - ]}, - {width: 0, height: 0, top: 0, left: 0, children: [ - {width: 0, height: 10, top: -10, left: 0} - ]} - ); - }); - - it('should calculate left properly with position: absolute right, width, and no parent dimensions', function() { - testLayout( - {style: {}, children: [ - {style: {width: 10, position: 'absolute', right: 0}} - ]}, - {width: 0, height: 0, top: 0, left: 0, children: [ - {width: 10, height: 0, top: 0, left: -10} - ]} - ); - }); - - it('should layout border bottom inside of justify content space between container', function() { - testLayout( - {style: {justifyContent: 'space-between'}, children: [ - {style: {borderBottomWidth: 1}} - ]}, - {width: 0, height: 1, top: 0, left: 0, children: [ - {width: 0, height: 1, top: 0, left: 0} - ]} - ); - }); - - it('should layout negative margin top inside of justify content center container', function() { - testLayout( - {style: {justifyContent: 'center'}, children: [ - {style: {marginTop: -6}} - ]}, - {width: 0, height: 0, top: 0, left: 0, children: [ - {width: 0, height: 0, top: -3, left: 0} - ]} - ); - }); - - it('should layout positive margin top inside of justify content center container', function() { - testLayout( - {style: {justifyContent: 'center'}, children: [ - {style: {marginTop: 20}} - ]}, - {width: 0, height: 20, top: 0, left: 0, children: [ - {width: 0, height: 0, top: 20, left: 0} - ]} - ); - }); - - it('should layout border bottom and flex end with an empty child', function() { - testLayout( - {style: {borderBottomWidth: 5, justifyContent: 'flex-end'}, children: [ - {style: {}} - ]}, - {width: 0, height: 5, top: 0, left: 0, children: [ - {width: 0, height: 0, top: 0, left: 0} - ]} - ); - }); - - it('should layout with children of a contain with left', function() { - testLayout( - {style: {width: 800}, children: [ - {style: {left: 5}, children: [ - {style: {}} - ]} - ]}, - {width: 800, height: 0, top: 0, left: 0, children: [ - {width: 800, height: 0, top: 0, left: 5, children: [ - {width: 800, height: 0, top: 0, left: 0} - ]} - ]} - ); - }); - - // This behavior is very weird. The child has a width of 0 but somehow the - // parent has a width of 500. Looks like a bug rather than a feature. - // https://code.google.com/p/chromium/issues/detail?id=441768 - xit('should layout with flex: 0 and a specific width', function() { - testLayout( - {style: {flexDirection: 'row'}, children: [ - {style: {width: 500, flex: 0}} - ]}, - {width: 500, height: 0, top: 0, left: 0, children: [ - {width: 0, height: 0, top: 0, left: 0} - ]} - ); - }); - - xit('should layout with nested padding', function() { - testLayout( - {style: {}, children: [ - {style: {}, children: [ - {style: {}} - ]}, - {style: {padding: 5}} - ]}, - {width: 10, height: 10, top: 0, left: 0, children: [ - {width: 10, height: 0, top: 0, left: 0, children: [ - {width: 10, height: 0, top: 0, left: 0} - ]}, - {width: 10, height: 10, top: 0, left: 0} - ]} - ); - }); - - it('should layout flex-wrap', function() { - testLayout( - {style: {flexWrap: 'wrap', flexDirection: 'row', width: 100}, children: [ - {style: {width: 40, height: 10}}, - {style: {width: 40, height: 10}}, - {style: {width: 40, height: 10}} - ]}, - {width: 100, height: 20, top: 0, left: 0, children: [ - {width: 40, height: 10, top: 0, left: 0}, - {width: 40, height: 10, top: 0, left: 40}, - {width: 40, height: 10, top: 10, left: 0} - ]} - ); - }); - - it('should layout flex-wrap in rtl', function() { - testLayout( - {style: {flexWrap: 'wrap', direction: 'rtl', flexDirection: 'row', width: 100}, children: [ - {style: {width: 40, height: 10}}, - {style: {width: 40, height: 10}}, - {style: {width: 40, height: 10}} - ]}, - {width: 100, height: 20, top: 0, left: 0, children: [ - {width: 40, height: 10, top: 0, left: 60}, - {width: 40, height: 10, top: 0, left: 20}, - {width: 40, height: 10, top: 10, left: 60} - ]} - ); - }); - - it('should layout flex wrap with a line bigger than container', function() { - testLayout( - {style: {height: 100, flexWrap: 'wrap'}, children: [ - {style: {height: 100}}, - {style: {height: 200}} - ]}, - {width: 0, height: 100, top: 0, left: 0, children: [ - {width: 0, height: 100, top: 0, left: 0}, - {width: 0, height: 200, top: 0, left: 0} - ]} - ); - }); - - // The container should be width = 25 because the width of the two children - // are 20 and 5. It's likely a bug in Chrome - // https://code.google.com/p/chromium/issues/detail?id=247963#c16 - xit('should layout flex wrap with padding and borders', function() { - testLayout( - {style: {height: 100, flexWrap: 'wrap'}, children: [ - {style: {height: 500, paddingRight: 20}}, - {style: {borderLeftWidth: 5}} - ]}, - {width: 20, height: 100, top: 0, left: 0, children: [ - {width: 20, height: 500, top: 0, left: 0}, - {width: 5, height: 0, top: 0, left: 20} - ]} - ); - }); - - - xit('should layout text with alignItems: stretch', function() { - testLayout( - {style: {width: 80, padding: 7, alignItems: 'stretch', measure: text(texts.big)}}, - {width: 80, height: 68, top: 0, left: 0} - ); - }); - - xit('should layout node with text and position absolute', function() { - testLayout( - {style: {}, children: [ - {style: {measure: text(texts.big)}} - ]}, - {width: 0, height: 0, top: 0, left: 0, children: [ - {width: 100, height: textSizes.bigHeight, top: 0, left: 0} - ]} - ); - }); - - it('should use max bounds', function() { - testLayout( - {style: {width: 100, height: 200, maxWidth: 90, maxHeight: 190}}, - {width: 90, height: 190, top: 0, left: 0} - ); - }); - - it('should use min bounds', function() { - testLayout( - {style: {width: 100, height: 200, minWidth: 110, minHeight: 210}}, - {width: 110, height: 210, top: 0, left: 0} - ); - }); - - it('should use min bounds over max bounds', function() { - testLayout( - {style: {width: 100, height: 200, minWidth: 110, maxWidth: 90, minHeight: 210, maxHeight: 190}}, - {width: 110, height: 210, top: 0, left: 0} - ); - }); - - it('should use min bounds over max bounds and natural width', function() { - testLayout( - {style: {width: 100, height: 200, minWidth: 90, maxWidth: 80, minHeight: 190, maxHeight: 180}}, - {width: 90, height: 190, top: 0, left: 0} - ); - }); - - it('should ignore negative min bounds', function() { - testLayout( - {style: {width: 100, height: 200, minWidth: -10, minHeight: -20}}, - {width: 100, height: 200, top: 0, left: 0} - ); - }); - - it('should ignore negative max bounds', function() { - testLayout( - {style: {width: 100, height: 200, maxWidth: -10, maxHeight: -20}}, - {width: 100, height: 200, top: 0, left: 0} - ); - }); - - it('should use padded size over max bounds', function() { - testLayout( - {style: {paddingTop: 15, paddingBottom: 15, paddingLeft: 20, paddingRight: 20, maxWidth: 30, maxHeight: 10}}, - {width: 40, height: 30, top: 0, left: 0} - ); - }); - - it('should use min size over padded size', function() { - testLayout( - {style: {paddingTop: 15, paddingBottom: 15, paddingLeft: 20, paddingRight: 20, minWidth: 50, minHeight: 40}}, - {width: 50, height: 40, top: 0, left: 0} - ); - }); - - it('should override flex direction size with min bounds', function() { - testLayout( - {style: {width: 300, height: 200, flexDirection: 'row'}, children: [ - {style: {flex: 1}}, - {style: {flex: 1, minWidth: 200}}, - {style: {flex: 1}} - ]}, - {width: 300, height: 200, top: 0, left: 0, children: [ - {width: 50, height: 200, top: 0, left: 0}, - {width: 200, height: 200, top: 0, left: 50}, - {width: 50, height: 200, top: 0, left: 250} - ]} - ); - }); - - it('should override flex direction size with min bounds in rtl', function() { - testLayout( - {style: {width: 300, height: 200, direction: 'rtl', flexDirection: 'row'}, children: [ - {style: {flex: 1}}, - {style: {flex: 1, minWidth: 200}}, - {style: {flex: 1}} - ]}, - {width: 300, height: 200, top: 0, left: 0, children: [ - {width: 50, height: 200, top: 0, left: 250}, - {width: 200, height: 200, top: 0, left: 50}, - {width: 50, height: 200, top: 0, left: 0} - ]} - ); - }); - - it('should not override flex direction size within bounds', function() { - testLayout( - {style: {width: 300, height: 200, flexDirection: 'row'}, children: [ - {style: {flex: 1}}, - {style: {flex: 1, minWidth: 90, maxWidth: 110}}, - {style: {flex: 1}} - ]}, - {width: 300, height: 200, top: 0, left: 0, children: [ - {width: 100, height: 200, top: 0, left: 0}, - {width: 100, height: 200, top: 0, left: 100}, - {width: 100, height: 200, top: 0, left: 200} - ]} - ); - }); - - it('should not override flex direction size within bounds in rtl', function() { - testLayout( - {style: {width: 300, height: 200, direction: 'rtl', flexDirection: 'row'}, children: [ - {style: {flex: 1}}, - {style: {flex: 1, minWidth: 90, maxWidth: 110}}, - {style: {flex: 1}} - ]}, - {width: 300, height: 200, top: 0, left: 0, children: [ - {width: 100, height: 200, top: 0, left: 200}, - {width: 100, height: 200, top: 0, left: 100}, - {width: 100, height: 200, top: 0, left: 0} - ]} - ); - }); - - it('should override flex direction size with max bounds', function() { - testLayout( - {style: {width: 300, height: 200, flexDirection: 'row'}, children: [ - {style: {flex: 1}}, - {style: {flex: 1, maxWidth: 60}}, - {style: {flex: 1}} - ]}, - {width: 300, height: 200, top: 0, left: 0, children: [ - {width: 120, height: 200, top: 0, left: 0}, - {width: 60, height: 200, top: 0, left: 120}, - {width: 120, height: 200, top: 0, left: 180} - ]} - ); - }); - - it('should override flex direction size with max bounds in rtl', function() { - testLayout( - {style: {width: 300, height: 200, direction: 'rtl', flexDirection: 'row'}, children: [ - {style: {flex: 1}}, - {style: {flex: 1, maxWidth: 60}}, - {style: {flex: 1}} - ]}, - {width: 300, height: 200, top: 0, left: 0, children: [ - {width: 120, height: 200, top: 0, left: 180}, - {width: 60, height: 200, top: 0, left: 120}, - {width: 120, height: 200, top: 0, left: 0} - ]} - ); - }); - - it('should ignore flex size if fully max bound', function() { - testLayout( - {style: {width: 300, height: 200, flexDirection: 'row'}, children: [ - {style: {flex: 1, maxWidth: 60}}, - {style: {flex: 1, maxWidth: 60}}, - {style: {flex: 1, maxWidth: 60}} - ]}, - {width: 300, height: 200, top: 0, left: 0, children: [ - {width: 60, height: 200, top: 0, left: 0}, - {width: 60, height: 200, top: 0, left: 60}, - {width: 60, height: 200, top: 0, left: 120} - ]} - ); - }); - - it('should ignore flex size if fully max bound in rtl', function() { - testLayout( - {style: {width: 300, height: 200, direction: 'rtl', flexDirection: 'row'}, children: [ - {style: {flex: 1, maxWidth: 60}}, - {style: {flex: 1, maxWidth: 60}}, - {style: {flex: 1, maxWidth: 60}} - ]}, - {width: 300, height: 200, top: 0, left: 0, children: [ - {width: 60, height: 200, top: 0, left: 240}, - {width: 60, height: 200, top: 0, left: 180}, - {width: 60, height: 200, top: 0, left: 120} - ]} - ); - }); - - it('should ignore flex size if fully min bound', function() { - testLayout( - {style: {width: 300, height: 200, flexDirection: 'row'}, children: [ - {style: {flex: 1, minWidth: 120}}, - {style: {flex: 1, minWidth: 120}}, - {style: {flex: 1, minWidth: 120}} - ]}, - {width: 300, height: 200, top: 0, left: 0, children: [ - {width: 120, height: 200, top: 0, left: 0}, - {width: 120, height: 200, top: 0, left: 120}, - {width: 120, height: 200, top: 0, left: 240} - ]} - ); - }); - - it('should ignore flex size if fully min bound in rtl', function() { - testLayout( - {style: {width: 300, height: 200, direction: 'rtl', flexDirection: 'row'}, children: [ - {style: {flex: 1, minWidth: 120}}, - {style: {flex: 1, minWidth: 120}}, - {style: {flex: 1, minWidth: 120}} - ]}, - {width: 300, height: 200, top: 0, left: 0, children: [ - {width: 120, height: 200, top: 0, left: 180}, - {width: 120, height: 200, top: 0, left: 60}, - {width: 120, height: 200, top: 0, left: -60} - ]} - ); - }); - - it('should pre-fill child size within bounds', function() { - testLayout( - {style: {width: 300, height: 200}, children: [ - {style: {flex: 1, minWidth: 290, maxWidth: 310}} - ]}, - {width: 300, height: 200, top: 0, left: 0, children: [ - {width: 300, height: 200, top: 0, left: 0} - ]} - ); - }); - - it('should pre-fill child size within max bound', function() { - testLayout( - {style: {width: 300, height: 200}, children: [ - {style: {flex: 1, maxWidth: 290}} - ]}, - {width: 300, height: 200, top: 0, left: 0, children: [ - {width: 290, height: 200, top: 0, left: 0} - ]} - ); - }); - - it('should pre-fill child size within min bounds', function() { - testLayout( - {style: {width: 300, height: 200}, children: [ - {style: {flex: 1, minWidth: 310}} - ]}, - {width: 300, height: 200, top: 0, left: 0, children: [ - {width: 310, height: 200, top: 0, left: 0} - ]} - ); - }); - - it('should set parents size based on bounded children', function() { - testLayout( - {style: {minWidth: 100, maxWidth: 300, minHeight: 500, maxHeight: 700}, children: [ - {style: {width: 200, height: 300}}, - {style: {width: 200, height: 300}} - ]}, - {width: 200, height: 600, top: 0, left: 0, children: [ - {width: 200, height: 300, top: 0, left: 0}, - {width: 200, height: 300, top: 300, left: 0} - ]} - ); - }); - - it('should set parents size based on max bounded children', function() { - testLayout( - {style: {maxWidth: 100, maxHeight: 500}, children: [ - {style: {width: 200, height: 300}}, - {style: {width: 200, height: 300}} - ]}, - {width: 100, height: 500, top: 0, left: 0, children: [ - {width: 200, height: 300, top: 0, left: 0}, - {width: 200, height: 300, top: 300, left: 0} - ]} - ); - }); - - it('should set parents size based on min bounded children', function() { - testLayout( - {style: {minWidth: 300, minHeight: 700}, children: [ - {style: {width: 200, height: 300}}, - {style: {width: 200, height: 300}} - ]}, - {width: 300, height: 700, top: 0, left: 0, children: [ - {width: 200, height: 300, top: 0, left: 0}, - {width: 200, height: 300, top: 300, left: 0} - ]} - ); - }); - - it('should keep stretched size within bounds', function() { - testLayout( - {style: {width: 1000, alignItems: 'stretch'}, children: [ - {style: {height: 100, minHeight: 90, maxHeight: 110, minWidth: 900, maxWidth: 1100}} - ]}, - {width: 1000, height: 100, top: 0, left: 0, children: [ - {width: 1000, height: 100, top: 0, left: 0} - ]} - ); - }); - - it('should keep stretched size within max bounds', function() { - testLayout( - {style: {width: 1000, alignItems: 'stretch'}, children: [ - {style: {height: 100, maxHeight: 90, maxWidth: 900}} - ]}, - {width: 1000, height: 90, top: 0, left: 0, children: [ - {width: 900, height: 90, top: 0, left: 0} - ]} - ); - }); - - it('should keep stretched size within min bounds', function() { - testLayout( - {style: {width: 1000, alignItems: 'stretch'}, children: [ - {style: {height: 100, minHeight: 110, minWidth: 1100}} - ]}, - {width: 1000, height: 110, top: 0, left: 0, children: [ - {width: 1100, height: 110, top: 0, left: 0} - ]} - ); - }); - - it('should keep cross axis size within min bounds', function() { - testLayout( - {style: {width: 1000, flexDirection: 'row'}, children: [ - {style: {height: 100, minHeight: 110, minWidth: 100}} - ]}, - {width: 1000, height: 110, top: 0, left: 0, children: [ - {width: 100, height: 110, top: 0, left: 0} - ]} - ); - }); - - it('should keep cross axis size within min bounds in rtl', function() { - testLayout( - {style: {width: 1000, direction: 'rtl', flexDirection: 'row'}, children: [ - {style: {height: 100, minHeight: 110, minWidth: 100}} - ]}, - {width: 1000, height: 110, top: 0, left: 0, children: [ - {width: 100, height: 110, top: 0, left: 900} - ]} - ); - }); - - it('should layout node with position absolute, top and left and max bounds', function() { - testLayout( - {style: {width: 1000, height: 1000}, children: [ - {style: {position: 'absolute', top: 100, left: 100, bottom: 100, right: 100, maxWidth: 500, maxHeight: 600}} - ]}, - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 500, height: 600, top: 100, left: 100} - ]} - ); - }); - - it('should layout node with position absolute, top and left and min bounds', function() { - testLayout( - {style: {width: 1000, height: 1000}, children: [ - {style: {position: 'absolute', top: 100, left: 100, bottom: 100, right: 100, minWidth: 900, minHeight: 1000}} - ]}, - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 900, height: 1000, top: 100, left: 100} - ]} - ); - }); - - xit('should layout minHeight with a flex child', function() { - testLayout( - {style: {minHeight: 800}, children: [ - {style: {flex: 1}} - ]}, - {width: 0, height: 800, top: 0, left: 0, children: [ - {width: 0, height: 800, top: 0, left: 0} - ]} - ); - }); - - it('should center flexible item with max size', function() { - testLayout( - {style: {width: 1000, height: 1000, flexDirection: 'row', justifyContent: 'center'}, children: [ - {style: {flex: 1, maxWidth: 600, height: 1000}} - ]}, - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 600, height: 1000, top: 0, left: 200} - ]} - ); - }); - - it('should correctly size flexible items with flex basis and a max width', function() { - testLayout( - {style: {width: 1000, height: 1000, flexDirection: 'row'}, children: [ - {style: {flex: 1, width: 100, height: 1000}}, - {style: {flex: 1, width: 100, maxWidth: 200, height: 1000}} - ]}, - {width: 1000, height: 1000, top: 0, left: 0, children: [ - {width: 800, height: 1000, top: 0, left: 0}, - {width: 200, height: 1000, top: 0, left: 800} - ]} - ); - }); - - xit('should layout node with a nested sibling child with width', function() { - testLayout( - {style: {}, children: [ - {style: {width: 5}}, - {style: {}, children: [ - {style: {}} - ]} - ]}, - {width: 5, height: 0, top: 0, left: 0, children: [ - {width: 5, height: 0, top: 0, left: 0}, - {width: 5, height: 0, top: 0, left: 0, children: [ - {width: 5, height: 0, top: 0, left: 0} - ]} - ]} - ); - }); - - it('should layout absolutely positioned node with absolutely positioned padded parent', function() { - testLayout( - {style: {width: 400, height: 400}, children: [ - {style: {position: 'absolute', top: 100, left: 100, right: 100, bottom: 100, padding: 10}, children: [ - {style: {position: 'absolute', top: 10, left: 10, right: 10, bottom: 10}} - ]} - ]}, - {width: 400, height: 400, top: 0, left: 0, children: [ - {width: 200, height: 200, top: 100, left: 100, children: [ - {width: 180, height: 180, top: 10, left: 10} - ]} - ]} - ); - }); - - it('should layout absolutely positioned node with absolutely positioned padded and bordered parent', function() { - testLayout( - {style: {width: 400, height: 400}, children: [ - {style: {position: 'absolute', top: 100, left: 100, right: 100, bottom: 100, padding: 10, borderWidth: 1}, children: [ - {style: {position: 'absolute', top: 10, left: 10, right: 10, bottom: 10}} - ]} - ]}, - {width: 400, height: 400, top: 0, left: 0, children: [ - {width: 200, height: 200, top: 100, left: 100, children: [ - {width: 178, height: 178, top: 11, left: 11} - ]} - ]} - ); - }); - - it('should layout absolutely positioned node with padded flex 1 parent', function() { - testLayout( - {style: {width: 400, height: 400}, children: [ - {style: {flex: 1, padding: 10}, children: [ - {style: {position: 'absolute', top: 10, left: 10, right: 10, bottom: 10}} - ]} - ]}, - {width: 400, height: 400, top: 0, left: 0, children: [ - {width: 400, height: 400, top: 0, left: 0, children: [ - {width: 380, height: 380, top: 10, left: 10} - ]} - ]} - ); - }); - - it('should layout nested nodes with mixed directions', function() { - testLayout( - {style: {width: 200, height: 200, direction: 'rtl'}, children: [ - {style: {flexDirection: 'row'}, children: [ - {style: {width: 50, height: 50}}, - {style: {width: 50, height: 50}} - ]}, - {style: {direction: 'ltr', flexDirection: 'row'}, children: [ - {style: {width: 50, height: 50}}, - {style: {width: 50, height: 50}} - ]} - ]}, - {width: 200, height: 200, top: 0, left: 0, children: [ - {width: 200, height: 50, top: 0, left: 0, children: [ - {width: 50, height: 50, top: 0, left: 150}, - {width: 50, height: 50, top: 0, left: 100} - ]}, - {width: 200, height: 50, top: 50, left: 0, children: [ - {width: 50, height: 50, top: 0, left: 0}, - {width: 50, height: 50, top: 0, left: 50} - ]} - ]} - ); - }); - - it('should correctly space wrapped nodes', function() { - testLayout( - {style: {width: 320, height: 200, flexDirection: 'row', justifyContent: 'space-between', flexWrap: 'wrap'}, children: [ - {style: {width: 100, height: 100}}, - {style: {width: 100, height: 100}}, - {style: {width: 100, height: 100}}, - {style: {width: 100, height: 100}}, - {style: {width: 100, height: 100}}, - {style: {width: 100, height: 100}} - ]}, - {width: 320, height: 200, top: 0, left: 0, children: [ - {width: 100, height: 100, top: 0, left: 0}, - {width: 100, height: 100, top: 0, left: 110}, - {width: 100, height: 100, top: 0, left: 220}, - {width: 100, height: 100, top: 100, left: 0}, - {width: 100, height: 100, top: 100, left: 110}, - {width: 100, height: 100, top: 100, left: 220} - ]} - ); - }); - - - it('should give start/end padding precedence over left/right padding', function() { - testLayout( - {style: {width: 200, paddingLeft: 5, paddingStart: 15, paddingRight: 5, paddingEnd: 15}, children: [ - {style: {height: 50}} - ]}, - {width: 200, height: 50, top: 0, left: 0, children: [ - {width: 170, height: 50, top: 0, left: 15} - ]} - ); - }); - - it('should give start/end margin precedence over left/right margin', function() { - testLayout( - {style: {width: 200}, children: [ - {style: {height: 50, marginLeft: 5, marginStart: 15, marginRight: 5, marginEnd: 15}} - ]}, - {width: 200, height: 50, top: 0, left: 0, children: [ - {width: 170, height: 50, top: 0, left: 15} - ]} - ); - }); - - it('should give start/end border precedence over left/right border', function() { - testLayout( - {style: {width: 200, borderLeftWidth: 5, borderStartWidth: 15, borderRightWidth: 5, borderEndWidth: 15}, children: [ - {style: {height: 50}} - ]}, - {width: 200, height: 50, top: 0, left: 0, children: [ - {width: 170, height: 50, top: 0, left: 15} - ]} - ); - }); - - it('should layout node with correct start/end padding', function() { - testLayout( - {style: {width: 200, paddingStart: 15, paddingEnd: 5}, children: [ - {style: {height: 50}} - ]}, - {width: 200, height: 50, top: 0, left: 0, children: [ - {width: 180, height: 50, top: 0, left: 15} - ]} - ); - }); - - it('should layout node with correct start/end padding in rtl', function() { - testLayout( - {style: {width: 200, direction: 'rtl', paddingStart: 15, paddingEnd: 5}, children: [ - {style: {height: 50}} - ]}, - {width: 200, height: 50, top: 0, left: 0, children: [ - {width: 180, height: 50, top: 0, left: 5} - ]} - ); - }); - - it('should layout node with correct start/end margin', function() { - testLayout( - {style: {width: 200}, children: [ - {style: {height: 50, marginStart: 15, marginEnd: 5}} - ]}, - {width: 200, height: 50, top: 0, left: 0, children: [ - {width: 180, height: 50, top: 0, left: 15} - ]} - ); - }); - - it('should layout node with correct start/end margin in rtl', function() { - testLayout( - {style: {width: 200}, children: [ - {style: {height: 50, direction: 'rtl', marginStart: 15, marginEnd: 5}} - ]}, - {width: 200, height: 50, top: 0, left: 0, children: [ - {width: 180, height: 50, top: 0, left: 5} - ]} - ); - }); - - it('should layout node with correct start/end border', function() { - testLayout( - {style: {width: 200, borderStartWidth: 15, borderEndWidth: 5}, children: [ - {style: {height: 50}} - ]}, - {width: 200, height: 50, top: 0, left: 0, children: [ - {width: 180, height: 50, top: 0, left: 15} - ]} - ); - }); - - it('should layout node with correct start/end border in rtl', function() { - testLayout( - {style: {width: 200, direction: 'rtl', borderStartWidth: 15, borderEndWidth: 5}, children: [ - {style: {height: 50}} - ]}, - {width: 200, height: 50, top: 0, left: 0, children: [ - {width: 180, height: 50, top: 0, left: 5} - ]} - ); - }); - - it('should layout node with a 0 width', function() { - testLayout( - {style: {width: 200}, children: [ - {style: {width: 0}} - ]}, - {width: 200, height: 0, top: 0, left: 0, children: [ - {width: 0, height: 0, top: 0, left: 0} - ]} - ); - }); - - xit('should stretch a nested child', function() { - testLayout( - {children: [ - {children: [{}]}, - {style: {width: 40}} - ]}, - {width: 40, height: 0, top: 0, left: 0, children: [ - {width: 40, height: 0, top: 0, left: 0, children: [ - {width: 40, height: 0, top: 0, left: 0} - ]}, - {width: 40, height: 0, top: 0, left: 0} - ]} - ); - }); - - it('should correctly progagate size contraints from flexible parents', function() { - testLayoutAgainstExpectedOnly( - {style:{flexDirection: 'row', alignItems: 'flex-start', width: 100, height: 10}, children: [ - {style: {width: 50, height: 10}}, - {style:{flexDirection: 'column', alignItems: 'flex-start', flex: 1, height: 10}, children: [ - {style: {measure: measureWithMatchParent, flex: 1, height: 10}} - ]} - ]}, - {width: 100, height: 10, top: 0, left: 0, children: [ - {width: 50, height: 10, top: 0, left: 0}, - {width: 50, height: 10, top: 0, left:50, children: [ - {width: 50, height: 10, top: 0, left: 0} - ]}, - ]} - ); - }); - - // https://github.com/facebook/css-layout/issues/127 - it('should layout content of an item which is stretched late', function() { - testLayout( - {style: {flexDirection: 'row', alignItems: 'stretch', width: 150}, children: [ - {style: {flexDirection: 'row', marginTop: 10, marginLeft: 10}, children: [ - {style: {flexDirection: 'row'}, children: [ - {style: {alignSelf: 'center'}} - ]} - ]}, - {style: { height: 150}} - ]}, - {width: 150, height: 150, top: 0, left: 0, children: [ - {width: 0, height: 140, top: 10, left: 10, children: [ - {width: 0, height: 140, top: 0, left: 0, children: [ - {width: 0, height: 0, top: 70, left: 0} - ]} - ]}, - {width: 0, height: 150, top: 0, left: 10} - ]} - ); - }); - - it('should layout items whose positioning is determined by sibling tree branches', function() { - testLayout( - {style: {}, children: [ - {style: {}, children: [ - {style: {width: 200, height: 200}} - ]}, - {style: {marginTop: 10, marginLeft: 10}, children: [ - {style: {}} - ]} - ]}, - {width: 200, height: 210, top: 0, left: 0, children: [ - {width: 200, height: 200, top: 0, left: 0, children: [ - {width: 200, height: 200, top: 0, left: 0} - ]}, - {width: 190, height: 0, top: 210, left: 10, children: [ - {width: 190, height: 0, top: 0, left: 0} - ]} - ]} - ); - }); - - it('should layout child whose cross axis is undefined and whose alignSelf is stretch', function() { - testLayout( - {style: {flexDirection: 'row'}, children: [ - {style: {marginTop: 10, marginLeft: 10, alignSelf: 'flex-start'}}, - {style: {width: 1, alignSelf: 'stretch'}}, - {style: {height: 150}} - ]}, - {width: 11, height: 150, top: 0, left: 0, children: [ - {width: 0, height: 0, top: 10, left: 10}, - {width: 1, height: 150, top: 0, left: 10}, - {width: 0, height: 150, top: 0, left: 11} - ]} - ); - }); - - it('should center items correctly inside a stretched layout', function() { - testLayout( - {style: {flexDirection: 'row'}, children: [ - {style: {}, children: [ - {style: {width: 100, height: 100}} - ]}, - {style: {width: 100}, children: [ - {style: {flexDirection: 'column', alignItems: 'center'}, children: [ - {style: {width: 50, height: 50}}, - ]}, - ]}, - ]}, - {width: 200, height: 100, top: 0, left: 0, children: [ - {width: 100, height: 100, top: 0, left: 0, children: [ - {width: 100, height: 100, top: 0, left: 0} - ]}, - {width: 100, height: 100, top: 0, left: 100, children: [ - {width: 100, height: 50, top: 0, left: 0, children: [ - {width: 50, height: 50, top: 0, left: 25} - ]}, - ]}, - ]} - ); - }); -}); - -describe('Layout flex:-1', function() { - // Tests for items with flex:-1 in a container with flexDirection:column - - it('should not shrink column node when there is space left over', function() { - testLayout( - {style: {width: 100, height: 100}, children: [ - {style: {width: 100, flex: -1}, children: [ - {style: {width: 100, height: 25}} - ]} - ]}, - {width: 100, height: 100, top: 0, left: 0, children: [ - {width: 100, height: 25, top: 0, left: 0, children: [ - {width: 100, height: 25, top: 0, left: 0} - ]} - ]} - ); - }); - - it('should shrink column node when there is not any space left over', function() { - testLayout( - {style: {width: 100, height: 100}, children: [ - {style: {width: 100, flex: -1}, children: [ - {style: {width: 100, height: 200}} - ]} - ]}, - {width: 100, height: 100, top: 0, left: 0, children: [ - {width: 100, height: 100, top: 0, left: 0, children: [ - {width: 100, height: 200, top: 0, left: 0} - ]} - ]} - ); - }); - - it('should not shrink column node with siblings when there is space left over', function() { - testLayout( - {style: {width: 100, height: 100}, children: [ - {style: {width: 100, height: 25}}, - {style: {width: 100, flex: -1}, children: [ - {style: {width: 100, height: 30}} - ]}, - {style: {width: 100, height: 15}}, - ]}, - {width: 100, height: 100, top: 0, left: 0, children: [ - {width: 100, height: 25, top: 0, left: 0}, - {width: 100, height: 30, top: 25, left: 0, children: [ - {width: 100, height: 30, top: 0, left: 0} - ]}, - {width: 100, height: 15, top: 55, left: 0}, - ]} - ); - }); - - it('should shrink column node with siblings when there is not any space left over', function() { - testLayout( - {style: {width: 100, height: 100}, children: [ - {style: {width: 100, height: 25}}, - {style: {width: 100, flex: -1}, children: [ - {style: {width: 100, height: 80}} - ]}, - {style: {width: 100, height: 15}}, - ]}, - {width: 100, height: 100, top: 0, left: 0, children: [ - {width: 100, height: 25, top: 0, left: 0}, - {width: 100, height: 60, top: 25, left: 0, children: [ - {width: 100, height: 80, top: 0, left: 0} - ]}, - {width: 100, height: 15, top: 85, left: 0}, - ]} - ); - }); - - it('should shrink column nodes proportional to their main size when there is not any space left over', function() { - testLayout( - {style: {width: 100, height: 100}, children: [ - {style: {width: 100, height: 30, flex: -1}}, - {style: {width: 100, height: 40}}, - {style: {width: 100, height: 50, flex: -1}} - ]}, - {width: 100, height: 100, top: 0, left: 0, children: [ - {width: 100, height: 22.5, top: 0, left: 0}, - {width: 100, height: 40, top: 22.5, left: 0}, - {width: 100, height: 37.5, top: 62.5, left: 0} - ]} - ); - }); - - // Tests for items with flex:-1 and overflow:visible in a container with flexDirection:row - - it('should not shrink visible row node when there is space left over', function() { - testLayout( - {style: {width: 100, height: 100, flexDirection: 'row'}, children: [ - {style: {height: 100, flex: -1}, children: [ - {style: {width: 25, height: 100}} - ]} - ]}, - {width: 100, height: 100, top: 0, left: 0, children: [ - {width: 25, height: 100, top: 0, left: 0, children: [ - {width: 25, height: 100, top: 0, left: 0} - ]} - ]} - ); - }); - - it('should shrink visible row node when there is not any space left over', function() { - testLayout( - {style: {width: 100, height: 100, flexDirection: 'row'}, children: [ - {style: {height: 100, flex: -1}, children: [ - {style: {width: 200, height: 100}} - ]} - ]}, - {width: 100, height: 100, top: 0, left: 0, children: [ - // width would be 100 if we implemented https://www.w3.org/TR/css-flexbox-1/#min-size-auto and min-width didn't default to 0 - {width: 100, height: 100, top: 0, left: 0, children: [ - {width: 200, height: 100, top: 0, left: 0} - ]} - ]} - ); - }); - - it('should not shrink visible row node with siblings when there is space left over', function() { - testLayout( - {style: {width: 100, height: 100, flexDirection: 'row'}, children: [ - {style: {width: 25, height: 100}}, - {style: {height: 100, flex: -1}, children: [ - {style: {width: 30, height: 100}} - ]}, - {style: {width: 15, height: 100}}, - ]}, - {width: 100, height: 100, top: 0, left: 0, children: [ - {width: 25, height: 100, top: 0, left: 0}, - {width: 30, height: 100, top: 0, left: 25, children: [ - {width: 30, height: 100, top: 0, left: 0} - ]}, - {width: 15, height: 100, top: 0, left: 55}, - ]} - ); - }); - - it('should shrink visible row node with siblings when there is not any space left over', function() { - testLayout( - {style: {width: 100, height: 100, flexDirection: 'row'}, children: [ - {style: {width: 25, height: 100}}, - {style: {height: 100, flex: -1}, children: [ - {style: {width: 80, height: 100}} - ]}, - {style: {width: 15, height: 100}}, - ]}, - {width: 100, height: 100, top: 0, left: 0, children: [ - {width: 25, height: 100, top: 0, left: 0}, - // width would be 80 if we implemented https://www.w3.org/TR/css-flexbox-1/#min-size-auto and min-width didn't default to 0 - {width: 60, height: 100, top: 0, left: 25, children: [ - {width: 80, height: 100, top: 0, left: 0} - ]}, - {width: 15, height: 100, top: 0, left: 85}, - ]} - ); - }); - - it('should shrink visible row nodes when there is not any space left over', function() { - testLayout( - {style: {width: 100, height: 100, flexDirection: 'row'}, children: [ - {style: {width: 30, height: 100, flex: -1}}, - {style: {width: 40, height: 100}}, - {style: {width: 50, height: 100, flex: -1}} - ]}, - {width: 100, height: 100, top: 0, left: 0, children: [ - // width would be 30 if we implemented https://www.w3.org/TR/css-flexbox-1/#min-size-auto and min-width didn't default to 0 - {width: 22.5, height: 100, top: 0, left: 0}, - {width: 40, height: 100, top: 0, left: 22.5}, - // width would be 50 if we implemented https://www.w3.org/TR/css-flexbox-1/#min-size-auto and min-width didn't default to 0 - {width: 37.5, height: 100, top: 0, left: 62.5} - ]} - ); - }); - - // Tests for items with flex:-1 and overflow:hidden in a container with flexDirection:row - - it('should not shrink hidden row node when there is space left over', function() { - testLayout( - {style: {width: 100, height: 100, flexDirection: 'row'}, children: [ - {style: {height: 100, flex: -1, overflow: 'hidden'}, children: [ - {style: {width: 25, height: 100}} - ]} - ]}, - {width: 100, height: 100, top: 0, left: 0, children: [ - {width: 25, height: 100, top: 0, left: 0, children: [ - {width: 25, height: 100, top: 0, left: 0} - ]} - ]} - ); - }); - - it('should shrink hidden row node when there is not any space left over', function() { - testLayout( - {style: {width: 100, height: 100, flexDirection: 'row'}, children: [ - {style: {height: 100, flex: -1, overflow: 'hidden'}, children: [ - {style: {width: 200, height: 100}} - ]} - ]}, - {width: 100, height: 100, top: 0, left: 0, children: [ - {width: 100, height: 100, top: 0, left: 0, children: [ - {width: 200, height: 100, top: 0, left: 0} - ]} - ]} - ); - }); - - it('should not shrink hidden row node with siblings when there is space left over', function() { - testLayout( - {style: {width: 100, height: 100, flexDirection: 'row'}, children: [ - {style: {width: 25, height: 100}}, - {style: {height: 100, flex: -1, overflow: 'hidden'}, children: [ - {style: {width: 30, height: 100}} - ]}, - {style: {width: 15, height: 100}}, - ]}, - {width: 100, height: 100, top: 0, left: 0, children: [ - {width: 25, height: 100, top: 0, left: 0}, - {width: 30, height: 100, top: 0, left: 25, children: [ - {width: 30, height: 100, top: 0, left: 0} - ]}, - {width: 15, height: 100, top: 0, left: 55}, - ]} - ); - }); - - it('should shrink hidden row node with siblings when there is not any space left over', function() { - testLayout( - {style: {width: 100, height: 100, flexDirection: 'row'}, children: [ - {style: {width: 25, height: 100}}, - {style: {height: 100, flex: -1, overflow: 'hidden'}, children: [ - {style: {width: 80, height: 100}} - ]}, - {style: {width: 15, height: 100}}, - ]}, - {width: 100, height: 100, top: 0, left: 0, children: [ - {width: 25, height: 100, top: 0, left: 0}, - {width: 60, height: 100, top: 0, left: 25, children: [ - {width: 80, height: 100, top: 0, left: 0} - ]}, - {width: 15, height: 100, top: 0, left: 85}, - ]} - ); - }); - - it('should shrink hidden row nodes proportional to their main size when there is not any space left over', function() { - testLayout( - {style: {width: 100, height: 100, flexDirection: 'row'}, children: [ - {style: {width: 30, height: 100, flex: -1, overflow: 'hidden'}}, - {style: {width: 40, height: 100}}, - {style: {width: 50, height: 100, flex: -1, overflow: 'hidden'}} - ]}, - {width: 100, height: 100, top: 0, left: 0, children: [ - {width: 22.5, height: 100, top: 0, left: 0}, - {width: 40, height: 100, top: 0, left: 22.5}, - {width: 37.5, height: 100, top: 0, left: 62.5} - ]} - ); - }); - - // Tests for items with flex:-1 containing a text node - - it('should not shrink text node with siblings when there is space left over', function() { - testLayoutAgainstExpectedOnly( - {style: {width: 213, height: 100, flexDirection: 'row'}, children: [ - {style: {width: 25, height: 100}}, - {style: {height: 100, flex: -1, flexDirection: 'row', alignItems: 'flex-start'}, children: [ - {style: {measure: text(texts.big)}} - ]}, - {style: {width: 15, height: 100}}, - ]}, - {width: 213, height: 100, top: 0, left: 0, children: [ - {width: 25, height: 100, top: 0, left: 0}, - {width: textSizes.bigWidth, height: 100, top: 0, left: 25, children: [ - {width: textSizes.bigWidth, height: textSizes.smallHeight, top: 0, left: 0} - ]}, - {width: 15, height: 100, top: 0, left: 25 + textSizes.bigWidth}, - ]} - ); - }); - - it('should shrink text node with siblings when there is not any space left over', function() { - testLayout( - {style: {width: 140, height: 100, flexDirection: 'row'}, children: [ - {style: {width: 25, height: 100}}, - {style: {height: 100, flex: -1, flexDirection: 'row', alignItems: 'flex-start'}, children: [ - {style: {flex: -1, measure: text(texts.big)}} - ]}, - {style: {width: 15, height: 100}}, - ]}, - {width: 140, height: 100, top: 0, left: 0, children: [ - {width: 25, height: 100, top: 0, left: 0}, - {width: textSizes.bigMinWidth, height: 100, top: 0, left: 25, children: [ - {width: textSizes.bigMinWidth, height: textSizes.bigHeight, top: 0, left: 0} - ]}, - {width: 15, height: 100, top: 0, left: 25 + textSizes.bigMinWidth}, - ]} - ); - }); -}); - -describe('Layout alignContent', function() { - - it('should layout with alignContent: stretch, and alignItems: flex-start', function() { - testLayout( - {style: {width: 300, height: 380, flexDirection: 'row', flexWrap: 'wrap', alignContent: 'stretch', alignItems: 'flex-start'}, - children: [ - /* 0 */ {style: {width: 50, height: 50, margin: 10}}, - /* 1 */ {style: {width: 50, height: 50, margin: 10}}, - /* 2 */ {style: {width: 50, height: 50, margin: 10}}, - /* 3 */ {style: {width: 50, height: 50, margin: 10}}, - /* 4 */ {style: {width: 50, height: 100, margin: 10}}, - /* 5 */ {style: {width: 50, height: 50, margin: 10, alignSelf: 'flex-start'}}, - /* 6 */ {style: {width: 50, height: 50, margin: 10}}, - /* 7 */ {style: {width: 50, height: 100, margin: 10}}, - /* 8 */ {style: {width: 50, height: 50, margin: 10}}, - /* 9 */ {style: {width: 50, height: 50, margin: 10}}, - /* 10 */ {style: {width: 50, height: 50, margin: 10, alignSelf: 'flex-start' }}, - /* 11 */ {style: {width: 50, height: 50, margin: 10}}, - /* 12 */ {style: {width: 50, height: 50, margin: 10}}, - /* 13 */ {style: {width: 50, height: 50, margin: 10, alignSelf: 'flex-start'}}, - /* 14 */ {style: {width: 50, height: 50, margin: 10}} - ] - }, - {width: 300, height: 380, top: 0, left: 0, children: [ - {width: 50, height: 50, top: 10, left: 10}, - {width: 50, height: 50, top: 10, left: 80}, - {width: 50, height: 50, top: 10, left: 150}, - {width: 50, height: 50, top: 10, left: 220}, - {width: 50, height: 100, top: 92.5, left: 10}, - {width: 50, height: 50, top: 92.5, left: 80}, - {width: 50, height: 50, top: 92.5, left: 150}, - {width: 50, height: 100, top: 92.5, left: 220}, - {width: 50, height: 50, top: 225, left: 10}, - {width: 50, height: 50, top: 225, left: 80}, - {width: 50, height: 50, top: 225, left: 150}, - {width: 50, height: 50, top: 225, left: 220}, - {width: 50, height: 50, top: 307.5, left: 10}, - {width: 50, height: 50, top: 307.5, left: 80}, - {width: 50, height: 50, top: 307.5, left: 150} - ]} - ); - }); - - - function testAlignContent(alignContent, alignItems) { - it('should layout with alignContent: ' + alignContent + ', and alignItems: ' + alignItems, function() { - testLayoutAgainstDomOnly( - {style: {width: 300, height: 380, flexDirection: 'row', flexWrap: 'wrap', alignContent: alignContent, alignItems: alignItems}, - children: [ - /* 0 */ {style: {width: 50, height: 50, margin: 10}}, - /* 1 */ {style: {width: 50, height: 50, margin: 10}}, - /* 2 */ {style: {width: 50, height: 50, margin: 10}}, - /* 3 */ {style: {width: 50, height: 50, margin: 10}}, - /* 4 */ {style: {width: 50, height: 100, margin: 10}}, - /* 5 */ {style: {width: 50, height: 50, margin: 10, alignSelf: 'flex-start'}}, - /* 6 */ {style: {width: 50, height: 50, margin: 10}}, - /* 7 */ {style: {width: 50, height: 100, margin: 10}}, - /* 8 */ {style: {width: 50, height: 50, margin: 10}}, - /* 9 */ {style: {width: 50, height: 50, margin: 10}}, - /* 10 */ {style: {width: 50, height: 50, margin: 10, alignSelf: 'flex-start' }}, - /* 11 */ {style: {width: 50, height: 50, margin: 10}}, - /* 12 */ {style: {width: 50, height: 50, margin: 10}}, - /* 13 */ {style: {width: 50, height: 50, margin: 10, alignSelf: 'flex-start'}}, - /* 14 */ {style: {width: 50, height: 50, margin: 10}} - ] - } - ); - }); - } - testAlignContent('stretch', 'center'); - testAlignContent('stretch', 'flex-end'); - testAlignContent('stretch', 'stretch'); - - testAlignContent('flex-start', 'flex-start'); - testAlignContent('flex-start', 'center'); - testAlignContent('flex-start', 'flex-end'); - testAlignContent('flex-start', 'stretch'); - - testAlignContent('center', 'flex-start'); - testAlignContent('center', 'center'); - testAlignContent('center', 'flex-end'); - testAlignContent('center', 'stretch'); - - testAlignContent('flex-end', 'flex-start'); - testAlignContent('flex-end', 'center'); - testAlignContent('flex-end', 'flex-end'); - testAlignContent('flex-end', 'stretch'); -}); diff --git a/java/java/tests/com/facebook/csslayout/CSSNodeTest.java b/tests/java/com/facebook/csslayout/CSSNodeTest.java similarity index 96% rename from java/java/tests/com/facebook/csslayout/CSSNodeTest.java rename to tests/java/com/facebook/csslayout/CSSNodeTest.java index 57431b44..f5dadec8 100644 --- a/java/java/tests/com/facebook/csslayout/CSSNodeTest.java +++ b/tests/java/com/facebook/csslayout/CSSNodeTest.java @@ -1,11 +1,12 @@ /** - * Copyright (c) 2014, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ + package com.facebook.csslayout; import org.junit.Test; diff --git a/java/java/tests/com/facebook/csslayout/LayoutCachingTest.java b/tests/java/com/facebook/csslayout/LayoutCachingTest.java similarity index 99% rename from java/java/tests/com/facebook/csslayout/LayoutCachingTest.java rename to tests/java/com/facebook/csslayout/LayoutCachingTest.java index 492571cf..78cd8a72 100644 --- a/java/java/tests/com/facebook/csslayout/LayoutCachingTest.java +++ b/tests/java/com/facebook/csslayout/LayoutCachingTest.java @@ -1,11 +1,12 @@ /** - * Copyright (c) 2014, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ + package com.facebook.csslayout; import org.junit.Test; diff --git a/java/java/tests/com/facebook/csslayout/LayoutEngineTest.java b/tests/java/com/facebook/csslayout/LayoutEngineTest.java similarity index 98% rename from java/java/tests/com/facebook/csslayout/LayoutEngineTest.java rename to tests/java/com/facebook/csslayout/LayoutEngineTest.java index 4337dc20..f901b3e3 100644 --- a/java/java/tests/com/facebook/csslayout/LayoutEngineTest.java +++ b/tests/java/com/facebook/csslayout/LayoutEngineTest.java @@ -1,11 +1,12 @@ /** - * Copyright (c) 2014, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ + package com.facebook.csslayout; import org.junit.Assert; @@ -34,20 +35,24 @@ public class LayoutEngineTest { width = 10000000; } measureOutput.width = Math.min(width, TestConstants.SMALL_WIDTH); - measureOutput.height = TestConstants.SMALL_HEIGHT; + measureOutput.height = TestConstants.SMALL_WIDTH > width ? TestConstants.BIG_HEIGHT : TestConstants.SMALL_HEIGHT; } else if (testNode.context.equals(TestConstants.LONG_TEXT)) { if (widthMode == CSSMeasureMode.UNDEFINED) { width = 10000000; } - 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; + measureOutput.width = Math.min(width, TestConstants.BIG_WIDTH); + measureOutput.height = TestConstants.BIG_WIDTH > width ? TestConstants.BIG_HEIGHT : TestConstants.SMALL_HEIGHT; } else if (testNode.context.equals(TestConstants.MEASURE_WITH_RATIO_2)) { - if (widthMode != CSSMeasureMode.UNDEFINED) { + if (widthMode == CSSMeasureMode.EXACTLY) { measureOutput.width = width; measureOutput.height = width * 2; - } else if (heightMode != CSSMeasureMode.UNDEFINED) { + } else if (heightMode == CSSMeasureMode.EXACTLY) { + measureOutput.width = height * 2; + measureOutput.height = height; + } else if (widthMode == CSSMeasureMode.AT_MOST) { + measureOutput.width = width; + measureOutput.height = width * 2; + } else if (heightMode == CSSMeasureMode.AT_MOST) { measureOutput.width = height * 2; measureOutput.height = height; } else { @@ -4251,7 +4256,7 @@ public class LayoutEngineTest { { TestCSSNode node_0 = root_node; node_0.setMeasureFunction(sTestMeasureFunction); - node_0.context = "small"; + node_0.context = TestConstants.SMALL_TEXT; } TestCSSNode root_layout = new TestCSSNode(); @@ -4259,8 +4264,8 @@ public class LayoutEngineTest { TestCSSNode node_0 = root_layout; node_0.layout.position[POSITION_TOP] = 0; node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 35; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 18; + node_0.layout.dimensions[DIMENSION_WIDTH] = TestConstants.SMALL_WIDTH; + node_0.layout.dimensions[DIMENSION_HEIGHT] = TestConstants.SMALL_HEIGHT; } test("should layout node with just text", root_node, root_layout); @@ -4274,7 +4279,7 @@ public class LayoutEngineTest { TestCSSNode node_0 = root_node; node_0.style.dimensions[DIMENSION_WIDTH] = 100; node_0.setMeasureFunction(sTestMeasureFunction); - node_0.context = "measureWithRatio2"; + node_0.context = TestConstants.MEASURE_WITH_RATIO_2; } TestCSSNode root_layout = new TestCSSNode(); @@ -4297,7 +4302,7 @@ public class LayoutEngineTest { TestCSSNode node_0 = root_node; node_0.style.dimensions[DIMENSION_HEIGHT] = 100; node_0.setMeasureFunction(sTestMeasureFunction); - node_0.context = "measureWithRatio2"; + node_0.context = TestConstants.MEASURE_WITH_RATIO_2; } TestCSSNode root_layout = new TestCSSNode(); @@ -4321,7 +4326,7 @@ public class LayoutEngineTest { node_0.style.dimensions[DIMENSION_WIDTH] = 100; node_0.style.dimensions[DIMENSION_HEIGHT] = 100; node_0.setMeasureFunction(sTestMeasureFunction); - node_0.context = "measureWithRatio2"; + node_0.context = TestConstants.MEASURE_WITH_RATIO_2; } TestCSSNode root_layout = new TestCSSNode(); @@ -4343,7 +4348,7 @@ public class LayoutEngineTest { { TestCSSNode node_0 = root_node; node_0.setMeasureFunction(sTestMeasureFunction); - node_0.context = "measureWithRatio2"; + node_0.context = TestConstants.MEASURE_WITH_RATIO_2; } TestCSSNode root_layout = new TestCSSNode(); @@ -4371,7 +4376,7 @@ public class LayoutEngineTest { TestCSSNode node_1; node_1 = node_0.getChildAt(0); node_1.setMeasureFunction(sTestMeasureFunction); - node_1.context = "measureWithRatio2"; + node_1.context = TestConstants.MEASURE_WITH_RATIO_2; node_1 = node_0.getChildAt(1); node_1.style.flexDirection = CSSFlexDirection.ROW; node_1.style.overflow = CSSOverflow.HIDDEN; @@ -4381,10 +4386,10 @@ public class LayoutEngineTest { TestCSSNode node_2; node_2 = node_1.getChildAt(0); node_2.setMeasureFunction(sTestMeasureFunction); - node_2.context = "measureWithRatio2"; + node_2.context = TestConstants.MEASURE_WITH_RATIO_2; node_2 = node_1.getChildAt(1); node_2.setMeasureFunction(sTestMeasureFunction); - node_2.context = "measureWithRatio2"; + node_2.context = TestConstants.MEASURE_WITH_RATIO_2; } } } @@ -4437,7 +4442,7 @@ public class LayoutEngineTest { TestCSSNode node_0 = root_node; node_0.style.dimensions[DIMENSION_WIDTH] = 10; node_0.setMeasureFunction(sTestMeasureFunction); - node_0.context = "small"; + node_0.context = TestConstants.SMALL_TEXT; } TestCSSNode root_layout = new TestCSSNode(); @@ -4446,7 +4451,7 @@ public class LayoutEngineTest { node_0.layout.position[POSITION_TOP] = 0; node_0.layout.position[POSITION_LEFT] = 0; node_0.layout.dimensions[DIMENSION_WIDTH] = 10; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 18; + node_0.layout.dimensions[DIMENSION_HEIGHT] = TestConstants.BIG_HEIGHT; } test("should layout node with text and width", root_node, root_layout); @@ -4459,7 +4464,7 @@ public class LayoutEngineTest { { TestCSSNode node_0 = root_node; node_0.setMeasureFunction(sTestMeasureFunction); - node_0.context = "loooooooooong with space"; + node_0.context = TestConstants.LONG_TEXT; } TestCSSNode root_layout = new TestCSSNode(); @@ -4467,8 +4472,8 @@ public class LayoutEngineTest { TestCSSNode node_0 = root_layout; node_0.layout.position[POSITION_TOP] = 0; node_0.layout.position[POSITION_LEFT] = 0; - node_0.layout.dimensions[DIMENSION_WIDTH] = 172; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 18; + node_0.layout.dimensions[DIMENSION_WIDTH] = TestConstants.BIG_WIDTH; + node_0.layout.dimensions[DIMENSION_HEIGHT] = TestConstants.SMALL_HEIGHT; } test("should layout node with text, padding and margin", root_node, root_layout); @@ -4543,7 +4548,7 @@ public class LayoutEngineTest { node_2 = node_1.getChildAt(0); node_2.style.flex = 1; node_2.setMeasureFunction(sTestMeasureFunction); - node_2.context = "loooooooooong with space"; + node_2.context = TestConstants.LONG_TEXT; } } } @@ -4554,7 +4559,7 @@ public class LayoutEngineTest { node_0.layout.position[POSITION_TOP] = 0; node_0.layout.position[POSITION_LEFT] = 0; node_0.layout.dimensions[DIMENSION_WIDTH] = 500; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 18; + node_0.layout.dimensions[DIMENSION_HEIGHT] = TestConstants.SMALL_HEIGHT; addChildren(node_0, 1); { TestCSSNode node_1; @@ -4562,7 +4567,7 @@ public class LayoutEngineTest { node_1.layout.position[POSITION_TOP] = 0; node_1.layout.position[POSITION_LEFT] = 0; node_1.layout.dimensions[DIMENSION_WIDTH] = 500; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 18; + node_1.layout.dimensions[DIMENSION_HEIGHT] = TestConstants.SMALL_HEIGHT; addChildren(node_1, 1); { TestCSSNode node_2; @@ -4570,7 +4575,7 @@ public class LayoutEngineTest { node_2.layout.position[POSITION_TOP] = 0; node_2.layout.position[POSITION_LEFT] = 0; node_2.layout.dimensions[DIMENSION_WIDTH] = 500; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 18; + node_2.layout.dimensions[DIMENSION_HEIGHT] = TestConstants.SMALL_HEIGHT; } } } @@ -4597,7 +4602,7 @@ public class LayoutEngineTest { node_2 = node_1.getChildAt(0); node_2.style.flex = 1; node_2.setMeasureFunction(sTestMeasureFunction); - node_2.context = "loooooooooong with space"; + node_2.context = TestConstants.LONG_TEXT; } } } @@ -4608,7 +4613,7 @@ public class LayoutEngineTest { node_0.layout.position[POSITION_TOP] = 0; node_0.layout.position[POSITION_LEFT] = 0; node_0.layout.dimensions[DIMENSION_WIDTH] = 500; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 18; + node_0.layout.dimensions[DIMENSION_HEIGHT] = TestConstants.SMALL_HEIGHT; addChildren(node_0, 1); { TestCSSNode node_1; @@ -4616,7 +4621,7 @@ public class LayoutEngineTest { node_1.layout.position[POSITION_TOP] = 0; node_1.layout.position[POSITION_LEFT] = 0; node_1.layout.dimensions[DIMENSION_WIDTH] = 500; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 18; + node_1.layout.dimensions[DIMENSION_HEIGHT] = TestConstants.SMALL_HEIGHT; addChildren(node_1, 1); { TestCSSNode node_2; @@ -4624,7 +4629,7 @@ public class LayoutEngineTest { node_2.layout.position[POSITION_TOP] = 0; node_2.layout.position[POSITION_LEFT] = 0; node_2.layout.dimensions[DIMENSION_WIDTH] = 500; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 18; + node_2.layout.dimensions[DIMENSION_HEIGHT] = TestConstants.SMALL_HEIGHT; } } } @@ -4650,7 +4655,7 @@ public class LayoutEngineTest { TestCSSNode node_2; node_2 = node_1.getChildAt(0); node_2.setMeasureFunction(sTestMeasureFunction); - node_2.context = "loooooooooong with space"; + node_2.context = TestConstants.LONG_TEXT; } } } @@ -4661,7 +4666,7 @@ public class LayoutEngineTest { node_0.layout.position[POSITION_TOP] = 0; node_0.layout.position[POSITION_LEFT] = 0; node_0.layout.dimensions[DIMENSION_WIDTH] = 130; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 36; + node_0.layout.dimensions[DIMENSION_HEIGHT] = TestConstants.BIG_HEIGHT; addChildren(node_0, 1); { TestCSSNode node_1; @@ -4669,7 +4674,7 @@ public class LayoutEngineTest { node_1.layout.position[POSITION_TOP] = 0; node_1.layout.position[POSITION_LEFT] = 0; node_1.layout.dimensions[DIMENSION_WIDTH] = 130; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 36; + node_1.layout.dimensions[DIMENSION_HEIGHT] = TestConstants.BIG_HEIGHT; addChildren(node_1, 1); { TestCSSNode node_2; @@ -4677,7 +4682,7 @@ public class LayoutEngineTest { node_2.layout.position[POSITION_TOP] = 0; node_2.layout.position[POSITION_LEFT] = 0; node_2.layout.dimensions[DIMENSION_WIDTH] = 130; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 36; + node_2.layout.dimensions[DIMENSION_HEIGHT] = TestConstants.BIG_HEIGHT; } } } @@ -4704,7 +4709,7 @@ public class LayoutEngineTest { node_2 = node_1.getChildAt(0); node_2.style.dimensions[DIMENSION_WIDTH] = 130; node_2.setMeasureFunction(sTestMeasureFunction); - node_2.context = "loooooooooong with space"; + node_2.context = TestConstants.LONG_TEXT; } } } @@ -4715,7 +4720,7 @@ public class LayoutEngineTest { node_0.layout.position[POSITION_TOP] = 0; node_0.layout.position[POSITION_LEFT] = 0; node_0.layout.dimensions[DIMENSION_WIDTH] = 200; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 36; + node_0.layout.dimensions[DIMENSION_HEIGHT] = TestConstants.BIG_HEIGHT; addChildren(node_0, 1); { TestCSSNode node_1; @@ -4723,7 +4728,7 @@ public class LayoutEngineTest { node_1.layout.position[POSITION_TOP] = 0; node_1.layout.position[POSITION_LEFT] = 0; node_1.layout.dimensions[DIMENSION_WIDTH] = 200; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 36; + node_1.layout.dimensions[DIMENSION_HEIGHT] = TestConstants.BIG_HEIGHT; addChildren(node_1, 1); { TestCSSNode node_2; @@ -4731,7 +4736,7 @@ public class LayoutEngineTest { node_2.layout.position[POSITION_TOP] = 0; node_2.layout.position[POSITION_LEFT] = 0; node_2.layout.dimensions[DIMENSION_WIDTH] = 130; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 36; + node_2.layout.dimensions[DIMENSION_HEIGHT] = TestConstants.BIG_HEIGHT; } } } @@ -4753,7 +4758,7 @@ public class LayoutEngineTest { node_1 = node_0.getChildAt(0); node_1.style.alignSelf = CSSAlign.FLEX_START; node_1.setMeasureFunction(sTestMeasureFunction); - node_1.context = "loooooooooong with space"; + node_1.context = TestConstants.LONG_TEXT; } } @@ -4763,7 +4768,7 @@ public class LayoutEngineTest { node_0.layout.position[POSITION_TOP] = 0; node_0.layout.position[POSITION_LEFT] = 0; node_0.layout.dimensions[DIMENSION_WIDTH] = 100; - node_0.layout.dimensions[DIMENSION_HEIGHT] = 36; + node_0.layout.dimensions[DIMENSION_HEIGHT] = TestConstants.BIG_HEIGHT; addChildren(node_0, 1); { TestCSSNode node_1; @@ -4771,7 +4776,7 @@ public class LayoutEngineTest { node_1.layout.position[POSITION_TOP] = 0; node_1.layout.position[POSITION_LEFT] = 0; node_1.layout.dimensions[DIMENSION_WIDTH] = 100; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 36; + node_1.layout.dimensions[DIMENSION_HEIGHT] = TestConstants.BIG_HEIGHT; } } @@ -4808,7 +4813,7 @@ public class LayoutEngineTest { TestCSSNode node_2; node_2 = node_1.getChildAt(0); node_2.setMeasureFunction(sTestMeasureFunction); - node_2.context = "loooooooooong with space"; + node_2.context = TestConstants.LONG_TEXT; } } } @@ -4827,15 +4832,15 @@ public class LayoutEngineTest { node_1.layout.position[POSITION_TOP] = 20; node_1.layout.position[POSITION_LEFT] = 20; node_1.layout.dimensions[DIMENSION_WIDTH] = 60; - node_1.layout.dimensions[DIMENSION_HEIGHT] = 36; + node_1.layout.dimensions[DIMENSION_HEIGHT] = TestConstants.BIG_HEIGHT; addChildren(node_1, 1); { TestCSSNode node_2; node_2 = node_1.getChildAt(0); node_2.layout.position[POSITION_TOP] = 0; node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 100; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 36; + node_2.layout.dimensions[DIMENSION_WIDTH] = 60; + node_2.layout.dimensions[DIMENSION_HEIGHT] = TestConstants.BIG_HEIGHT; } } } @@ -5030,7 +5035,7 @@ public class LayoutEngineTest { node_2.setMargin(Spacing.START, 20); node_2.setMargin(Spacing.END, 20); node_2.setMeasureFunction(sTestMeasureFunction); - node_2.context = "loooooooooong with space"; + node_2.context = TestConstants.SMALL_TEXT; } } } @@ -5056,8 +5061,8 @@ public class LayoutEngineTest { node_2 = node_1.getChildAt(0); node_2.layout.position[POSITION_TOP] = 20; node_2.layout.position[POSITION_LEFT] = 20; - node_2.layout.dimensions[DIMENSION_WIDTH] = 172; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 18; + node_2.layout.dimensions[DIMENSION_WIDTH] = TestConstants.SMALL_WIDTH; + node_2.layout.dimensions[DIMENSION_HEIGHT] = TestConstants.SMALL_HEIGHT; } } } @@ -5089,7 +5094,7 @@ public class LayoutEngineTest { node_2.setMargin(Spacing.START, 20); node_2.setMargin(Spacing.END, 20); node_2.setMeasureFunction(sTestMeasureFunction); - node_2.context = "loooooooooong with space"; + node_2.context = TestConstants.SMALL_TEXT; } } } @@ -5114,9 +5119,9 @@ public class LayoutEngineTest { TestCSSNode node_2; node_2 = node_1.getChildAt(0); node_2.layout.position[POSITION_TOP] = 20; - node_2.layout.position[POSITION_LEFT] = 8; - node_2.layout.dimensions[DIMENSION_WIDTH] = 172; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 18; + node_2.layout.position[POSITION_LEFT] = 145; + node_2.layout.dimensions[DIMENSION_WIDTH] = TestConstants.SMALL_WIDTH; + node_2.layout.dimensions[DIMENSION_HEIGHT] = TestConstants.SMALL_HEIGHT; } } } @@ -5146,7 +5151,7 @@ public class LayoutEngineTest { node_2.setMargin(Spacing.START, 20); node_2.setMargin(Spacing.END, 20); node_2.setMeasureFunction(sTestMeasureFunction); - node_2.context = "loooooooooong with space"; + node_2.context = TestConstants.LONG_TEXT; } } } @@ -5173,7 +5178,7 @@ public class LayoutEngineTest { node_2.layout.position[POSITION_TOP] = 20; node_2.layout.position[POSITION_LEFT] = 20; node_2.layout.dimensions[DIMENSION_WIDTH] = 160; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 36; + node_2.layout.dimensions[DIMENSION_HEIGHT] = TestConstants.BIG_HEIGHT; } } } @@ -8244,7 +8249,7 @@ public class LayoutEngineTest { node_2.style.flex = 1; node_2.style.dimensions[DIMENSION_HEIGHT] = 10; node_2.setMeasureFunction(sTestMeasureFunction); - node_2.context = "measureWithMatchParent"; + node_2.context = TestConstants.MEASURE_WITH_MATCH_PARENT; } } } @@ -9529,7 +9534,7 @@ public class LayoutEngineTest { TestCSSNode node_2; node_2 = node_1.getChildAt(0); node_2.setMeasureFunction(sTestMeasureFunction); - node_2.context = "loooooooooong with space"; + node_2.context = TestConstants.LONG_TEXT; } node_1 = node_0.getChildAt(2); node_1.style.dimensions[DIMENSION_WIDTH] = 15; @@ -9555,7 +9560,7 @@ public class LayoutEngineTest { node_1 = node_0.getChildAt(1); node_1.layout.position[POSITION_TOP] = 0; node_1.layout.position[POSITION_LEFT] = 25; - node_1.layout.dimensions[DIMENSION_WIDTH] = 172; + node_1.layout.dimensions[DIMENSION_WIDTH] = TestConstants.BIG_WIDTH; node_1.layout.dimensions[DIMENSION_HEIGHT] = 100; addChildren(node_1, 1); { @@ -9563,8 +9568,8 @@ public class LayoutEngineTest { node_2 = node_1.getChildAt(0); node_2.layout.position[POSITION_TOP] = 0; node_2.layout.position[POSITION_LEFT] = 0; - node_2.layout.dimensions[DIMENSION_WIDTH] = 172; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 18; + node_2.layout.dimensions[DIMENSION_WIDTH] = TestConstants.BIG_WIDTH; + node_2.layout.dimensions[DIMENSION_HEIGHT] = TestConstants.SMALL_HEIGHT; } node_1 = node_0.getChildAt(2); node_1.layout.position[POSITION_TOP] = 0; @@ -9603,7 +9608,7 @@ public class LayoutEngineTest { node_2 = node_1.getChildAt(0); node_2.style.flex = -1; node_2.setMeasureFunction(sTestMeasureFunction); - node_2.context = "loooooooooong with space"; + node_2.context = TestConstants.LONG_TEXT; } node_1 = node_0.getChildAt(2); node_1.style.dimensions[DIMENSION_WIDTH] = 15; @@ -9638,7 +9643,7 @@ public class LayoutEngineTest { node_2.layout.position[POSITION_TOP] = 0; node_2.layout.position[POSITION_LEFT] = 0; node_2.layout.dimensions[DIMENSION_WIDTH] = 100; - node_2.layout.dimensions[DIMENSION_HEIGHT] = 36; + node_2.layout.dimensions[DIMENSION_HEIGHT] = TestConstants.BIG_HEIGHT; } node_1 = node_0.getChildAt(2); node_1.layout.position[POSITION_TOP] = 0; diff --git a/java/java/tests/com/facebook/csslayout/TestConstants.java b/tests/java/com/facebook/csslayout/TestConstants.java similarity index 79% rename from java/java/tests/com/facebook/csslayout/TestConstants.java rename to tests/java/com/facebook/csslayout/TestConstants.java index 41cce209..a4de46f5 100644 --- a/java/java/tests/com/facebook/csslayout/TestConstants.java +++ b/tests/java/com/facebook/csslayout/TestConstants.java @@ -1,27 +1,21 @@ /** - * Copyright (c) 2014, Facebook, Inc. + * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ + package com.facebook.csslayout; -/** - * Generated constants used in {@link LayoutEngineTest}. - */ public class TestConstants { - - /** START_GENERATED **/ public static final float SMALL_WIDTH = 35f; public static final float SMALL_HEIGHT = 18f; public static final float BIG_WIDTH = 172f; public static final float BIG_HEIGHT = 36f; - public static final float BIG_MIN_WIDTH = 100f; public static final String SMALL_TEXT = "small"; public static final String LONG_TEXT = "loooooooooong with space"; public static final String MEASURE_WITH_RATIO_2 = "measureWithRatio2"; public static final String MEASURE_WITH_MATCH_PARENT = "measureWithMatchParent"; - /** END_GENERATED **/ }