Import new C source of truth css-layout

fbshipit-source-id: e866918d6c62fc1cf3a04c269f782b94db9b875a
This commit is contained in:
FBShipIt 2016-07-25 06:31:32 -07:00 коммит произвёл Emil Sjolander
Родитель 93809b69c8
Коммит fdd8552c4e
118 изменённых файлов: 11099 добавлений и 34574 удалений

2
.buckconfig Normal file
Просмотреть файл

@ -0,0 +1,2 @@
[cxx]
gtest_dep = //lib/gtest:gtest

1
.buckversion Normal file
Просмотреть файл

@ -0,0 +1 @@
158950c02e1553d3a17979e74d9df020594e4d30

Просмотреть файл

@ -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
}
}

14
.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-*/

7
.hgignore Normal file
Просмотреть файл

@ -0,0 +1,7 @@
.DS_STORE
/buck-cache/
/buck-out/
/.buckconfig.local
/.buckd
/lib/gtest/googletest-*/

Просмотреть файл

@ -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

81
BUCK Normal file
Просмотреть файл

@ -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,
],
)

Просмотреть файл

7
CSSLAYOUT_DEFS Normal file
Просмотреть файл

@ -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'

Просмотреть файл

@ -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 <stdio.h>
#include <stdlib.h>
#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

Разница между файлами не показана из-за своего большого размера Загрузить разницу

210
CSSLayout/CSSLayout.h Normal file
Просмотреть файл

@ -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 <math.h>
#ifndef __cplusplus
#include <stdbool.h>
#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 <CSSLayout/CSSMacros.h>
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

Просмотреть файл

@ -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

86
CSSLayout/CSSNodeList.c Normal file
Просмотреть файл

@ -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 <assert.h>
#include <stdio.h>
#include <stdlib.h>
#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];
}

30
CSSLayout/CSSNodeList.h Normal file
Просмотреть файл

@ -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 <CSSLayout/CSSLayout.h>
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

Просмотреть файл

@ -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']);
};

Просмотреть файл

@ -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:

9
README Normal file
Просмотреть файл

@ -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.

157
README.md
Просмотреть файл

@ -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
```

Просмотреть файл

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!--This file represents the results of running a test suite-->
<test-results name="src/csharp/Facebook.CSSLayout.Tests/bin/Release/Facebook.CSSLayout.Tests.dll" total="0" failures="0" not-run="0" date="2016-07-08" time="14:42:41">
<environment nunit-version="2.4.8.0" clr-version="4.0.30319.17020" os-version="Unix 15.5.0.0" platform="Unix" cwd="/Volumes/Source/css-layout" machine-name="emilsj-pro" user="emilsj" user-domain="emilsj-pro" />
<culture-info current-culture="en-US" current-uiculture="en-US" />
<test-suite name="src/csharp/Facebook.CSSLayout.Tests/bin/Release/Facebook.CSSLayout.Tests.dll" success="True" time="0.001" asserts="0">
<results />
</test-suite>
</test-results>

20
dist/README.md поставляемый
Просмотреть файл

@ -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 [<newversion> | 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
```

Двоичные данные
dist/css-layout.jar поставляемый

Двоичный файл не отображается.

1737
dist/css-layout.js поставляемый

Разница между файлами не показана из-за своего большого размера Загрузить разницу

2
dist/css-layout.min.js поставляемый

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

1
dist/css-layout.min.js.map поставляемый

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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 <stdlib.h>
#ifdef _MSC_VER
#include <float.h>
#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;
}

Просмотреть файл

@ -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 <stdio.h>
#include <string.h>
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);

Просмотреть файл

@ -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;
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -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 <math.h>
#ifndef __cplusplus
#include <stdbool.h>
#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

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -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 {

Просмотреть файл

@ -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 {

Просмотреть файл

@ -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 {

Просмотреть файл

@ -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 {

Просмотреть файл

@ -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 {

Просмотреть файл

@ -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 {

Просмотреть файл

@ -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;

Просмотреть файл

@ -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;
/**

Просмотреть файл

@ -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 {

Просмотреть файл

@ -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;

Просмотреть файл

@ -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 {

Просмотреть файл

@ -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 {

Просмотреть файл

@ -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;

Просмотреть файл

@ -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 {

Просмотреть файл

@ -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;
/**

Просмотреть файл

@ -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 {

Просмотреть файл

@ -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 **/
}
}

Просмотреть файл

@ -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;
/**

Просмотреть файл

@ -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;

Просмотреть файл

@ -1,13 +0,0 @@
root = true
[*]
end_of_line=LF
[*.cs]
indent_style=space
indent_size=4
[*.js]
indent_style=space
indent_size=2

6
java/csharp/.gitignore поставляемый
Просмотреть файл

@ -1,6 +0,0 @@
bin/
obj/
/packages/
/.vs/
*.user
*.nupkg

Просмотреть файл

@ -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);
}
}
}

Просмотреть файл

@ -1,70 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{E687C8FD-0A0D-450F-853D-EC301BE1C038}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Facebook.CSSLayout.Tests</RootNamespace>
<AssemblyName>Facebook.CSSLayout.Tests</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="nunit.framework, Version=2.6.4.14350, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\NUnit.2.6.4\lib\nunit.framework.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="CSSNodeTest.cs" />
<Compile Include="LayoutCachingTest.cs" />
<Compile Include="LayoutEngineTest.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TestConstants.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Facebook.CSSLayout\Facebook.CSSLayout.csproj">
<Project>{d534fb4b-a7d4-4a29-96d3-f39a91a259bd}</Project>
<Name>Facebook.CSSLayout</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

Просмотреть файл

@ -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);
}
}
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -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")]

Просмотреть файл

@ -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 **/
}
}

Просмотреть файл

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="NUnit" version="2.6.4" targetFramework="net45" />
</packages>

Просмотреть файл

@ -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

Просмотреть файл

@ -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>(T v) where T : class
{
Debug.Assert(v != null);
return v;
}
public static void assertCondition(bool condition, string explanation)
{
Debug.Assert(condition, explanation);
}
}
}

Просмотреть файл

@ -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;
}
}

Просмотреть файл

@ -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);
}
}
}

Просмотреть файл

@ -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
}
}

Просмотреть файл

@ -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
}
}

Просмотреть файл

@ -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
}
}

Просмотреть файл

@ -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>(T[] array, T value)
{
for (var i = 0; i != array.Length; ++i)
array[i] = value;
}
}
}

Просмотреть файл

@ -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;
}
}

Просмотреть файл

@ -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,
}
}

Просмотреть файл

@ -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<CSSNode> mChildren = new List<CSSNode>(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<CSSNode> 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<T>([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<ValueT>(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);
}
}
}

Просмотреть файл

@ -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
}
}

Просмотреть файл

@ -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
}
}

Просмотреть файл

@ -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
}
}

Просмотреть файл

@ -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;
}
}

Просмотреть файл

@ -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
}
}

Просмотреть файл

@ -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;
}
}

Просмотреть файл

@ -1,73 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<MinimumVisualStudioVersion>10.0</MinimumVisualStudioVersion>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{D534FB4B-A7D4-4A29-96D3-F39A91A259BD}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Facebook.CSSLayout</RootNamespace>
<AssemblyName>Facebook.CSSLayout</AssemblyName>
<DefaultLanguage>en-US</DefaultLanguage>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<TargetFrameworkProfile>Profile259</TargetFrameworkProfile>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<LangVersion>5</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<!-- A reference to the entire .NET Framework is automatically included -->
</ItemGroup>
<ItemGroup>
<Compile Include="Assertions.cs" />
<Compile Include="CachedCSSLayout.cs" />
<Compile Include="CSSAlign.cs" />
<Compile Include="CSSCachedMeasurement.cs" />
<Compile Include="CSSConstants.cs" />
<Compile Include="CSSDirection.cs" />
<Compile Include="CSSFlexDirection.cs" />
<Compile Include="CSSJustify.cs" />
<Compile Include="CSSLayout.cs" />
<Compile Include="CSSLayoutContext.cs" />
<Compile Include="CSSMeasureMode.cs" />
<Compile Include="CSSNode.cs" />
<Compile Include="CSSOverflow.cs" />
<Compile Include="CSSPositionType.cs" />
<Compile Include="CSSStyle.cs" />
<Compile Include="CSSWrap.cs" />
<Compile Include="FloatUtil.cs" />
<Compile Include="LayoutEngine.cs" />
<Compile Include="MeasureOutput.cs" />
<Compile Include="NullableAttribute.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Spacing.cs" />
<Compile Include="CSSSpacingType.cs" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

Просмотреть файл

@ -1,17 +0,0 @@
<?xml version="1.0"?>
<package >
<metadata>
<id>$id$</id>
<version>$version$</version>
<title>$title$</title>
<authors>$author$</authors>
<owners>$author$</owners>
<licenseUrl>https://github.com/facebook/css-layout/blob/master/LICENSE</licenseUrl>
<projectUrl>https://github.com/facebook/css-layout</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>$description$</description>
<releaseNotes></releaseNotes>
<copyright>Copyright 2015 Facebook</copyright>
<tags>flexbox flex-box css layout css-layout facebook</tags>
</metadata>
</package>

Просмотреть файл

@ -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;
}
}
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -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; }
}
}
}

Просмотреть файл

@ -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
{
}
}

Просмотреть файл

@ -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")]

Просмотреть файл

@ -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
};
}
}
}

Просмотреть файл

@ -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"

Просмотреть файл

@ -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 */
};
}));

Просмотреть файл

@ -1 +0,0 @@
css-layout

Просмотреть файл

@ -1,23 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<option name="DEFAULT_COMPILER" value="Javac" />
<resourceExtensions />
<wildcardResourcePatterns>
<entry name="!?*.java" />
<entry name="!?*.form" />
<entry name="!?*.class" />
<entry name="!?*.groovy" />
<entry name="!?*.scala" />
<entry name="!?*.flex" />
<entry name="!?*.kt" />
<entry name="!?*.clj" />
</wildcardResourcePatterns>
<annotationProcessing>
<profile default="true" name="Default" enabled="false">
<processorPath useClasspath="true" />
</profile>
</annotationProcessing>
</component>
</project>

Просмотреть файл

@ -1,5 +0,0 @@
<component name="CopyrightManager">
<settings default="">
<module2copyright />
</settings>
</component>

Просмотреть файл

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
</project>

Просмотреть файл

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="EntryPointsManager">
<entry_points version="2.0" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="1.6" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

Просмотреть файл

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/java.iml" filepath="$PROJECT_DIR$/java.iml" />
</modules>
</component>
</project>

Просмотреть файл

@ -1,5 +0,0 @@
<component name="DependencyValidationManager">
<state>
<option name="SKIP_IMPORT_STATEMENTS" value="false" />
</state>
</component>

Просмотреть файл

@ -1,125 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>

Просмотреть файл

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="" />
</component>
</project>

Просмотреть файл

@ -1,22 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="jar://$APPLICATION_HOME_DIR$/lib/junit-4.10.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
</component>
</module>

Просмотреть файл

@ -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));

42
lib/gtest/BUCK Normal file
Просмотреть файл

@ -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],
)

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше