diff --git a/Examples/UIExplorer/UIExplorerUnitTests/RCTShadowViewTests.m b/Examples/UIExplorer/UIExplorerUnitTests/RCTShadowViewTests.m
index 7a49a86034e757..a966f9022b729d 100644
--- a/Examples/UIExplorer/UIExplorerUnitTests/RCTShadowViewTests.m
+++ b/Examples/UIExplorer/UIExplorerUnitTests/RCTShadowViewTests.m
@@ -28,8 +28,8 @@ - (void)setUp
{
[super setUp];
- self.parentView = [self _shadowViewWithStyle:^(css_style_t *style) {
- style->flex_direction = CSS_FLEX_DIRECTION_COLUMN;
+ self.parentView = [self _shadowViewWithStyle:^(CSSStyle *style) {
+ style->flexDirection = CSSFlexDirectionColumn;
style->dimensions[0] = 440;
style->dimensions[1] = 440;
}];
@@ -50,22 +50,22 @@ - (void)setUp
//
- (void)testApplyingLayoutRecursivelyToShadowView
{
- RCTShadowView *leftView = [self _shadowViewWithStyle:^(css_style_t *style) {
+ RCTShadowView *leftView = [self _shadowViewWithStyle:^(CSSStyle *style) {
style->flex = 1;
}];
- RCTShadowView *centerView = [self _shadowViewWithStyle:^(css_style_t *style) {
+ RCTShadowView *centerView = [self _shadowViewWithStyle:^(CSSStyle *style) {
style->flex = 2;
style->margin[0] = 10;
style->margin[2] = 10;
}];
- RCTShadowView *rightView = [self _shadowViewWithStyle:^(css_style_t *style) {
+ RCTShadowView *rightView = [self _shadowViewWithStyle:^(CSSStyle *style) {
style->flex = 1;
}];
- RCTShadowView *mainView = [self _shadowViewWithStyle:^(css_style_t *style) {
- style->flex_direction = CSS_FLEX_DIRECTION_ROW;
+ RCTShadowView *mainView = [self _shadowViewWithStyle:^(CSSStyle *style) {
+ style->flexDirection = CSSFlexDirectionRow;
style->flex = 2;
style->margin[1] = 10;
style->margin[3] = 10;
@@ -75,11 +75,11 @@ - (void)testApplyingLayoutRecursivelyToShadowView
[mainView insertReactSubview:centerView atIndex:1];
[mainView insertReactSubview:rightView atIndex:2];
- RCTShadowView *headerView = [self _shadowViewWithStyle:^(css_style_t *style) {
+ RCTShadowView *headerView = [self _shadowViewWithStyle:^(CSSStyle *style) {
style->flex = 1;
}];
- RCTShadowView *footerView = [self _shadowViewWithStyle:^(css_style_t *style) {
+ RCTShadowView *footerView = [self _shadowViewWithStyle:^(CSSStyle *style) {
style->flex = 1;
}];
@@ -108,10 +108,10 @@ - (void)testApplyingLayoutRecursivelyToShadowView
- (void)testAssignsSuggestedWidthDimension
{
- [self _withShadowViewWithStyle:^(css_style_t *style) {
- style->position[CSS_LEFT] = 0;
- style->position[CSS_TOP] = 0;
- style->dimensions[CSS_HEIGHT] = 10;
+ [self _withShadowViewWithStyle:^(CSSStyle *style) {
+ style->position[CSSPositionLeft] = 0;
+ style->position[CSSPositionTop] = 0;
+ style->dimensions[CSSDimensionHeight] = 10;
}
assertRelativeLayout:CGRectMake(0, 0, 3, 10)
withIntrinsicContentSize:CGSizeMake(3, UIViewNoIntrinsicMetric)];
@@ -119,10 +119,10 @@ - (void)testAssignsSuggestedWidthDimension
- (void)testAssignsSuggestedHeightDimension
{
- [self _withShadowViewWithStyle:^(css_style_t *style) {
- style->position[CSS_LEFT] = 0;
- style->position[CSS_TOP] = 0;
- style->dimensions[CSS_WIDTH] = 10;
+ [self _withShadowViewWithStyle:^(CSSStyle *style) {
+ style->position[CSSPositionLeft] = 0;
+ style->position[CSSPositionTop] = 0;
+ style->dimensions[CSSDimensionWidth] = 10;
}
assertRelativeLayout:CGRectMake(0, 0, 10, 4)
withIntrinsicContentSize:CGSizeMake(UIViewNoIntrinsicMetric, 4)];
@@ -130,11 +130,11 @@ - (void)testAssignsSuggestedHeightDimension
- (void)testDoesNotOverrideDimensionStyleWithSuggestedDimensions
{
- [self _withShadowViewWithStyle:^(css_style_t *style) {
- style->position[CSS_LEFT] = 0;
- style->position[CSS_TOP] = 0;
- style->dimensions[CSS_WIDTH] = 10;
- style->dimensions[CSS_HEIGHT] = 10;
+ [self _withShadowViewWithStyle:^(CSSStyle *style) {
+ style->position[CSSPositionLeft] = 0;
+ style->position[CSSPositionTop] = 0;
+ style->dimensions[CSSDimensionWidth] = 10;
+ style->dimensions[CSSDimensionHeight] = 10;
}
assertRelativeLayout:CGRectMake(0, 0, 10, 10)
withIntrinsicContentSize:CGSizeMake(3, 4)];
@@ -142,16 +142,16 @@ - (void)testDoesNotOverrideDimensionStyleWithSuggestedDimensions
- (void)testDoesNotAssignSuggestedDimensionsWhenStyledWithFlexAttribute
{
- float parentWidth = self.parentView.cssNode->style.dimensions[CSS_WIDTH];
- float parentHeight = self.parentView.cssNode->style.dimensions[CSS_HEIGHT];
- [self _withShadowViewWithStyle:^(css_style_t *style) {
+ float parentWidth = self.parentView.cssNode->style.dimensions[CSSDimensionWidth];
+ float parentHeight = self.parentView.cssNode->style.dimensions[CSSDimensionHeight];
+ [self _withShadowViewWithStyle:^(CSSStyle *style) {
style->flex = 1;
}
assertRelativeLayout:CGRectMake(0, 0, parentWidth, parentHeight)
withIntrinsicContentSize:CGSizeMake(3, 4)];
}
-- (void)_withShadowViewWithStyle:(void(^)(css_style_t *style))styleBlock
+- (void)_withShadowViewWithStyle:(void(^)(CSSStyle *style))styleBlock
assertRelativeLayout:(CGRect)expectedRect
withIntrinsicContentSize:(CGSize)contentSize
{
@@ -166,11 +166,11 @@ - (void)_withShadowViewWithStyle:(void(^)(css_style_t *style))styleBlock
NSStringFromCGRect(actualRect));
}
-- (RCTRootShadowView *)_shadowViewWithStyle:(void(^)(css_style_t *style))styleBlock
+- (RCTRootShadowView *)_shadowViewWithStyle:(void(^)(CSSStyle *style))styleBlock
{
RCTRootShadowView *shadowView = [RCTRootShadowView new];
- css_style_t style = shadowView.cssNode->style;
+ CSSStyle style = shadowView.cssNode->style;
styleBlock(&style);
shadowView.cssNode->style = style;
diff --git a/Examples/UIExplorer/js/ToastAndroidExample.android.js b/Examples/UIExplorer/js/ToastAndroidExample.android.js
index 53cd3a95a85d29..86866b1c346d68 100644
--- a/Examples/UIExplorer/js/ToastAndroidExample.android.js
+++ b/Examples/UIExplorer/js/ToastAndroidExample.android.js
@@ -60,7 +60,43 @@ var ToastExample = React.createClass({
ToastAndroid.show('This is a toast with long duration', ToastAndroid.LONG)}>
- Click me too.
+ Click me.
+
+
+
+
+ ToastAndroid.showWithGravity(
+ 'This is a toast with top gravity',
+ ToastAndroid.SHORT,
+ ToastAndroid.TOP,
+ )
+ }>
+ Click me.
+
+
+
+
+ ToastAndroid.showWithGravity(
+ 'This is a toast with center gravity',
+ ToastAndroid.SHORT,
+ ToastAndroid.CENTER,
+ )
+ }>
+ Click me.
+
+
+
+
+ ToastAndroid.showWithGravity(
+ 'This is a toast with bottom gravity',
+ ToastAndroid.SHORT,
+ ToastAndroid.BOTTOM,
+ )
+ }>
+ Click me.
diff --git a/Libraries/BatchedBridge/BatchedBridgedModules/NativeModules.js b/Libraries/BatchedBridge/BatchedBridgedModules/NativeModules.js
index dfbd9edd1a3554..f1a4da1d4c2412 100644
--- a/Libraries/BatchedBridge/BatchedBridgedModules/NativeModules.js
+++ b/Libraries/BatchedBridge/BatchedBridgedModules/NativeModules.js
@@ -46,8 +46,11 @@ Object.keys(RemoteModules).forEach((moduleName) => {
get: () => {
let module = RemoteModules[moduleName];
if (module && typeof module.moduleID === 'number' && global.nativeRequireModuleConfig) {
- const json = global.nativeRequireModuleConfig(moduleName);
- const config = json && JSON.parse(json);
+ // The old bridge (still used by iOS) will send the config as
+ // a JSON string that needs parsing, so we set config according
+ // to the type of response we got.
+ const rawConfig = global.nativeRequireModuleConfig(moduleName);
+ const config = typeof rawConfig === 'string' ? JSON.parse(rawConfig) : rawConfig;
module = config && BatchedBridge.processModuleConfig(config, module.moduleID);
RemoteModules[moduleName] = module;
}
diff --git a/Libraries/Components/ToastAndroid/ToastAndroid.android.js b/Libraries/Components/ToastAndroid/ToastAndroid.android.js
index 1006b929387ced..ac03e62d4805e8 100644
--- a/Libraries/Components/ToastAndroid/ToastAndroid.android.js
+++ b/Libraries/Components/ToastAndroid/ToastAndroid.android.js
@@ -19,13 +19,22 @@ var RCTToastAndroid = require('NativeModules').ToastAndroid;
*
* 1. String message: A string with the text to toast
* 2. int duration: The duration of the toast. May be ToastAndroid.SHORT or ToastAndroid.LONG
+ *
+ * There is also a function `showWithGravity` to specify the layout gravity. May be
+ * ToastAndroid.TOP, ToastAndroid.BOTTOM, ToastAndroid.CENTER
*/
var ToastAndroid = {
+ // Toast duration constants
SHORT: RCTToastAndroid.SHORT,
LONG: RCTToastAndroid.LONG,
+ // Toast gravity constants
+ TOP: RCTToastAndroid.TOP,
+ BOTTOM: RCTToastAndroid.BOTTOM,
+ CENTER: RCTToastAndroid.CENTER,
+
show: function (
message: string,
duration: number
@@ -33,6 +42,13 @@ var ToastAndroid = {
RCTToastAndroid.show(message, duration);
},
+ showWithGravity: function (
+ message: string,
+ duration: number,
+ gravity: number,
+ ): void {
+ RCTToastAndroid.showWithGravity(message, duration, gravity);
+ },
};
module.exports = ToastAndroid;
diff --git a/Libraries/QuickPerformanceLogger/QuickPerformanceLogger.js b/Libraries/QuickPerformanceLogger/QuickPerformanceLogger.js
index fa6b257dd3e64d..42f75f688bd231 100644
--- a/Libraries/QuickPerformanceLogger/QuickPerformanceLogger.js
+++ b/Libraries/QuickPerformanceLogger/QuickPerformanceLogger.js
@@ -21,12 +21,6 @@ var fixOpts = function(opts) {
};
var QuickPerformanceLogger = {
-
- // These two empty containers will cause all calls to ActionId.SOMETHING or MarkerId.OTHER
- // to equal 'undefined', unless they are given a concrete value elsewhere.
- ActionId: {},
- MarkerId: {},
-
markerStart(markerId, opts) {
if (typeof markerId !== 'number') {
return;
diff --git a/Libraries/Text/RCTShadowText.m b/Libraries/Text/RCTShadowText.m
index 32e73997facaa7..bbff4ac1b6ed23 100644
--- a/Libraries/Text/RCTShadowText.m
+++ b/Libraries/Text/RCTShadowText.m
@@ -33,7 +33,7 @@ @implementation RCTShadowText
CGFloat _effectiveLetterSpacing;
}
-static css_dim_t RCTMeasure(void *context, float width, css_measure_mode_t widthMode, float height, css_measure_mode_t heightMode)
+static CSSMeasureResult RCTMeasure(void *context, float width, CSSMeasureMode widthMode, float height, CSSMeasureMode heightMode)
{
RCTShadowText *shadowText = (__bridge RCTShadowText *)context;
NSTextStorage *textStorage = [shadowText buildTextStorageForWidth:width widthMode:widthMode];
@@ -41,12 +41,12 @@ static css_dim_t RCTMeasure(void *context, float width, css_measure_mode_t width
NSTextContainer *textContainer = layoutManager.textContainers.firstObject;
CGSize computedSize = [layoutManager usedRectForTextContainer:textContainer].size;
- css_dim_t result;
- result.dimensions[CSS_WIDTH] = RCTCeilPixelValue(computedSize.width);
+ CSSMeasureResult result;
+ result.dimensions[CSSDimensionWidth] = RCTCeilPixelValue(computedSize.width);
if (shadowText->_effectiveLetterSpacing < 0) {
- result.dimensions[CSS_WIDTH] -= shadowText->_effectiveLetterSpacing;
+ result.dimensions[CSSDimensionWidth] -= shadowText->_effectiveLetterSpacing;
}
- result.dimensions[CSS_HEIGHT] = RCTCeilPixelValue(computedSize.height);
+ result.dimensions[CSSDimensionHeight] = RCTCeilPixelValue(computedSize.height);
return result;
}
@@ -61,6 +61,7 @@ - (instancetype)init
_cachedTextStorageWidth = -1;
_cachedTextStorageWidthMode = -1;
_fontSizeMultiplier = 1.0;
+ self.cssNode->measure = RCTMeasure;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(contentSizeMultiplierDidChange:)
name:RCTUIManagerWillUpdateViewsDueToContentSizeMultiplierChangeNotification
@@ -80,6 +81,11 @@ - (NSString *)description
return [[superDescription substringToIndex:superDescription.length - 1] stringByAppendingFormat:@"; text: %@>", [self attributedString].string];
}
+- (BOOL)isCSSLeafNode
+{
+ return YES;
+}
+
- (void)contentSizeMultiplierDidChange:(NSNotification *)note
{
[self dirtyLayout];
@@ -100,7 +106,7 @@ - (void)contentSizeMultiplierDidChange:(NSNotification *)note
CGFloat width = self.frame.size.width - (padding.left + padding.right);
NSNumber *parentTag = [[self reactSuperview] reactTag];
- NSTextStorage *textStorage = [self buildTextStorageForWidth:width widthMode:CSS_MEASURE_MODE_EXACTLY];
+ NSTextStorage *textStorage = [self buildTextStorageForWidth:width widthMode:CSSMeasureModeExactly];
[applierBlocks addObject:^(NSDictionary *viewRegistry) {
RCTText *view = (RCTText *)viewRegistry[self.reactTag];
view.textStorage = textStorage;
@@ -122,7 +128,7 @@ - (void)contentSizeMultiplierDidChange:(NSNotification *)note
return parentProperties;
}
-- (void)applyLayoutNode:(css_node_t *)node
+- (void)applyLayoutNode:(CSSNode *)node
viewsWithNewFrame:(NSMutableSet *)viewsWithNewFrame
absolutePosition:(CGPoint)absolutePosition
{
@@ -130,21 +136,21 @@ - (void)applyLayoutNode:(css_node_t *)node
[self dirtyPropagation];
}
-- (void)applyLayoutToChildren:(css_node_t *)node
+- (void)applyLayoutToChildren:(CSSNode *)node
viewsWithNewFrame:(NSMutableSet *)viewsWithNewFrame
absolutePosition:(CGPoint)absolutePosition
{
// Run layout on subviews.
- NSTextStorage *textStorage = [self buildTextStorageForWidth:self.frame.size.width widthMode:CSS_MEASURE_MODE_EXACTLY];
+ NSTextStorage *textStorage = [self buildTextStorageForWidth:self.frame.size.width widthMode:CSSMeasureModeExactly];
NSLayoutManager *layoutManager = textStorage.layoutManagers.firstObject;
NSTextContainer *textContainer = layoutManager.textContainers.firstObject;
NSRange glyphRange = [layoutManager glyphRangeForTextContainer:textContainer];
NSRange characterRange = [layoutManager characterRangeForGlyphRange:glyphRange actualGlyphRange:NULL];
[layoutManager.textStorage enumerateAttribute:RCTShadowViewAttributeName inRange:characterRange options:0 usingBlock:^(RCTShadowView *child, NSRange range, BOOL *_) {
if (child) {
- css_node_t *childNode = child.cssNode;
- float width = childNode->style.dimensions[CSS_WIDTH];
- float height = childNode->style.dimensions[CSS_HEIGHT];
+ CSSNode *childNode = child.cssNode;
+ float width = childNode->style.dimensions[CSSDimensionWidth];
+ float height = childNode->style.dimensions[CSSDimensionHeight];
if (isUndefined(width) || isUndefined(height)) {
RCTLogError(@"Views nested within a must have a width and height");
}
@@ -169,7 +175,7 @@ - (void)applyLayoutToChildren:(css_node_t *)node
}];
}
-- (NSTextStorage *)buildTextStorageForWidth:(CGFloat)width widthMode:(css_measure_mode_t)widthMode
+- (NSTextStorage *)buildTextStorageForWidth:(CGFloat)width widthMode:(CSSMeasureMode)widthMode
{
if (_cachedTextStorage && width == _cachedTextStorageWidth && widthMode == _cachedTextStorageWidthMode) {
return _cachedTextStorage;
@@ -190,7 +196,7 @@ - (NSTextStorage *)buildTextStorageForWidth:(CGFloat)width widthMode:(css_measur
}
textContainer.maximumNumberOfLines = _numberOfLines;
- textContainer.size = (CGSize){widthMode == CSS_MEASURE_MODE_UNDEFINED ? CGFLOAT_MAX : width, CGFLOAT_MAX};
+ textContainer.size = (CGSize){widthMode == CSSMeasureModeUndefined ? CGFLOAT_MAX : width, CGFLOAT_MAX};
[layoutManager addTextContainer:textContainer];
[layoutManager ensureLayoutForTextContainer:textContainer];
@@ -285,8 +291,8 @@ - (NSAttributedString *)_attributedStringWithFontFamily:(NSString *)fontFamily
[attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:shadowRawText.text ?: @""]];
[child setTextComputed];
} else {
- float width = child.cssNode->style.dimensions[CSS_WIDTH];
- float height = child.cssNode->style.dimensions[CSS_HEIGHT];
+ float width = child.cssNode->style.dimensions[CSSDimensionWidth];
+ float height = child.cssNode->style.dimensions[CSSDimensionHeight];
if (isUndefined(width) || isUndefined(height)) {
RCTLogError(@"Views nested within a must have a width and height");
}
@@ -378,10 +384,10 @@ - (void)_setParagraphStyleOnAttributedString:(NSMutableAttributedString *)attrib
// We will climb up to the first node which style has been setted as non-inherit
if (newTextAlign == NSTextAlignmentRight || newTextAlign == NSTextAlignmentLeft) {
RCTShadowView *view = self;
- while (view != nil && view.cssNode->style.direction == CSS_DIRECTION_INHERIT) {
+ while (view != nil && view.cssNode->style.direction == CSSDirectionInherit) {
view = [view reactSuperview];
}
- if (view != nil && view.cssNode->style.direction == CSS_DIRECTION_RTL) {
+ if (view != nil && view.cssNode->style.direction == CSSDirectionRTL) {
if (newTextAlign == NSTextAlignmentRight) {
newTextAlign = NSTextAlignmentLeft;
} else if (newTextAlign == NSTextAlignmentLeft) {
@@ -442,25 +448,6 @@ - (void)_setParagraphStyleOnAttributedString:(NSMutableAttributedString *)attrib
}
}
-- (void)fillCSSNode:(css_node_t *)node
-{
- [super fillCSSNode:node];
- node->measure = RCTMeasure;
- node->children_count = 0;
-}
-
-- (void)insertReactSubview:(RCTShadowView *)subview atIndex:(NSInteger)atIndex
-{
- [super insertReactSubview:subview atIndex:atIndex];
- self.cssNode->children_count = 0;
-}
-
-- (void)removeReactSubview:(RCTShadowView *)subview
-{
- [super removeReactSubview:subview];
- self.cssNode->children_count = 0;
-}
-
- (void)setBackgroundColor:(UIColor *)backgroundColor
{
super.backgroundColor = backgroundColor;
diff --git a/Libraries/Text/RCTTextManager.m b/Libraries/Text/RCTTextManager.m
index 676ff9bb2063b8..c8fe246ddbc69b 100644
--- a/Libraries/Text/RCTTextManager.m
+++ b/Libraries/Text/RCTTextManager.m
@@ -34,7 +34,7 @@ static void collectDirtyNonTextDescendants(RCTShadowText *shadowView, NSMutableA
@interface RCTShadowText (Private)
-- (NSTextStorage *)buildTextStorageForWidth:(CGFloat)width widthMode:(css_measure_mode_t)widthMode;
+- (NSTextStorage *)buildTextStorageForWidth:(CGFloat)width widthMode:(CSSMeasureMode)widthMode;
@end
diff --git a/React/Base/RCTConvert.h b/React/Base/RCTConvert.h
index 086e5dfca6623f..8aeda7e28064a3 100644
--- a/React/Base/RCTConvert.h
+++ b/React/Base/RCTConvert.h
@@ -116,11 +116,11 @@ typedef id NSPropertyList;
typedef BOOL css_clip_t, css_backface_visibility_t;
+ (css_clip_t)css_clip_t:(id)json;
+ (css_backface_visibility_t)css_backface_visibility_t:(id)json;
-+ (css_flex_direction_t)css_flex_direction_t:(id)json;
-+ (css_justify_t)css_justify_t:(id)json;
-+ (css_align_t)css_align_t:(id)json;
-+ (css_position_type_t)css_position_type_t:(id)json;
-+ (css_wrap_type_t)css_wrap_type_t:(id)json;
++ (CSSFlexDirection)CSSFlexDirection:(id)json;
++ (CSSJustify)CSSJustify:(id)json;
++ (CSSAlign)CSSAlign:(id)json;
++ (CSSPositionType)CSSPositionType:(id)json;
++ (CSSWrapType)CSSWrapType:(id)json;
+ (RCTPointerEvents)RCTPointerEvents:(id)json;
+ (RCTAnimationType)RCTAnimationType:(id)json;
diff --git a/React/Base/RCTConvert.m b/React/Base/RCTConvert.m
index e37766cee88a27..24683744cd39f9 100644
--- a/React/Base/RCTConvert.m
+++ b/React/Base/RCTConvert.m
@@ -822,38 +822,38 @@ + (NSPropertyList)NSPropertyList:(id)json
@"visible": @NO
}), NO, boolValue)
-RCT_ENUM_CONVERTER(css_flex_direction_t, (@{
- @"row": @(CSS_FLEX_DIRECTION_ROW),
- @"row-reverse": @(CSS_FLEX_DIRECTION_ROW_REVERSE),
- @"column": @(CSS_FLEX_DIRECTION_COLUMN),
- @"column-reverse": @(CSS_FLEX_DIRECTION_COLUMN_REVERSE)
-}), CSS_FLEX_DIRECTION_COLUMN, intValue)
-
-RCT_ENUM_CONVERTER(css_justify_t, (@{
- @"flex-start": @(CSS_JUSTIFY_FLEX_START),
- @"flex-end": @(CSS_JUSTIFY_FLEX_END),
- @"center": @(CSS_JUSTIFY_CENTER),
- @"space-between": @(CSS_JUSTIFY_SPACE_BETWEEN),
- @"space-around": @(CSS_JUSTIFY_SPACE_AROUND)
-}), CSS_JUSTIFY_FLEX_START, intValue)
-
-RCT_ENUM_CONVERTER(css_align_t, (@{
- @"flex-start": @(CSS_ALIGN_FLEX_START),
- @"flex-end": @(CSS_ALIGN_FLEX_END),
- @"center": @(CSS_ALIGN_CENTER),
- @"auto": @(CSS_ALIGN_AUTO),
- @"stretch": @(CSS_ALIGN_STRETCH)
-}), CSS_ALIGN_FLEX_START, intValue)
-
-RCT_ENUM_CONVERTER(css_position_type_t, (@{
- @"absolute": @(CSS_POSITION_ABSOLUTE),
- @"relative": @(CSS_POSITION_RELATIVE)
-}), CSS_POSITION_RELATIVE, intValue)
-
-RCT_ENUM_CONVERTER(css_wrap_type_t, (@{
- @"wrap": @(CSS_WRAP),
- @"nowrap": @(CSS_NOWRAP)
-}), CSS_NOWRAP, intValue)
+RCT_ENUM_CONVERTER(CSSFlexDirection, (@{
+ @"row": @(CSSFlexDirectionRow),
+ @"row-reverse": @(CSSFlexDirectionRowReverse),
+ @"column": @(CSSFlexDirectionColumn),
+ @"column-reverse": @(CSSFlexDirectionColumnReverse)
+}), CSSFlexDirectionColumn, intValue)
+
+RCT_ENUM_CONVERTER(CSSJustify, (@{
+ @"flex-start": @(CSSJustifyFlexStart),
+ @"flex-end": @(CSSJustifyFlexEnd),
+ @"center": @(CSSJustifyCenter),
+ @"space-between": @(CSSJustifySpaceBetween),
+ @"space-around": @(CSSJustifySpaceAround)
+}), CSSJustifyFlexStart, intValue)
+
+RCT_ENUM_CONVERTER(CSSAlign, (@{
+ @"flex-start": @(CSSAlignFlexStart),
+ @"flex-end": @(CSSAlignFlexEnd),
+ @"center": @(CSSAlignCenter),
+ @"auto": @(CSSAlignAuto),
+ @"stretch": @(CSSAlignStretch)
+}), CSSAlignFlexStart, intValue)
+
+RCT_ENUM_CONVERTER(CSSPositionType, (@{
+ @"absolute": @(CSSPositionTypeAbsolute),
+ @"relative": @(CSSPositionTypeRelative)
+}), CSSPositionTypeRelative, intValue)
+
+RCT_ENUM_CONVERTER(CSSWrapType, (@{
+ @"wrap": @(CSSWrapTypeWrap),
+ @"nowrap": @(CSSWrapTypeNoWrap)
+}), CSSWrapTypeNoWrap, intValue)
RCT_ENUM_CONVERTER(RCTPointerEvents, (@{
@"none": @(RCTPointerEventsNone),
diff --git a/React/CSSLayout/CSSLayout.c b/React/CSSLayout/CSSLayout.c
index ae44f8897149dd..6db70b40e8da77 100644
--- a/React/CSSLayout/CSSLayout.c
+++ b/React/CSSLayout/CSSLayout.c
@@ -31,8 +31,8 @@ __forceinline const float fmaxf(const float a, const float b) {
int gCurrentGenerationCount = 0;
-bool layoutNodeInternal(css_node_t* node, float availableWidth, float availableHeight, css_direction_t parentDirection,
- css_measure_mode_t widthMeasureMode, css_measure_mode_t heightMeasureMode, bool performLayout, char* reason);
+bool layoutNodeInternal(CSSNode* node, float availableWidth, float availableHeight, CSSDirection parentDirection,
+ CSSMeasureMode widthMeasureMode, CSSMeasureMode heightMeasureMode, bool performLayout, char* reason);
bool isUndefined(float value) {
return isnan(value);
@@ -45,58 +45,58 @@ static bool eq(float a, float b) {
return fabs(a - b) < 0.0001;
}
-void init_css_node(css_node_t* node) {
- node->style.align_items = CSS_ALIGN_STRETCH;
- node->style.align_content = CSS_ALIGN_FLEX_START;
+void CSSNodeInit(CSSNode* node) {
+ node->style.alignItems = CSSAlignStretch;
+ node->style.alignContent = CSSAlignFlexStart;
- node->style.direction = CSS_DIRECTION_INHERIT;
- node->style.flex_direction = CSS_FLEX_DIRECTION_COLUMN;
+ node->style.direction = CSSDirectionInherit;
+ node->style.flexDirection = CSSFlexDirectionColumn;
- node->style.overflow = CSS_OVERFLOW_VISIBLE;
+ node->style.overflow = CSSOverflowVisible;
// Some of the fields default to undefined and not 0
- node->style.dimensions[CSS_WIDTH] = CSS_UNDEFINED;
- node->style.dimensions[CSS_HEIGHT] = CSS_UNDEFINED;
+ node->style.dimensions[CSSDimensionWidth] = CSSUndefined;
+ node->style.dimensions[CSSDimensionHeight] = CSSUndefined;
- node->style.minDimensions[CSS_WIDTH] = CSS_UNDEFINED;
- node->style.minDimensions[CSS_HEIGHT] = CSS_UNDEFINED;
+ node->style.minDimensions[CSSDimensionWidth] = CSSUndefined;
+ node->style.minDimensions[CSSDimensionHeight] = CSSUndefined;
- node->style.maxDimensions[CSS_WIDTH] = CSS_UNDEFINED;
- node->style.maxDimensions[CSS_HEIGHT] = CSS_UNDEFINED;
+ node->style.maxDimensions[CSSDimensionWidth] = CSSUndefined;
+ node->style.maxDimensions[CSSDimensionHeight] = CSSUndefined;
- node->style.position[CSS_LEFT] = CSS_UNDEFINED;
- node->style.position[CSS_TOP] = CSS_UNDEFINED;
- node->style.position[CSS_RIGHT] = CSS_UNDEFINED;
- node->style.position[CSS_BOTTOM] = CSS_UNDEFINED;
+ node->style.position[CSSPositionLeft] = CSSUndefined;
+ node->style.position[CSSPositionTop] = CSSUndefined;
+ node->style.position[CSSPositionRight] = CSSUndefined;
+ node->style.position[CSSPositionBottom] = CSSUndefined;
- node->style.margin[CSS_START] = CSS_UNDEFINED;
- node->style.margin[CSS_END] = CSS_UNDEFINED;
- node->style.padding[CSS_START] = CSS_UNDEFINED;
- node->style.padding[CSS_END] = CSS_UNDEFINED;
- node->style.border[CSS_START] = CSS_UNDEFINED;
- node->style.border[CSS_END] = CSS_UNDEFINED;
+ node->style.margin[CSSPositionStart] = CSSUndefined;
+ node->style.margin[CSSPositionEnd] = CSSUndefined;
+ node->style.padding[CSSPositionStart] = CSSUndefined;
+ node->style.padding[CSSPositionEnd] = CSSUndefined;
+ node->style.border[CSSPositionStart] = CSSUndefined;
+ node->style.border[CSSPositionEnd] = CSSUndefined;
- node->layout.dimensions[CSS_WIDTH] = CSS_UNDEFINED;
- node->layout.dimensions[CSS_HEIGHT] = CSS_UNDEFINED;
+ node->layout.dimensions[CSSDimensionWidth] = CSSUndefined;
+ node->layout.dimensions[CSSDimensionHeight] = CSSUndefined;
// Such that the comparison is always going to be false
- node->layout.last_parent_direction = (css_direction_t)-1;
- node->layout.should_update = true;
- node->layout.next_cached_measurements_index = 0;
-
- node->layout.measured_dimensions[CSS_WIDTH] = CSS_UNDEFINED;
- node->layout.measured_dimensions[CSS_HEIGHT] = CSS_UNDEFINED;
- node->layout.cached_layout.width_measure_mode = (css_measure_mode_t)-1;
- node->layout.cached_layout.height_measure_mode = (css_measure_mode_t)-1;
+ node->layout.lastParentDirection = (CSSDirection)-1;
+ node->layout.shouldUpdate = true;
+ node->layout.nextCachedMeasurementsIndex = 0;
+
+ node->layout.measuredDimensions[CSSDimensionWidth] = CSSUndefined;
+ node->layout.measuredDimensions[CSSDimensionHeight] = CSSUndefined;
+ node->layout.cached_layout.widthMeasureMode = (CSSMeasureMode)-1;
+ node->layout.cached_layout.heightMeasureMode = (CSSMeasureMode)-1;
}
-css_node_t* new_css_node() {
- css_node_t* node = (css_node_t*)calloc(1, sizeof(*node));
- init_css_node(node);
+CSSNode* CSSNodeNew() {
+ CSSNode* node = (CSSNode*)calloc(1, sizeof(*node));
+ CSSNodeInit(node);
return node;
}
-void free_css_node(css_node_t* node) {
+void CSSNodeFree(CSSNode* node) {
free(node);
}
@@ -127,8 +127,8 @@ static bool four_equal(float four[4]) {
static void print_css_node_rec(
- css_node_t* node,
- css_print_options_t options,
+ CSSNode* node,
+ CSSPrintOptions options,
int level
) {
indent(level);
@@ -138,124 +138,124 @@ static void print_css_node_rec(
node->print(node->context);
}
- if (options & CSS_PRINT_LAYOUT) {
+ if (options & CSSPrintOptionsLayout) {
printf("layout: {");
- printf("width: %g, ", node->layout.dimensions[CSS_WIDTH]);
- printf("height: %g, ", node->layout.dimensions[CSS_HEIGHT]);
- printf("top: %g, ", node->layout.position[CSS_TOP]);
- printf("left: %g", node->layout.position[CSS_LEFT]);
+ printf("width: %g, ", node->layout.dimensions[CSSDimensionWidth]);
+ printf("height: %g, ", node->layout.dimensions[CSSDimensionHeight]);
+ printf("top: %g, ", node->layout.position[CSSPositionTop]);
+ printf("left: %g", node->layout.position[CSSPositionLeft]);
printf("}, ");
}
- if (options & CSS_PRINT_STYLE) {
- if (node->style.flex_direction == CSS_FLEX_DIRECTION_COLUMN) {
+ if (options & CSSPrintOptionsStyle) {
+ if (node->style.flexDirection == CSSFlexDirectionColumn) {
printf("flexDirection: 'column', ");
- } else if (node->style.flex_direction == CSS_FLEX_DIRECTION_COLUMN_REVERSE) {
+ } else if (node->style.flexDirection == CSSFlexDirectionColumnReverse) {
printf("flexDirection: 'column-reverse', ");
- } else if (node->style.flex_direction == CSS_FLEX_DIRECTION_ROW) {
+ } else if (node->style.flexDirection == CSSFlexDirectionRow) {
printf("flexDirection: 'row', ");
- } else if (node->style.flex_direction == CSS_FLEX_DIRECTION_ROW_REVERSE) {
+ } else if (node->style.flexDirection == CSSFlexDirectionRowReverse) {
printf("flexDirection: 'row-reverse', ");
}
- if (node->style.justify_content == CSS_JUSTIFY_CENTER) {
+ if (node->style.justifyContent == CSSJustifyCenter) {
printf("justifyContent: 'center', ");
- } else if (node->style.justify_content == CSS_JUSTIFY_FLEX_END) {
+ } else if (node->style.justifyContent == CSSJustifyFlexEnd) {
printf("justifyContent: 'flex-end', ");
- } else if (node->style.justify_content == CSS_JUSTIFY_SPACE_AROUND) {
+ } else if (node->style.justifyContent == CSSJustifySpaceAround) {
printf("justifyContent: 'space-around', ");
- } else if (node->style.justify_content == CSS_JUSTIFY_SPACE_BETWEEN) {
+ } else if (node->style.justifyContent == CSSJustifySpaceBetween) {
printf("justifyContent: 'space-between', ");
}
- if (node->style.align_items == CSS_ALIGN_CENTER) {
+ if (node->style.alignItems == CSSAlignCenter) {
printf("alignItems: 'center', ");
- } else if (node->style.align_items == CSS_ALIGN_FLEX_END) {
+ } else if (node->style.alignItems == CSSAlignFlexEnd) {
printf("alignItems: 'flex-end', ");
- } else if (node->style.align_items == CSS_ALIGN_STRETCH) {
+ } else if (node->style.alignItems == CSSAlignStretch) {
printf("alignItems: 'stretch', ");
}
- if (node->style.align_content == CSS_ALIGN_CENTER) {
+ if (node->style.alignContent == CSSAlignCenter) {
printf("alignContent: 'center', ");
- } else if (node->style.align_content == CSS_ALIGN_FLEX_END) {
+ } else if (node->style.alignContent == CSSAlignFlexEnd) {
printf("alignContent: 'flex-end', ");
- } else if (node->style.align_content == CSS_ALIGN_STRETCH) {
+ } else if (node->style.alignContent == CSSAlignStretch) {
printf("alignContent: 'stretch', ");
}
- if (node->style.align_self == CSS_ALIGN_FLEX_START) {
+ if (node->style.alignSelf == CSSAlignFlexStart) {
printf("alignSelf: 'flex-start', ");
- } else if (node->style.align_self == CSS_ALIGN_CENTER) {
+ } else if (node->style.alignSelf == CSSAlignCenter) {
printf("alignSelf: 'center', ");
- } else if (node->style.align_self == CSS_ALIGN_FLEX_END) {
+ } else if (node->style.alignSelf == CSSAlignFlexEnd) {
printf("alignSelf: 'flex-end', ");
- } else if (node->style.align_self == CSS_ALIGN_STRETCH) {
+ } else if (node->style.alignSelf == CSSAlignStretch) {
printf("alignSelf: 'stretch', ");
}
print_number_nan("flex", node->style.flex);
- if (node->style.overflow == CSS_OVERFLOW_HIDDEN) {
+ if (node->style.overflow == CSSOverflowHidden) {
printf("overflow: 'hidden', ");
- } else if (node->style.overflow == CSS_OVERFLOW_VISIBLE) {
+ } else if (node->style.overflow == CSSOverflowVisible) {
printf("overflow: 'visible', ");
}
if (four_equal(node->style.margin)) {
- print_number_0("margin", node->style.margin[CSS_LEFT]);
+ print_number_0("margin", node->style.margin[CSSPositionLeft]);
} else {
- print_number_0("marginLeft", node->style.margin[CSS_LEFT]);
- print_number_0("marginRight", node->style.margin[CSS_RIGHT]);
- print_number_0("marginTop", node->style.margin[CSS_TOP]);
- print_number_0("marginBottom", node->style.margin[CSS_BOTTOM]);
- print_number_0("marginStart", node->style.margin[CSS_START]);
- print_number_0("marginEnd", node->style.margin[CSS_END]);
+ print_number_0("marginLeft", node->style.margin[CSSPositionLeft]);
+ print_number_0("marginRight", node->style.margin[CSSPositionRight]);
+ print_number_0("marginTop", node->style.margin[CSSPositionTop]);
+ print_number_0("marginBottom", node->style.margin[CSSPositionBottom]);
+ print_number_0("marginStart", node->style.margin[CSSPositionStart]);
+ print_number_0("marginEnd", node->style.margin[CSSPositionEnd]);
}
if (four_equal(node->style.padding)) {
- print_number_0("padding", node->style.padding[CSS_LEFT]);
+ print_number_0("padding", node->style.padding[CSSPositionLeft]);
} else {
- print_number_0("paddingLeft", node->style.padding[CSS_LEFT]);
- print_number_0("paddingRight", node->style.padding[CSS_RIGHT]);
- print_number_0("paddingTop", node->style.padding[CSS_TOP]);
- print_number_0("paddingBottom", node->style.padding[CSS_BOTTOM]);
- print_number_0("paddingStart", node->style.padding[CSS_START]);
- print_number_0("paddingEnd", node->style.padding[CSS_END]);
+ print_number_0("paddingLeft", node->style.padding[CSSPositionLeft]);
+ print_number_0("paddingRight", node->style.padding[CSSPositionRight]);
+ print_number_0("paddingTop", node->style.padding[CSSPositionTop]);
+ print_number_0("paddingBottom", node->style.padding[CSSPositionBottom]);
+ print_number_0("paddingStart", node->style.padding[CSSPositionStart]);
+ print_number_0("paddingEnd", node->style.padding[CSSPositionEnd]);
}
if (four_equal(node->style.border)) {
- print_number_0("borderWidth", node->style.border[CSS_LEFT]);
+ print_number_0("borderWidth", node->style.border[CSSPositionLeft]);
} else {
- print_number_0("borderLeftWidth", node->style.border[CSS_LEFT]);
- print_number_0("borderRightWidth", node->style.border[CSS_RIGHT]);
- print_number_0("borderTopWidth", node->style.border[CSS_TOP]);
- print_number_0("borderBottomWidth", node->style.border[CSS_BOTTOM]);
- print_number_0("borderStartWidth", node->style.border[CSS_START]);
- print_number_0("borderEndWidth", node->style.border[CSS_END]);
+ print_number_0("borderLeftWidth", node->style.border[CSSPositionLeft]);
+ print_number_0("borderRightWidth", node->style.border[CSSPositionRight]);
+ print_number_0("borderTopWidth", node->style.border[CSSPositionTop]);
+ print_number_0("borderBottomWidth", node->style.border[CSSPositionBottom]);
+ print_number_0("borderStartWidth", node->style.border[CSSPositionStart]);
+ print_number_0("borderEndWidth", node->style.border[CSSPositionEnd]);
}
- print_number_nan("width", node->style.dimensions[CSS_WIDTH]);
- print_number_nan("height", node->style.dimensions[CSS_HEIGHT]);
- print_number_nan("maxWidth", node->style.maxDimensions[CSS_WIDTH]);
- print_number_nan("maxHeight", node->style.maxDimensions[CSS_HEIGHT]);
- print_number_nan("minWidth", node->style.minDimensions[CSS_WIDTH]);
- print_number_nan("minHeight", node->style.minDimensions[CSS_HEIGHT]);
+ print_number_nan("width", node->style.dimensions[CSSDimensionWidth]);
+ print_number_nan("height", node->style.dimensions[CSSDimensionHeight]);
+ print_number_nan("maxWidth", node->style.maxDimensions[CSSDimensionWidth]);
+ print_number_nan("maxHeight", node->style.maxDimensions[CSSDimensionHeight]);
+ print_number_nan("minWidth", node->style.minDimensions[CSSDimensionWidth]);
+ print_number_nan("minHeight", node->style.minDimensions[CSSDimensionHeight]);
- if (node->style.position_type == CSS_POSITION_ABSOLUTE) {
+ if (node->style.positionType == CSSPositionTypeAbsolute) {
printf("position: 'absolute', ");
}
- print_number_nan("left", node->style.position[CSS_LEFT]);
- print_number_nan("right", node->style.position[CSS_RIGHT]);
- print_number_nan("top", node->style.position[CSS_TOP]);
- print_number_nan("bottom", node->style.position[CSS_BOTTOM]);
+ print_number_nan("left", node->style.position[CSSPositionLeft]);
+ print_number_nan("right", node->style.position[CSSPositionRight]);
+ print_number_nan("top", node->style.position[CSSPositionTop]);
+ print_number_nan("bottom", node->style.position[CSSPositionBottom]);
}
- if (options & CSS_PRINT_CHILDREN && node->children_count > 0) {
+ if (options & CSSPrintOptionsChildren && node->childCount > 0) {
printf("children: [\n");
- for (int i = 0; i < node->children_count; ++i) {
- print_css_node_rec(node->get_child(node->context, i), options, level + 1);
+ for (int i = 0; i < node->childCount; ++i) {
+ print_css_node_rec(node->getChild(node->context, i), options, level + 1);
}
indent(level);
printf("]},\n");
@@ -264,46 +264,46 @@ static void print_css_node_rec(
}
}
-void print_css_node(css_node_t* node, css_print_options_t options) {
+void CSSNodePrint(CSSNode* node, CSSPrintOptions options) {
print_css_node_rec(node, options, 0);
}
-static css_position_t leading[4] = {
- /* CSS_FLEX_DIRECTION_COLUMN = */ CSS_TOP,
- /* CSS_FLEX_DIRECTION_COLUMN_REVERSE = */ CSS_BOTTOM,
- /* CSS_FLEX_DIRECTION_ROW = */ CSS_LEFT,
- /* CSS_FLEX_DIRECTION_ROW_REVERSE = */ CSS_RIGHT
+static CSSPosition leading[4] = {
+ /* CSSFlexDirectionColumn = */ CSSPositionTop,
+ /* CSSFlexDirectionColumnReverse = */ CSSPositionBottom,
+ /* CSSFlexDirectionRow = */ CSSPositionLeft,
+ /* CSSFlexDirectionRowReverse = */ CSSPositionRight
};
-static css_position_t trailing[4] = {
- /* CSS_FLEX_DIRECTION_COLUMN = */ CSS_BOTTOM,
- /* CSS_FLEX_DIRECTION_COLUMN_REVERSE = */ CSS_TOP,
- /* CSS_FLEX_DIRECTION_ROW = */ CSS_RIGHT,
- /* CSS_FLEX_DIRECTION_ROW_REVERSE = */ CSS_LEFT
+static CSSPosition trailing[4] = {
+ /* CSSFlexDirectionColumn = */ CSSPositionBottom,
+ /* CSSFlexDirectionColumnReverse = */ CSSPositionTop,
+ /* CSSFlexDirectionRow = */ CSSPositionRight,
+ /* CSSFlexDirectionRowReverse = */ CSSPositionLeft
};
-static css_position_t pos[4] = {
- /* CSS_FLEX_DIRECTION_COLUMN = */ CSS_TOP,
- /* CSS_FLEX_DIRECTION_COLUMN_REVERSE = */ CSS_BOTTOM,
- /* CSS_FLEX_DIRECTION_ROW = */ CSS_LEFT,
- /* CSS_FLEX_DIRECTION_ROW_REVERSE = */ CSS_RIGHT
+static CSSPosition pos[4] = {
+ /* CSSFlexDirectionColumn = */ CSSPositionTop,
+ /* CSSFlexDirectionColumnReverse = */ CSSPositionBottom,
+ /* CSSFlexDirectionRow = */ CSSPositionLeft,
+ /* CSSFlexDirectionRowReverse = */ CSSPositionRight
};
-static css_dimension_t dim[4] = {
- /* CSS_FLEX_DIRECTION_COLUMN = */ CSS_HEIGHT,
- /* CSS_FLEX_DIRECTION_COLUMN_REVERSE = */ CSS_HEIGHT,
- /* CSS_FLEX_DIRECTION_ROW = */ CSS_WIDTH,
- /* CSS_FLEX_DIRECTION_ROW_REVERSE = */ CSS_WIDTH
+static CSSDimension dim[4] = {
+ /* CSSFlexDirectionColumn = */ CSSDimensionHeight,
+ /* CSSFlexDirectionColumnReverse = */ CSSDimensionHeight,
+ /* CSSFlexDirectionRow = */ CSSDimensionWidth,
+ /* CSSFlexDirectionRowReverse = */ CSSDimensionWidth
};
-static bool isRowDirection(css_flex_direction_t flex_direction) {
- return flex_direction == CSS_FLEX_DIRECTION_ROW ||
- flex_direction == CSS_FLEX_DIRECTION_ROW_REVERSE;
+static bool isRowDirection(CSSFlexDirection flexDirection) {
+ return flexDirection == CSSFlexDirectionRow ||
+ flexDirection == CSSFlexDirectionRowReverse;
}
-static bool isColumnDirection(css_flex_direction_t flex_direction) {
- return flex_direction == CSS_FLEX_DIRECTION_COLUMN ||
- flex_direction == CSS_FLEX_DIRECTION_COLUMN_REVERSE;
+static bool isColumnDirection(CSSFlexDirection flexDirection) {
+ return flexDirection == CSSFlexDirectionColumn ||
+ flexDirection == CSSFlexDirectionColumnReverse;
}
-static bool isFlexBasisAuto(css_node_t* node) {
+static bool isFlexBasisAuto(CSSNode* node) {
#if POSITIVE_FLEX_IS_AUTO
// All flex values are auto.
(void) node;
@@ -314,7 +314,7 @@ static bool isFlexBasisAuto(css_node_t* node) {
#endif
}
-static float getFlexGrowFactor(css_node_t* node) {
+static float getFlexGrowFactor(CSSNode* node) {
// Flex grow is implied by positive values for flex.
if (node->style.flex > 0) {
return node->style.flex;
@@ -322,7 +322,7 @@ static float getFlexGrowFactor(css_node_t* node) {
return 0;
}
-static float getFlexShrinkFactor(css_node_t* node) {
+static float getFlexShrinkFactor(CSSNode* node) {
#if POSITIVE_FLEX_IS_AUTO
// A flex shrink factor of 1 is implied by non-zero values for flex.
if (node->style.flex != 0) {
@@ -337,27 +337,27 @@ static float getFlexShrinkFactor(css_node_t* node) {
return 0;
}
-static float getLeadingMargin(css_node_t* node, css_flex_direction_t axis) {
- if (isRowDirection(axis) && !isUndefined(node->style.margin[CSS_START])) {
- return node->style.margin[CSS_START];
+static float getLeadingMargin(CSSNode* node, CSSFlexDirection axis) {
+ if (isRowDirection(axis) && !isUndefined(node->style.margin[CSSPositionStart])) {
+ return node->style.margin[CSSPositionStart];
}
return node->style.margin[leading[axis]];
}
-static float getTrailingMargin(css_node_t* node, css_flex_direction_t axis) {
- if (isRowDirection(axis) && !isUndefined(node->style.margin[CSS_END])) {
- return node->style.margin[CSS_END];
+static float getTrailingMargin(CSSNode* node, CSSFlexDirection axis) {
+ if (isRowDirection(axis) && !isUndefined(node->style.margin[CSSPositionEnd])) {
+ return node->style.margin[CSSPositionEnd];
}
return node->style.margin[trailing[axis]];
}
-static float getLeadingPadding(css_node_t* node, css_flex_direction_t axis) {
+static float getLeadingPadding(CSSNode* node, CSSFlexDirection axis) {
if (isRowDirection(axis) &&
- !isUndefined(node->style.padding[CSS_START]) &&
- node->style.padding[CSS_START] >= 0) {
- return node->style.padding[CSS_START];
+ !isUndefined(node->style.padding[CSSPositionStart]) &&
+ node->style.padding[CSSPositionStart] >= 0) {
+ return node->style.padding[CSSPositionStart];
}
if (node->style.padding[leading[axis]] >= 0) {
@@ -367,11 +367,11 @@ static float getLeadingPadding(css_node_t* node, css_flex_direction_t axis) {
return 0;
}
-static float getTrailingPadding(css_node_t* node, css_flex_direction_t axis) {
+static float getTrailingPadding(CSSNode* node, CSSFlexDirection axis) {
if (isRowDirection(axis) &&
- !isUndefined(node->style.padding[CSS_END]) &&
- node->style.padding[CSS_END] >= 0) {
- return node->style.padding[CSS_END];
+ !isUndefined(node->style.padding[CSSPositionEnd]) &&
+ node->style.padding[CSSPositionEnd] >= 0) {
+ return node->style.padding[CSSPositionEnd];
}
if (node->style.padding[trailing[axis]] >= 0) {
@@ -381,11 +381,11 @@ static float getTrailingPadding(css_node_t* node, css_flex_direction_t axis) {
return 0;
}
-static float getLeadingBorder(css_node_t* node, css_flex_direction_t axis) {
+static float getLeadingBorder(CSSNode* node, CSSFlexDirection axis) {
if (isRowDirection(axis) &&
- !isUndefined(node->style.border[CSS_START]) &&
- node->style.border[CSS_START] >= 0) {
- return node->style.border[CSS_START];
+ !isUndefined(node->style.border[CSSPositionStart]) &&
+ node->style.border[CSSPositionStart] >= 0) {
+ return node->style.border[CSSPositionStart];
}
if (node->style.border[leading[axis]] >= 0) {
@@ -395,11 +395,11 @@ static float getLeadingBorder(css_node_t* node, css_flex_direction_t axis) {
return 0;
}
-static float getTrailingBorder(css_node_t* node, css_flex_direction_t axis) {
+static float getTrailingBorder(CSSNode* node, CSSFlexDirection axis) {
if (isRowDirection(axis) &&
- !isUndefined(node->style.border[CSS_END]) &&
- node->style.border[CSS_END] >= 0) {
- return node->style.border[CSS_END];
+ !isUndefined(node->style.border[CSSPositionEnd]) &&
+ node->style.border[CSSPositionEnd] >= 0) {
+ return node->style.border[CSSPositionEnd];
}
if (node->style.border[trailing[axis]] >= 0) {
@@ -409,103 +409,103 @@ static float getTrailingBorder(css_node_t* node, css_flex_direction_t axis) {
return 0;
}
-static float getLeadingPaddingAndBorder(css_node_t* node, css_flex_direction_t axis) {
+static float getLeadingPaddingAndBorder(CSSNode* node, CSSFlexDirection axis) {
return getLeadingPadding(node, axis) + getLeadingBorder(node, axis);
}
-static float getTrailingPaddingAndBorder(css_node_t* node, css_flex_direction_t axis) {
+static float getTrailingPaddingAndBorder(CSSNode* node, CSSFlexDirection axis) {
return getTrailingPadding(node, axis) + getTrailingBorder(node, axis);
}
-static float getMarginAxis(css_node_t* node, css_flex_direction_t axis) {
+static float getMarginAxis(CSSNode* node, CSSFlexDirection axis) {
return getLeadingMargin(node, axis) + getTrailingMargin(node, axis);
}
-static float getPaddingAndBorderAxis(css_node_t* node, css_flex_direction_t axis) {
+static float getPaddingAndBorderAxis(CSSNode* node, CSSFlexDirection axis) {
return getLeadingPaddingAndBorder(node, axis) + getTrailingPaddingAndBorder(node, axis);
}
-static css_align_t getAlignItem(css_node_t* node, css_node_t* child) {
- if (child->style.align_self != CSS_ALIGN_AUTO) {
- return child->style.align_self;
+static CSSAlign getAlignItem(CSSNode* node, CSSNode* child) {
+ if (child->style.alignSelf != CSSAlignAuto) {
+ return child->style.alignSelf;
}
- return node->style.align_items;
+ return node->style.alignItems;
}
-static css_direction_t resolveDirection(css_node_t* node, css_direction_t parentDirection) {
- css_direction_t direction = node->style.direction;
+static CSSDirection resolveDirection(CSSNode* node, CSSDirection parentDirection) {
+ CSSDirection direction = node->style.direction;
- if (direction == CSS_DIRECTION_INHERIT) {
- direction = parentDirection > CSS_DIRECTION_INHERIT ? parentDirection : CSS_DIRECTION_LTR;
+ if (direction == CSSDirectionInherit) {
+ direction = parentDirection > CSSDirectionInherit ? parentDirection : CSSDirectionLTR;
}
return direction;
}
-static css_flex_direction_t getFlexDirection(css_node_t* node) {
- return node->style.flex_direction;
+static CSSFlexDirection getFlexDirection(CSSNode* node) {
+ return node->style.flexDirection;
}
-static css_flex_direction_t resolveAxis(css_flex_direction_t flex_direction, css_direction_t direction) {
- if (direction == CSS_DIRECTION_RTL) {
- if (flex_direction == CSS_FLEX_DIRECTION_ROW) {
- return CSS_FLEX_DIRECTION_ROW_REVERSE;
- } else if (flex_direction == CSS_FLEX_DIRECTION_ROW_REVERSE) {
- return CSS_FLEX_DIRECTION_ROW;
+static CSSFlexDirection resolveAxis(CSSFlexDirection flexDirection, CSSDirection direction) {
+ if (direction == CSSDirectionRTL) {
+ if (flexDirection == CSSFlexDirectionRow) {
+ return CSSFlexDirectionRowReverse;
+ } else if (flexDirection == CSSFlexDirectionRowReverse) {
+ return CSSFlexDirectionRow;
}
}
- return flex_direction;
+ return flexDirection;
}
-static css_flex_direction_t getCrossFlexDirection(css_flex_direction_t flex_direction, css_direction_t direction) {
- if (isColumnDirection(flex_direction)) {
- return resolveAxis(CSS_FLEX_DIRECTION_ROW, direction);
+static CSSFlexDirection getCrossFlexDirection(CSSFlexDirection flexDirection, CSSDirection direction) {
+ if (isColumnDirection(flexDirection)) {
+ return resolveAxis(CSSFlexDirectionRow, direction);
} else {
- return CSS_FLEX_DIRECTION_COLUMN;
+ return CSSFlexDirectionColumn;
}
}
-static float getFlex(css_node_t* node) {
+static float getFlex(CSSNode* node) {
return node->style.flex;
}
-static bool isFlex(css_node_t* node) {
+static bool isFlex(CSSNode* node) {
return (
- node->style.position_type == CSS_POSITION_RELATIVE &&
+ node->style.positionType == CSSPositionTypeRelative &&
getFlex(node) != 0
);
}
-static bool isFlexWrap(css_node_t* node) {
- return node->style.flex_wrap == CSS_WRAP;
+static bool isFlexWrap(CSSNode* node) {
+ return node->style.flexWrap == CSSWrapTypeWrap;
}
-static float getDimWithMargin(css_node_t* node, css_flex_direction_t axis) {
- return node->layout.measured_dimensions[dim[axis]] +
+static float getDimWithMargin(CSSNode* node, CSSFlexDirection axis) {
+ return node->layout.measuredDimensions[dim[axis]] +
getLeadingMargin(node, axis) +
getTrailingMargin(node, axis);
}
-static bool isStyleDimDefined(css_node_t* node, css_flex_direction_t axis) {
+static bool isStyleDimDefined(CSSNode* node, CSSFlexDirection axis) {
float value = node->style.dimensions[dim[axis]];
return !isUndefined(value) && value >= 0.0;
}
-static bool isLayoutDimDefined(css_node_t* node, css_flex_direction_t axis) {
- float value = node->layout.measured_dimensions[dim[axis]];
+static bool isLayoutDimDefined(CSSNode* node, CSSFlexDirection axis) {
+ float value = node->layout.measuredDimensions[dim[axis]];
return !isUndefined(value) && value >= 0.0;
}
-static bool isPosDefined(css_node_t* node, css_position_t position) {
+static bool isPosDefined(CSSNode* node, CSSPosition position) {
return !isUndefined(node->style.position[position]);
}
-static bool isMeasureDefined(css_node_t* node) {
+static bool isMeasureDefined(CSSNode* node) {
return node->measure;
}
-static float getPosition(css_node_t* node, css_position_t position) {
+static float getPosition(CSSNode* node, CSSPosition position) {
float result = node->style.position[position];
if (!isUndefined(result)) {
return result;
@@ -513,16 +513,16 @@ static float getPosition(css_node_t* node, css_position_t position) {
return 0;
}
-static float boundAxisWithinMinAndMax(css_node_t* node, css_flex_direction_t axis, float value) {
- float min = CSS_UNDEFINED;
- float max = CSS_UNDEFINED;
+static float boundAxisWithinMinAndMax(CSSNode* node, CSSFlexDirection axis, float value) {
+ float min = CSSUndefined;
+ float max = CSSUndefined;
if (isColumnDirection(axis)) {
- min = node->style.minDimensions[CSS_HEIGHT];
- max = node->style.maxDimensions[CSS_HEIGHT];
+ min = node->style.minDimensions[CSSDimensionHeight];
+ max = node->style.maxDimensions[CSSDimensionHeight];
} else if (isRowDirection(axis)) {
- min = node->style.minDimensions[CSS_WIDTH];
- max = node->style.maxDimensions[CSS_WIDTH];
+ min = node->style.minDimensions[CSSDimensionWidth];
+ max = node->style.maxDimensions[CSSDimensionWidth];
}
float boundValue = value;
@@ -539,20 +539,20 @@ static float boundAxisWithinMinAndMax(css_node_t* node, css_flex_direction_t axi
// Like boundAxisWithinMinAndMax but also ensures that the value doesn't go below the
// padding and border amount.
-static float boundAxis(css_node_t* node, css_flex_direction_t axis, float value) {
+static float boundAxis(CSSNode* node, CSSFlexDirection axis, float value) {
return fmaxf(boundAxisWithinMinAndMax(node, axis, value), getPaddingAndBorderAxis(node, axis));
}
-static void setTrailingPosition(css_node_t* node, css_node_t* child, css_flex_direction_t axis) {
- float size = child->style.position_type == CSS_POSITION_ABSOLUTE ?
+static void setTrailingPosition(CSSNode* node, CSSNode* child, CSSFlexDirection axis) {
+ float size = child->style.positionType == CSSPositionTypeAbsolute ?
0 :
- child->layout.measured_dimensions[dim[axis]];
- child->layout.position[trailing[axis]] = node->layout.measured_dimensions[dim[axis]] - size - child->layout.position[pos[axis]];
+ child->layout.measuredDimensions[dim[axis]];
+ child->layout.position[trailing[axis]] = node->layout.measuredDimensions[dim[axis]] - size - child->layout.position[pos[axis]];
}
// If both left and right are defined, then use left. Otherwise return
// +left or -right depending on which is defined.
-static float getRelativePosition(css_node_t* node, css_flex_direction_t axis) {
+static float getRelativePosition(CSSNode* node, CSSFlexDirection axis) {
float lead = node->style.position[leading[axis]];
if (!isUndefined(lead)) {
return lead;
@@ -560,9 +560,9 @@ static float getRelativePosition(css_node_t* node, css_flex_direction_t axis) {
return -getPosition(node, trailing[axis]);
}
-static void setPosition(css_node_t* node, css_direction_t direction) {
- css_flex_direction_t mainAxis = resolveAxis(getFlexDirection(node), direction);
- css_flex_direction_t crossAxis = getCrossFlexDirection(mainAxis, direction);
+static void setPosition(CSSNode* node, CSSDirection direction) {
+ CSSFlexDirection mainAxis = resolveAxis(getFlexDirection(node), direction);
+ CSSFlexDirection crossAxis = getCrossFlexDirection(mainAxis, direction);
node->layout.position[leading[mainAxis]] = getLeadingMargin(node, mainAxis) +
getRelativePosition(node, mainAxis);
@@ -620,7 +620,7 @@ static void setPosition(css_node_t* node, css_direction_t direction) {
// Input parameters:
// - node: current node to be sized and layed out
// - availableWidth & availableHeight: available size to be used for sizing the node
-// or CSS_UNDEFINED if the size is not available; interpretation depends on layout
+// or CSSUndefined if the size is not available; interpretation depends on layout
// flags
// - parentDirection: the inline (text) direction within the parent (left-to-right or
// right-to-left)
@@ -633,35 +633,35 @@ static void setPosition(css_node_t* node, css_direction_t direction) {
// Details:
// This routine is called recursively to lay out subtrees of flexbox elements. It uses the
// information in node.style, which is treated as a read-only input. It is responsible for
-// setting the layout.direction and layout.measured_dimensions fields for the input node as well
-// as the layout.position and layout.line_index fields for its child nodes. The
-// layout.measured_dimensions field includes any border or padding for the node but does
+// setting the layout.direction and layout.measuredDimensions fields for the input node as well
+// as the layout.position and layout.lineIndex fields for its child nodes. The
+// layout.measuredDimensions field includes any border or padding for the node but does
// not include margins.
//
// The spec describes four different layout modes: "fill available", "max content", "min content",
// and "fit content". Of these, we don't use "min content" because we don't support default
// minimum main sizes (see above for details). Each of our measure modes maps to a layout mode
// from the spec (https://www.w3.org/TR/css3-sizing/#terms):
-// - CSS_MEASURE_MODE_UNDEFINED: max content
-// - CSS_MEASURE_MODE_EXACTLY: fill available
-// - CSS_MEASURE_MODE_AT_MOST: fit content
+// - CSSMeasureModeUndefined: max content
+// - CSSMeasureModeExactly: fill available
+// - CSSMeasureModeAtMost: fit content
//
// When calling layoutNodeImpl and layoutNodeInternal, if the caller passes an available size of
-// undefined then it must also pass a measure mode of CSS_MEASURE_MODE_UNDEFINED in that dimension.
+// undefined then it must also pass a measure mode of CSSMeasureModeUndefined in that dimension.
//
-static void layoutNodeImpl(css_node_t* node, float availableWidth, float availableHeight,
- css_direction_t parentDirection, css_measure_mode_t widthMeasureMode, css_measure_mode_t heightMeasureMode, bool performLayout) {
+static void layoutNodeImpl(CSSNode* node, float availableWidth, float availableHeight,
+ CSSDirection parentDirection, CSSMeasureMode widthMeasureMode, CSSMeasureMode heightMeasureMode, bool performLayout) {
- assert(isUndefined(availableWidth) ? widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED : true); // availableWidth is indefinite so widthMeasureMode must be CSS_MEASURE_MODE_UNDEFINED
- assert(isUndefined(availableHeight) ? heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED : true); // availableHeight is indefinite so heightMeasureMode must be CSS_MEASURE_MODE_UNDEFINED
+ assert(isUndefined(availableWidth) ? widthMeasureMode == CSSMeasureModeUndefined : true); // availableWidth is indefinite so widthMeasureMode must be CSSMeasureModeUndefined
+ assert(isUndefined(availableHeight) ? heightMeasureMode == CSSMeasureModeUndefined : true); // availableHeight is indefinite so heightMeasureMode must be CSSMeasureModeUndefined
- float paddingAndBorderAxisRow = getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_ROW);
- float paddingAndBorderAxisColumn = getPaddingAndBorderAxis(node, CSS_FLEX_DIRECTION_COLUMN);
- float marginAxisRow = getMarginAxis(node, CSS_FLEX_DIRECTION_ROW);
- float marginAxisColumn = getMarginAxis(node, CSS_FLEX_DIRECTION_COLUMN);
+ float paddingAndBorderAxisRow = getPaddingAndBorderAxis(node, CSSFlexDirectionRow);
+ float paddingAndBorderAxisColumn = getPaddingAndBorderAxis(node, CSSFlexDirectionColumn);
+ float marginAxisRow = getMarginAxis(node, CSSFlexDirectionRow);
+ float marginAxisColumn = getMarginAxis(node, CSSFlexDirectionColumn);
// Set the resolved resolution in the node's layout.
- css_direction_t direction = resolveDirection(node, parentDirection);
+ CSSDirection direction = resolveDirection(node, parentDirection);
node->layout.direction = direction;
// For content (text) nodes, determine the dimensions based on the text contents.
@@ -669,20 +669,20 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab
float innerWidth = availableWidth - marginAxisRow - paddingAndBorderAxisRow;
float innerHeight = availableHeight - marginAxisColumn - paddingAndBorderAxisColumn;
- if (widthMeasureMode == CSS_MEASURE_MODE_EXACTLY && heightMeasureMode == CSS_MEASURE_MODE_EXACTLY) {
+ if (widthMeasureMode == CSSMeasureModeExactly && heightMeasureMode == CSSMeasureModeExactly) {
// Don't bother sizing the text if both dimensions are already defined.
- node->layout.measured_dimensions[CSS_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, availableWidth - marginAxisRow);
- node->layout.measured_dimensions[CSS_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, availableHeight - marginAxisColumn);
+ node->layout.measuredDimensions[CSSDimensionWidth] = boundAxis(node, CSSFlexDirectionRow, availableWidth - marginAxisRow);
+ node->layout.measuredDimensions[CSSDimensionHeight] = boundAxis(node, CSSFlexDirectionColumn, availableHeight - marginAxisColumn);
} else if (innerWidth <= 0 || innerHeight <= 0) {
// Don't bother sizing the text if there's no horizontal or vertical space.
- node->layout.measured_dimensions[CSS_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, 0);
- node->layout.measured_dimensions[CSS_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, 0);
+ node->layout.measuredDimensions[CSSDimensionWidth] = boundAxis(node, CSSFlexDirectionRow, 0);
+ node->layout.measuredDimensions[CSSDimensionHeight] = boundAxis(node, CSSFlexDirectionColumn, 0);
} else {
// Measure the text under the current constraints.
- css_dim_t measureDim = node->measure(
+ CSSMeasureResult measureDim = node->measure(
node->context,
innerWidth,
@@ -691,13 +691,13 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab
heightMeasureMode
);
- node->layout.measured_dimensions[CSS_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW,
- (widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED || widthMeasureMode == CSS_MEASURE_MODE_AT_MOST) ?
- measureDim.dimensions[CSS_WIDTH] + paddingAndBorderAxisRow :
+ node->layout.measuredDimensions[CSSDimensionWidth] = boundAxis(node, CSSFlexDirectionRow,
+ (widthMeasureMode == CSSMeasureModeUndefined || widthMeasureMode == CSSMeasureModeAtMost) ?
+ measureDim.dimensions[CSSDimensionWidth] + paddingAndBorderAxisRow :
availableWidth - marginAxisRow);
- node->layout.measured_dimensions[CSS_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN,
- (heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED || heightMeasureMode == CSS_MEASURE_MODE_AT_MOST) ?
- measureDim.dimensions[CSS_HEIGHT] + paddingAndBorderAxisColumn :
+ node->layout.measuredDimensions[CSSDimensionHeight] = boundAxis(node, CSSFlexDirectionColumn,
+ (heightMeasureMode == CSSMeasureModeUndefined || heightMeasureMode == CSSMeasureModeAtMost) ?
+ measureDim.dimensions[CSSDimensionHeight] + paddingAndBorderAxisColumn :
availableHeight - marginAxisColumn);
}
@@ -706,14 +706,14 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab
// For nodes with no children, use the available values if they were provided, or
// the minimum size as indicated by the padding and border sizes.
- int childCount = node->children_count;
+ int childCount = node->childCount;
if (childCount == 0) {
- node->layout.measured_dimensions[CSS_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW,
- (widthMeasureMode == CSS_MEASURE_MODE_UNDEFINED || widthMeasureMode == CSS_MEASURE_MODE_AT_MOST) ?
+ node->layout.measuredDimensions[CSSDimensionWidth] = boundAxis(node, CSSFlexDirectionRow,
+ (widthMeasureMode == CSSMeasureModeUndefined || widthMeasureMode == CSSMeasureModeAtMost) ?
paddingAndBorderAxisRow :
availableWidth - marginAxisRow);
- node->layout.measured_dimensions[CSS_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN,
- (heightMeasureMode == CSS_MEASURE_MODE_UNDEFINED || heightMeasureMode == CSS_MEASURE_MODE_AT_MOST) ?
+ node->layout.measuredDimensions[CSSDimensionHeight] = boundAxis(node, CSSFlexDirectionColumn,
+ (heightMeasureMode == CSSMeasureModeUndefined || heightMeasureMode == CSSMeasureModeAtMost) ?
paddingAndBorderAxisColumn :
availableHeight - marginAxisColumn);
return;
@@ -724,42 +724,42 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab
if (!performLayout) {
// If we're being asked to size the content with an at most constraint but there is no available width,
// the measurement will always be zero.
- if (widthMeasureMode == CSS_MEASURE_MODE_AT_MOST && availableWidth <= 0 &&
- heightMeasureMode == CSS_MEASURE_MODE_AT_MOST && availableHeight <= 0) {
- node->layout.measured_dimensions[CSS_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, 0);
- node->layout.measured_dimensions[CSS_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, 0);
+ if (widthMeasureMode == CSSMeasureModeAtMost && availableWidth <= 0 &&
+ heightMeasureMode == CSSMeasureModeAtMost && availableHeight <= 0) {
+ node->layout.measuredDimensions[CSSDimensionWidth] = boundAxis(node, CSSFlexDirectionRow, 0);
+ node->layout.measuredDimensions[CSSDimensionHeight] = boundAxis(node, CSSFlexDirectionColumn, 0);
return;
}
- if (widthMeasureMode == CSS_MEASURE_MODE_AT_MOST && availableWidth <= 0) {
- node->layout.measured_dimensions[CSS_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, 0);
- node->layout.measured_dimensions[CSS_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, isUndefined(availableHeight) ? 0 : (availableHeight - marginAxisColumn));
+ if (widthMeasureMode == CSSMeasureModeAtMost && availableWidth <= 0) {
+ node->layout.measuredDimensions[CSSDimensionWidth] = boundAxis(node, CSSFlexDirectionRow, 0);
+ node->layout.measuredDimensions[CSSDimensionHeight] = boundAxis(node, CSSFlexDirectionColumn, isUndefined(availableHeight) ? 0 : (availableHeight - marginAxisColumn));
return;
}
- if (heightMeasureMode == CSS_MEASURE_MODE_AT_MOST && availableHeight <= 0) {
- node->layout.measured_dimensions[CSS_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, isUndefined(availableWidth) ? 0 : (availableWidth - marginAxisRow));
- node->layout.measured_dimensions[CSS_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, 0);
+ if (heightMeasureMode == CSSMeasureModeAtMost && availableHeight <= 0) {
+ node->layout.measuredDimensions[CSSDimensionWidth] = boundAxis(node, CSSFlexDirectionRow, isUndefined(availableWidth) ? 0 : (availableWidth - marginAxisRow));
+ node->layout.measuredDimensions[CSSDimensionHeight] = boundAxis(node, CSSFlexDirectionColumn, 0);
return;
}
// If we're being asked to use an exact width/height, there's no need to measure the children.
- if (widthMeasureMode == CSS_MEASURE_MODE_EXACTLY && heightMeasureMode == CSS_MEASURE_MODE_EXACTLY) {
- node->layout.measured_dimensions[CSS_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, availableWidth - marginAxisRow);
- node->layout.measured_dimensions[CSS_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, availableHeight - marginAxisColumn);
+ if (widthMeasureMode == CSSMeasureModeExactly && heightMeasureMode == CSSMeasureModeExactly) {
+ node->layout.measuredDimensions[CSSDimensionWidth] = boundAxis(node, CSSFlexDirectionRow, availableWidth - marginAxisRow);
+ node->layout.measuredDimensions[CSSDimensionHeight] = boundAxis(node, CSSFlexDirectionColumn, availableHeight - marginAxisColumn);
return;
}
}
// STEP 1: CALCULATE VALUES FOR REMAINDER OF ALGORITHM
- css_flex_direction_t mainAxis = resolveAxis(getFlexDirection(node), direction);
- css_flex_direction_t crossAxis = getCrossFlexDirection(mainAxis, direction);
+ CSSFlexDirection mainAxis = resolveAxis(getFlexDirection(node), direction);
+ CSSFlexDirection crossAxis = getCrossFlexDirection(mainAxis, direction);
bool isMainAxisRow = isRowDirection(mainAxis);
- css_justify_t justifyContent = node->style.justify_content;
+ CSSJustify justifyContent = node->style.justifyContent;
bool isNodeFlexWrap = isFlexWrap(node);
- css_node_t* firstAbsoluteChild = NULL;
- css_node_t* currentAbsoluteChild = NULL;
+ CSSNode* firstAbsoluteChild = NULL;
+ CSSNode* currentAbsoluteChild = NULL;
float leadingPaddingAndBorderMain = getLeadingPaddingAndBorder(node, mainAxis);
float trailingPaddingAndBorderMain = getTrailingPaddingAndBorder(node, mainAxis);
@@ -767,8 +767,8 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab
float paddingAndBorderAxisMain = getPaddingAndBorderAxis(node, mainAxis);
float paddingAndBorderAxisCross = getPaddingAndBorderAxis(node, crossAxis);
- css_measure_mode_t measureModeMainDim = isMainAxisRow ? widthMeasureMode : heightMeasureMode;
- css_measure_mode_t measureModeCrossDim = isMainAxisRow ? heightMeasureMode : widthMeasureMode;
+ CSSMeasureMode measureModeMainDim = isMainAxisRow ? widthMeasureMode : heightMeasureMode;
+ CSSMeasureMode measureModeCrossDim = isMainAxisRow ? heightMeasureMode : widthMeasureMode;
// STEP 2: DETERMINE AVAILABLE SIZE IN MAIN AND CROSS DIRECTIONS
float availableInnerWidth = availableWidth - marginAxisRow - paddingAndBorderAxisRow;
@@ -777,24 +777,24 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab
float availableInnerCrossDim = isMainAxisRow ? availableInnerHeight : availableInnerWidth;
// STEP 3: DETERMINE FLEX BASIS FOR EACH ITEM
- css_node_t* child;
+ CSSNode* child;
int i;
float childWidth;
float childHeight;
- css_measure_mode_t childWidthMeasureMode;
- css_measure_mode_t childHeightMeasureMode;
+ CSSMeasureMode childWidthMeasureMode;
+ CSSMeasureMode childHeightMeasureMode;
for (i = 0; i < childCount; i++) {
- child = node->get_child(node->context, i);
+ child = node->getChild(node->context, i);
if (performLayout) {
// Set the initial position (relative to the parent).
- css_direction_t childDirection = resolveDirection(child, direction);
+ CSSDirection childDirection = resolveDirection(child, direction);
setPosition(child, childDirection);
}
// Absolute-positioned children don't participate in flex layout. Add them
// to a list that we can process later.
- if (child->style.position_type == CSS_POSITION_ABSOLUTE) {
+ if (child->style.positionType == CSSPositionTypeAbsolute) {
// Store a private linked list of absolutely positioned children
// so that we can efficiently traverse them later.
@@ -802,39 +802,39 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab
firstAbsoluteChild = child;
}
if (currentAbsoluteChild != NULL) {
- currentAbsoluteChild->next_child = child;
+ currentAbsoluteChild->nextChild = child;
}
currentAbsoluteChild = child;
- child->next_child = NULL;
+ child->nextChild = NULL;
} else {
- if (isMainAxisRow && isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW)) {
+ if (isMainAxisRow && isStyleDimDefined(child, CSSFlexDirectionRow)) {
// The width is definite, so use that as the flex basis.
- child->layout.flex_basis = fmaxf(child->style.dimensions[CSS_WIDTH], getPaddingAndBorderAxis(child, CSS_FLEX_DIRECTION_ROW));
- } else if (!isMainAxisRow && isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN)) {
+ child->layout.flexBasis = fmaxf(child->style.dimensions[CSSDimensionWidth], getPaddingAndBorderAxis(child, CSSFlexDirectionRow));
+ } else if (!isMainAxisRow && isStyleDimDefined(child, CSSFlexDirectionColumn)) {
// The height is definite, so use that as the flex basis.
- child->layout.flex_basis = fmaxf(child->style.dimensions[CSS_HEIGHT], getPaddingAndBorderAxis(child, CSS_FLEX_DIRECTION_COLUMN));
+ child->layout.flexBasis = fmaxf(child->style.dimensions[CSSDimensionHeight], getPaddingAndBorderAxis(child, CSSFlexDirectionColumn));
} else if (!isFlexBasisAuto(child) && !isUndefined(availableInnerMainDim)) {
// If the basis isn't 'auto', it is assumed to be zero.
- child->layout.flex_basis = fmaxf(0, getPaddingAndBorderAxis(child, mainAxis));
+ child->layout.flexBasis = fmaxf(0, getPaddingAndBorderAxis(child, mainAxis));
} else {
// Compute the flex basis and hypothetical main size (i.e. the clamped flex basis).
- childWidth = CSS_UNDEFINED;
- childHeight = CSS_UNDEFINED;
- childWidthMeasureMode = CSS_MEASURE_MODE_UNDEFINED;
- childHeightMeasureMode = CSS_MEASURE_MODE_UNDEFINED;
-
- if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW)) {
- childWidth = child->style.dimensions[CSS_WIDTH] + getMarginAxis(child, CSS_FLEX_DIRECTION_ROW);
- childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;
+ childWidth = CSSUndefined;
+ childHeight = CSSUndefined;
+ childWidthMeasureMode = CSSMeasureModeUndefined;
+ childHeightMeasureMode = CSSMeasureModeUndefined;
+
+ if (isStyleDimDefined(child, CSSFlexDirectionRow)) {
+ childWidth = child->style.dimensions[CSSDimensionWidth] + getMarginAxis(child, CSSFlexDirectionRow);
+ childWidthMeasureMode = CSSMeasureModeExactly;
}
- if (isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN)) {
- childHeight = child->style.dimensions[CSS_HEIGHT] + getMarginAxis(child, CSS_FLEX_DIRECTION_COLUMN);
- childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;
+ if (isStyleDimDefined(child, CSSFlexDirectionColumn)) {
+ childHeight = child->style.dimensions[CSSDimensionHeight] + getMarginAxis(child, CSSFlexDirectionColumn);
+ childHeightMeasureMode = CSSMeasureModeExactly;
}
// According to the spec, if the main size is not definite and the
@@ -843,15 +843,15 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab
// the main size. Otherwise use "AT_MOST" in the cross axis.
if (!isMainAxisRow && isUndefined(childWidth) && !isUndefined(availableInnerWidth)) {
childWidth = availableInnerWidth;
- childWidthMeasureMode = CSS_MEASURE_MODE_AT_MOST;
+ childWidthMeasureMode = CSSMeasureModeAtMost;
}
// The W3C spec doesn't say anything about the 'overflow' property,
// but all major browsers appear to implement the following logic.
- if (node->style.overflow == CSS_OVERFLOW_HIDDEN) {
+ if (node->style.overflow == CSSOverflowHidden) {
if (isMainAxisRow && isUndefined(childHeight) && !isUndefined(availableInnerHeight)) {
childHeight = availableInnerHeight;
- childHeightMeasureMode = CSS_MEASURE_MODE_AT_MOST;
+ childHeightMeasureMode = CSSMeasureModeAtMost;
}
}
@@ -859,25 +859,25 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab
// axis to be measured exactly with the available inner width
if (!isMainAxisRow &&
!isUndefined(availableInnerWidth) &&
- !isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW) &&
- widthMeasureMode == CSS_MEASURE_MODE_EXACTLY &&
- getAlignItem(node, child) == CSS_ALIGN_STRETCH) {
+ !isStyleDimDefined(child, CSSFlexDirectionRow) &&
+ widthMeasureMode == CSSMeasureModeExactly &&
+ getAlignItem(node, child) == CSSAlignStretch) {
childWidth = availableInnerWidth;
- childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;
+ childWidthMeasureMode = CSSMeasureModeExactly;
}
if (isMainAxisRow &&
!isUndefined(availableInnerHeight) &&
- !isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN) &&
- heightMeasureMode == CSS_MEASURE_MODE_EXACTLY &&
- getAlignItem(node, child) == CSS_ALIGN_STRETCH) {
+ !isStyleDimDefined(child, CSSFlexDirectionColumn) &&
+ heightMeasureMode == CSSMeasureModeExactly &&
+ getAlignItem(node, child) == CSSAlignStretch) {
childHeight = availableInnerHeight;
- childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;
+ childHeightMeasureMode = CSSMeasureModeExactly;
}
// Measure the child
layoutNodeInternal(child, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, false, "measure");
- child->layout.flex_basis = fmaxf(isMainAxisRow ? child->layout.measured_dimensions[CSS_WIDTH] : child->layout.measured_dimensions[CSS_HEIGHT], getPaddingAndBorderAxis(child, mainAxis));
+ child->layout.flexBasis = fmaxf(isMainAxisRow ? child->layout.measuredDimensions[CSSDimensionWidth] : child->layout.measuredDimensions[CSSDimensionHeight], getPaddingAndBorderAxis(child, mainAxis));
}
}
}
@@ -915,16 +915,16 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab
i = startOfLineIndex;
// Maintain a linked list of the child nodes that can shrink and/or grow.
- css_node_t* firstRelativeChild = NULL;
- css_node_t* currentRelativeChild = NULL;
+ CSSNode* firstRelativeChild = NULL;
+ CSSNode* currentRelativeChild = NULL;
// Add items to the current line until it's full or we run out of items.
while (i < childCount) {
- child = node->get_child(node->context, i);
- child->line_index = lineCount;
+ child = node->getChild(node->context, i);
+ child->lineIndex = lineCount;
- if (child->style.position_type != CSS_POSITION_ABSOLUTE) {
- float outerFlexBasis = child->layout.flex_basis + getMarginAxis(child, mainAxis);
+ if (child->style.positionType != CSSPositionTypeAbsolute) {
+ float outerFlexBasis = child->layout.flexBasis + getMarginAxis(child, mainAxis);
// If this is a multi-line flow and this item pushes us over the available size, we've
// hit the end of the current line. Break out of the loop and lay out the current line.
@@ -940,7 +940,7 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab
// Unlike the grow factor, the shrink factor is scaled relative to the child
// dimension.
- totalFlexShrinkScaledFactors += getFlexShrinkFactor(child) * child->layout.flex_basis;
+ totalFlexShrinkScaledFactors += getFlexShrinkFactor(child) * child->layout.flexBasis;
}
// Store a private linked list of children that need to be layed out.
@@ -948,10 +948,10 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab
firstRelativeChild = child;
}
if (currentRelativeChild != NULL) {
- currentRelativeChild->next_child = child;
+ currentRelativeChild->nextChild = child;
}
currentRelativeChild = child;
- child->next_child = NULL;
+ child->nextChild = NULL;
}
i++;
@@ -959,7 +959,7 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab
}
// If we don't need to measure the cross axis, we can skip the entire flex step.
- bool canSkipFlex = !performLayout && measureModeCrossDim == CSS_MEASURE_MODE_EXACTLY;
+ bool canSkipFlex = !performLayout && measureModeCrossDim == CSSMeasureModeExactly;
// In order to position the elements in the main axis, we have two
// controls. The space between the beginning and the first element
@@ -1009,7 +1009,7 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab
float deltaFlexGrowFactors = 0;
currentRelativeChild = firstRelativeChild;
while (currentRelativeChild != NULL) {
- childFlexBasis = currentRelativeChild->layout.flex_basis;
+ childFlexBasis = currentRelativeChild->layout.flexBasis;
if (remainingFreeSpace < 0) {
flexShrinkScaledFactor = getFlexShrinkFactor(currentRelativeChild) * childFlexBasis;
@@ -1045,7 +1045,7 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab
}
}
- currentRelativeChild = currentRelativeChild->next_child;
+ currentRelativeChild = currentRelativeChild->nextChild;
}
totalFlexShrinkScaledFactors += deltaFlexShrinkScaledFactors;
@@ -1056,7 +1056,7 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab
deltaFreeSpace = 0;
currentRelativeChild = firstRelativeChild;
while (currentRelativeChild != NULL) {
- childFlexBasis = currentRelativeChild->layout.flex_basis;
+ childFlexBasis = currentRelativeChild->layout.flexBasis;
float updatedMainSize = childFlexBasis;
if (remainingFreeSpace < 0) {
@@ -1080,48 +1080,48 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab
deltaFreeSpace -= updatedMainSize - childFlexBasis;
if (isMainAxisRow) {
- childWidth = updatedMainSize + getMarginAxis(currentRelativeChild, CSS_FLEX_DIRECTION_ROW);
- childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;
+ childWidth = updatedMainSize + getMarginAxis(currentRelativeChild, CSSFlexDirectionRow);
+ childWidthMeasureMode = CSSMeasureModeExactly;
if (!isUndefined(availableInnerCrossDim) &&
- !isStyleDimDefined(currentRelativeChild, CSS_FLEX_DIRECTION_COLUMN) &&
- heightMeasureMode == CSS_MEASURE_MODE_EXACTLY &&
- getAlignItem(node, currentRelativeChild) == CSS_ALIGN_STRETCH) {
+ !isStyleDimDefined(currentRelativeChild, CSSFlexDirectionColumn) &&
+ heightMeasureMode == CSSMeasureModeExactly &&
+ getAlignItem(node, currentRelativeChild) == CSSAlignStretch) {
childHeight = availableInnerCrossDim;
- childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;
- } else if (!isStyleDimDefined(currentRelativeChild, CSS_FLEX_DIRECTION_COLUMN)) {
+ childHeightMeasureMode = CSSMeasureModeExactly;
+ } else if (!isStyleDimDefined(currentRelativeChild, CSSFlexDirectionColumn)) {
childHeight = availableInnerCrossDim;
- childHeightMeasureMode = isUndefined(childHeight) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_AT_MOST;
+ childHeightMeasureMode = isUndefined(childHeight) ? CSSMeasureModeUndefined : CSSMeasureModeAtMost;
} else {
- childHeight = currentRelativeChild->style.dimensions[CSS_HEIGHT] + getMarginAxis(currentRelativeChild, CSS_FLEX_DIRECTION_COLUMN);
- childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;
+ childHeight = currentRelativeChild->style.dimensions[CSSDimensionHeight] + getMarginAxis(currentRelativeChild, CSSFlexDirectionColumn);
+ childHeightMeasureMode = CSSMeasureModeExactly;
}
} else {
- childHeight = updatedMainSize + getMarginAxis(currentRelativeChild, CSS_FLEX_DIRECTION_COLUMN);
- childHeightMeasureMode = CSS_MEASURE_MODE_EXACTLY;
+ childHeight = updatedMainSize + getMarginAxis(currentRelativeChild, CSSFlexDirectionColumn);
+ childHeightMeasureMode = CSSMeasureModeExactly;
if (!isUndefined(availableInnerCrossDim) &&
- !isStyleDimDefined(currentRelativeChild, CSS_FLEX_DIRECTION_ROW) &&
- widthMeasureMode == CSS_MEASURE_MODE_EXACTLY &&
- getAlignItem(node, currentRelativeChild) == CSS_ALIGN_STRETCH) {
+ !isStyleDimDefined(currentRelativeChild, CSSFlexDirectionRow) &&
+ widthMeasureMode == CSSMeasureModeExactly &&
+ getAlignItem(node, currentRelativeChild) == CSSAlignStretch) {
childWidth = availableInnerCrossDim;
- childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;
- } else if (!isStyleDimDefined(currentRelativeChild, CSS_FLEX_DIRECTION_ROW)) {
+ childWidthMeasureMode = CSSMeasureModeExactly;
+ } else if (!isStyleDimDefined(currentRelativeChild, CSSFlexDirectionRow)) {
childWidth = availableInnerCrossDim;
- childWidthMeasureMode = isUndefined(childWidth) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_AT_MOST;
+ childWidthMeasureMode = isUndefined(childWidth) ? CSSMeasureModeUndefined : CSSMeasureModeAtMost;
} else {
- childWidth = currentRelativeChild->style.dimensions[CSS_WIDTH] + getMarginAxis(currentRelativeChild, CSS_FLEX_DIRECTION_ROW);
- childWidthMeasureMode = CSS_MEASURE_MODE_EXACTLY;
+ childWidth = currentRelativeChild->style.dimensions[CSSDimensionWidth] + getMarginAxis(currentRelativeChild, CSSFlexDirectionRow);
+ childWidthMeasureMode = CSSMeasureModeExactly;
}
}
bool requiresStretchLayout = !isStyleDimDefined(currentRelativeChild, crossAxis) &&
- getAlignItem(node, currentRelativeChild) == CSS_ALIGN_STRETCH;
+ getAlignItem(node, currentRelativeChild) == CSSAlignStretch;
// Recursively call the layout algorithm for this child with the updated main size.
layoutNodeInternal(currentRelativeChild, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, performLayout && !requiresStretchLayout, "flex");
- currentRelativeChild = currentRelativeChild->next_child;
+ currentRelativeChild = currentRelativeChild->nextChild;
}
}
@@ -1136,25 +1136,25 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab
// If we are using "at most" rules in the main axis, we won't distribute
// any remaining space at this point.
- if (measureModeMainDim == CSS_MEASURE_MODE_AT_MOST) {
+ if (measureModeMainDim == CSSMeasureModeAtMost) {
remainingFreeSpace = 0;
}
// Use justifyContent to figure out how to allocate the remaining space
// available in the main axis.
- if (justifyContent != CSS_JUSTIFY_FLEX_START) {
- if (justifyContent == CSS_JUSTIFY_CENTER) {
+ if (justifyContent != CSSJustifyFlexStart) {
+ if (justifyContent == CSSJustifyCenter) {
leadingMainDim = remainingFreeSpace / 2;
- } else if (justifyContent == CSS_JUSTIFY_FLEX_END) {
+ } else if (justifyContent == CSSJustifyFlexEnd) {
leadingMainDim = remainingFreeSpace;
- } else if (justifyContent == CSS_JUSTIFY_SPACE_BETWEEN) {
+ } else if (justifyContent == CSSJustifySpaceBetween) {
remainingFreeSpace = fmaxf(remainingFreeSpace, 0);
if (itemsOnLine > 1) {
betweenMainDim = remainingFreeSpace / (itemsOnLine - 1);
} else {
betweenMainDim = 0;
}
- } else if (justifyContent == CSS_JUSTIFY_SPACE_AROUND) {
+ } else if (justifyContent == CSSJustifySpaceAround) {
// Space on the edges is half of the space between elements
betweenMainDim = remainingFreeSpace / itemsOnLine;
leadingMainDim = betweenMainDim / 2;
@@ -1165,9 +1165,9 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab
float crossDim = 0;
for (i = startOfLineIndex; i < endOfLineIndex; ++i) {
- child = node->get_child(node->context, i);
+ child = node->getChild(node->context, i);
- if (child->style.position_type == CSS_POSITION_ABSOLUTE &&
+ if (child->style.positionType == CSSPositionTypeAbsolute &&
isPosDefined(child, leading[mainAxis])) {
if (performLayout) {
// In case the child is position absolute and has left/top being
@@ -1187,11 +1187,11 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab
// Now that we placed the element, we need to update the variables.
// We need to do that only for relative elements. Absolute elements
// do not take part in that phase.
- if (child->style.position_type == CSS_POSITION_RELATIVE) {
+ if (child->style.positionType == CSSPositionTypeRelative) {
if (canSkipFlex) {
// If we skipped the flex step, then we can't rely on the measuredDims because
// they weren't computed. This means we can't call getDimWithMargin.
- mainDim += betweenMainDim + getMarginAxis(child, mainAxis) + child->layout.flex_basis;
+ mainDim += betweenMainDim + getMarginAxis(child, mainAxis) + child->layout.flexBasis;
crossDim = availableInnerCrossDim;
} else {
// The main dimension is the sum of all the elements dimension plus
@@ -1209,17 +1209,17 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab
mainDim += trailingPaddingAndBorderMain;
float containerCrossAxis = availableInnerCrossDim;
- if (measureModeCrossDim == CSS_MEASURE_MODE_UNDEFINED || measureModeCrossDim == CSS_MEASURE_MODE_AT_MOST) {
+ if (measureModeCrossDim == CSSMeasureModeUndefined || measureModeCrossDim == CSSMeasureModeAtMost) {
// Compute the cross axis from the max cross dimension of the children.
containerCrossAxis = boundAxis(node, crossAxis, crossDim + paddingAndBorderAxisCross) - paddingAndBorderAxisCross;
- if (measureModeCrossDim == CSS_MEASURE_MODE_AT_MOST) {
+ if (measureModeCrossDim == CSSMeasureModeAtMost) {
containerCrossAxis = fminf(containerCrossAxis, availableInnerCrossDim);
}
}
// If there's no flex wrap, the cross dimension is defined by the container.
- if (!isNodeFlexWrap && measureModeCrossDim == CSS_MEASURE_MODE_EXACTLY) {
+ if (!isNodeFlexWrap && measureModeCrossDim == CSSMeasureModeExactly) {
crossDim = availableInnerCrossDim;
}
@@ -1230,9 +1230,9 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab
// We can skip child alignment if we're just measuring the container.
if (performLayout) {
for (i = startOfLineIndex; i < endOfLineIndex; ++i) {
- child = node->get_child(node->context, i);
+ child = node->getChild(node->context, i);
- if (child->style.position_type == CSS_POSITION_ABSOLUTE) {
+ if (child->style.positionType == CSSPositionTypeAbsolute) {
// If the child is absolutely positioned and has a top/left/bottom/right
// set, override all the previously computed positions to set it correctly.
if (isPosDefined(child, leading[crossAxis])) {
@@ -1248,35 +1248,35 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab
// For a relative children, we're either using alignItems (parent) or
// alignSelf (child) in order to determine the position in the cross axis
- css_align_t alignItem = getAlignItem(node, child);
+ CSSAlign alignItem = getAlignItem(node, child);
// If the child uses align stretch, we need to lay it out one more time, this time
// forcing the cross-axis size to be the computed cross size for the current line.
- if (alignItem == CSS_ALIGN_STRETCH) {
- childWidth = child->layout.measured_dimensions[CSS_WIDTH] + getMarginAxis(child, CSS_FLEX_DIRECTION_ROW);
- childHeight = child->layout.measured_dimensions[CSS_HEIGHT] + getMarginAxis(child, CSS_FLEX_DIRECTION_COLUMN);
+ if (alignItem == CSSAlignStretch) {
+ childWidth = child->layout.measuredDimensions[CSSDimensionWidth] + getMarginAxis(child, CSSFlexDirectionRow);
+ childHeight = child->layout.measuredDimensions[CSSDimensionHeight] + getMarginAxis(child, CSSFlexDirectionColumn);
bool isCrossSizeDefinite = false;
if (isMainAxisRow) {
- isCrossSizeDefinite = isStyleDimDefined(child, CSS_FLEX_DIRECTION_COLUMN);
+ isCrossSizeDefinite = isStyleDimDefined(child, CSSFlexDirectionColumn);
childHeight = crossDim;
} else {
- isCrossSizeDefinite = isStyleDimDefined(child, CSS_FLEX_DIRECTION_ROW);
+ isCrossSizeDefinite = isStyleDimDefined(child, CSSFlexDirectionRow);
childWidth = crossDim;
}
// If the child defines a definite size for its cross axis, there's no need to stretch.
if (!isCrossSizeDefinite) {
- childWidthMeasureMode = isUndefined(childWidth) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_EXACTLY;
- childHeightMeasureMode = isUndefined(childHeight) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_EXACTLY;
+ childWidthMeasureMode = isUndefined(childWidth) ? CSSMeasureModeUndefined : CSSMeasureModeExactly;
+ childHeightMeasureMode = isUndefined(childHeight) ? CSSMeasureModeUndefined : CSSMeasureModeExactly;
layoutNodeInternal(child, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, true, "stretch");
}
- } else if (alignItem != CSS_ALIGN_FLEX_START) {
+ } else if (alignItem != CSSAlignFlexStart) {
float remainingCrossDim = containerCrossAxis - getDimWithMargin(child, crossAxis);
- if (alignItem == CSS_ALIGN_CENTER) {
+ if (alignItem == CSSAlignCenter) {
leadingCrossDim += remainingCrossDim / 2;
- } else { // CSS_ALIGN_FLEX_END
+ } else { // CSSAlignFlexEnd
leadingCrossDim += remainingCrossDim;
}
}
@@ -1303,12 +1303,12 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab
float crossDimLead = 0;
float currentLead = leadingPaddingAndBorderCross;
- css_align_t alignContent = node->style.align_content;
- if (alignContent == CSS_ALIGN_FLEX_END) {
+ CSSAlign alignContent = node->style.alignContent;
+ if (alignContent == CSSAlignFlexEnd) {
currentLead += remainingAlignContentDim;
- } else if (alignContent == CSS_ALIGN_CENTER) {
+ } else if (alignContent == CSSAlignCenter) {
currentLead += remainingAlignContentDim / 2;
- } else if (alignContent == CSS_ALIGN_STRETCH) {
+ } else if (alignContent == CSSAlignStretch) {
if (availableInnerCrossDim > totalLineCrossDim) {
crossDimLead = (remainingAlignContentDim / lineCount);
}
@@ -1322,16 +1322,16 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab
// compute the line's height and find the endIndex
float lineHeight = 0;
for (j = startIndex; j < childCount; ++j) {
- child = node->get_child(node->context, j);
- if (child->style.position_type != CSS_POSITION_RELATIVE) {
+ child = node->getChild(node->context, j);
+ if (child->style.positionType != CSSPositionTypeRelative) {
continue;
}
- if (child->line_index != i) {
+ if (child->lineIndex != i) {
break;
}
if (isLayoutDimDefined(child, crossAxis)) {
lineHeight = fmaxf(lineHeight,
- child->layout.measured_dimensions[dim[crossAxis]] + getMarginAxis(child, crossAxis));
+ child->layout.measuredDimensions[dim[crossAxis]] + getMarginAxis(child, crossAxis));
}
}
endIndex = j;
@@ -1339,20 +1339,20 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab
if (performLayout) {
for (j = startIndex; j < endIndex; ++j) {
- child = node->get_child(node->context, j);
- if (child->style.position_type != CSS_POSITION_RELATIVE) {
+ child = node->getChild(node->context, j);
+ if (child->style.positionType != CSSPositionTypeRelative) {
continue;
}
- css_align_t alignContentAlignItem = getAlignItem(node, child);
- if (alignContentAlignItem == CSS_ALIGN_FLEX_START) {
+ CSSAlign alignContentAlignItem = getAlignItem(node, child);
+ if (alignContentAlignItem == CSSAlignFlexStart) {
child->layout.position[pos[crossAxis]] = currentLead + getLeadingMargin(child, crossAxis);
- } else if (alignContentAlignItem == CSS_ALIGN_FLEX_END) {
- child->layout.position[pos[crossAxis]] = currentLead + lineHeight - getTrailingMargin(child, crossAxis) - child->layout.measured_dimensions[dim[crossAxis]];
- } else if (alignContentAlignItem == CSS_ALIGN_CENTER) {
- childHeight = child->layout.measured_dimensions[dim[crossAxis]];
+ } else if (alignContentAlignItem == CSSAlignFlexEnd) {
+ child->layout.position[pos[crossAxis]] = currentLead + lineHeight - getTrailingMargin(child, crossAxis) - child->layout.measuredDimensions[dim[crossAxis]];
+ } else if (alignContentAlignItem == CSSAlignCenter) {
+ childHeight = child->layout.measuredDimensions[dim[crossAxis]];
child->layout.position[pos[crossAxis]] = currentLead + (lineHeight - childHeight) / 2;
- } else if (alignContentAlignItem == CSS_ALIGN_STRETCH) {
+ } else if (alignContentAlignItem == CSSAlignStretch) {
child->layout.position[pos[crossAxis]] = currentLead + getLeadingMargin(child, crossAxis);
// TODO(prenaux): Correctly set the height of items with indefinite
// (auto) crossAxis dimension.
@@ -1365,28 +1365,28 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab
}
// STEP 9: COMPUTING FINAL DIMENSIONS
- node->layout.measured_dimensions[CSS_WIDTH] = boundAxis(node, CSS_FLEX_DIRECTION_ROW, availableWidth - marginAxisRow);
- node->layout.measured_dimensions[CSS_HEIGHT] = boundAxis(node, CSS_FLEX_DIRECTION_COLUMN, availableHeight - marginAxisColumn);
+ node->layout.measuredDimensions[CSSDimensionWidth] = boundAxis(node, CSSFlexDirectionRow, availableWidth - marginAxisRow);
+ node->layout.measuredDimensions[CSSDimensionHeight] = boundAxis(node, CSSFlexDirectionColumn, availableHeight - marginAxisColumn);
// If the user didn't specify a width or height for the node, set the
// dimensions based on the children.
- if (measureModeMainDim == CSS_MEASURE_MODE_UNDEFINED) {
+ if (measureModeMainDim == CSSMeasureModeUndefined) {
// Clamp the size to the min/max size, if specified, and make sure it
// doesn't go below the padding and border amount.
- node->layout.measured_dimensions[dim[mainAxis]] = boundAxis(node, mainAxis, maxLineMainDim);
- } else if (measureModeMainDim == CSS_MEASURE_MODE_AT_MOST) {
- node->layout.measured_dimensions[dim[mainAxis]] = fmaxf(
+ node->layout.measuredDimensions[dim[mainAxis]] = boundAxis(node, mainAxis, maxLineMainDim);
+ } else if (measureModeMainDim == CSSMeasureModeAtMost) {
+ node->layout.measuredDimensions[dim[mainAxis]] = fmaxf(
fminf(availableInnerMainDim + paddingAndBorderAxisMain,
boundAxisWithinMinAndMax(node, mainAxis, maxLineMainDim)),
paddingAndBorderAxisMain);
}
- if (measureModeCrossDim == CSS_MEASURE_MODE_UNDEFINED) {
+ if (measureModeCrossDim == CSSMeasureModeUndefined) {
// Clamp the size to the min/max size, if specified, and make sure it
// doesn't go below the padding and border amount.
- node->layout.measured_dimensions[dim[crossAxis]] = boundAxis(node, crossAxis, totalLineCrossDim + paddingAndBorderAxisCross);
- } else if (measureModeCrossDim == CSS_MEASURE_MODE_AT_MOST) {
- node->layout.measured_dimensions[dim[crossAxis]] = fmaxf(
+ node->layout.measuredDimensions[dim[crossAxis]] = boundAxis(node, crossAxis, totalLineCrossDim + paddingAndBorderAxisCross);
+ } else if (measureModeCrossDim == CSSMeasureModeAtMost) {
+ node->layout.measuredDimensions[dim[crossAxis]] = fmaxf(
fminf(availableInnerCrossDim + paddingAndBorderAxisCross,
boundAxisWithinMinAndMax(node, crossAxis, totalLineCrossDim + paddingAndBorderAxisCross)),
paddingAndBorderAxisCross);
@@ -1397,20 +1397,20 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab
bool needsMainTrailingPos = false;
bool needsCrossTrailingPos = false;
- if (mainAxis == CSS_FLEX_DIRECTION_ROW_REVERSE ||
- mainAxis == CSS_FLEX_DIRECTION_COLUMN_REVERSE) {
+ if (mainAxis == CSSFlexDirectionRowReverse ||
+ mainAxis == CSSFlexDirectionColumnReverse) {
needsMainTrailingPos = true;
}
- if (crossAxis == CSS_FLEX_DIRECTION_ROW_REVERSE ||
- crossAxis == CSS_FLEX_DIRECTION_COLUMN_REVERSE) {
+ if (crossAxis == CSSFlexDirectionRowReverse ||
+ crossAxis == CSSFlexDirectionColumnReverse) {
needsCrossTrailingPos = true;
}
// Set trailing position if necessary.
if (needsMainTrailingPos || needsCrossTrailingPos) {
for (i = 0; i < childCount; ++i) {
- child = node->get_child(node->context, i);
+ child = node->getChild(node->context, i);
if (needsMainTrailingPos) {
setTrailingPosition(node, child, mainAxis);
@@ -1430,37 +1430,37 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab
// absolutely-positioned children.
if (performLayout) {
- childWidth = CSS_UNDEFINED;
- childHeight = CSS_UNDEFINED;
+ childWidth = CSSUndefined;
+ childHeight = CSSUndefined;
- if (isStyleDimDefined(currentAbsoluteChild, CSS_FLEX_DIRECTION_ROW)) {
- childWidth = currentAbsoluteChild->style.dimensions[CSS_WIDTH] + getMarginAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_ROW);
+ if (isStyleDimDefined(currentAbsoluteChild, CSSFlexDirectionRow)) {
+ childWidth = currentAbsoluteChild->style.dimensions[CSSDimensionWidth] + getMarginAxis(currentAbsoluteChild, CSSFlexDirectionRow);
} else {
// If the child doesn't have a specified width, compute the width based on the left/right offsets if they're defined.
- if (isPosDefined(currentAbsoluteChild, CSS_LEFT) && isPosDefined(currentAbsoluteChild, CSS_RIGHT)) {
- childWidth = node->layout.measured_dimensions[CSS_WIDTH] -
- (getLeadingBorder(node, CSS_FLEX_DIRECTION_ROW) + getTrailingBorder(node, CSS_FLEX_DIRECTION_ROW)) -
- (currentAbsoluteChild->style.position[CSS_LEFT] + currentAbsoluteChild->style.position[CSS_RIGHT]);
- childWidth = boundAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_ROW, childWidth);
+ if (isPosDefined(currentAbsoluteChild, CSSPositionLeft) && isPosDefined(currentAbsoluteChild, CSSPositionRight)) {
+ childWidth = node->layout.measuredDimensions[CSSDimensionWidth] -
+ (getLeadingBorder(node, CSSFlexDirectionRow) + getTrailingBorder(node, CSSFlexDirectionRow)) -
+ (currentAbsoluteChild->style.position[CSSPositionLeft] + currentAbsoluteChild->style.position[CSSPositionRight]);
+ childWidth = boundAxis(currentAbsoluteChild, CSSFlexDirectionRow, childWidth);
}
}
- if (isStyleDimDefined(currentAbsoluteChild, CSS_FLEX_DIRECTION_COLUMN)) {
- childHeight = currentAbsoluteChild->style.dimensions[CSS_HEIGHT] + getMarginAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_COLUMN);
+ if (isStyleDimDefined(currentAbsoluteChild, CSSFlexDirectionColumn)) {
+ childHeight = currentAbsoluteChild->style.dimensions[CSSDimensionHeight] + getMarginAxis(currentAbsoluteChild, CSSFlexDirectionColumn);
} else {
// If the child doesn't have a specified height, compute the height based on the top/bottom offsets if they're defined.
- if (isPosDefined(currentAbsoluteChild, CSS_TOP) && isPosDefined(currentAbsoluteChild, CSS_BOTTOM)) {
- childHeight = node->layout.measured_dimensions[CSS_HEIGHT] -
- (getLeadingBorder(node, CSS_FLEX_DIRECTION_COLUMN) + getTrailingBorder(node, CSS_FLEX_DIRECTION_COLUMN)) -
- (currentAbsoluteChild->style.position[CSS_TOP] + currentAbsoluteChild->style.position[CSS_BOTTOM]);
- childHeight = boundAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_COLUMN, childHeight);
+ if (isPosDefined(currentAbsoluteChild, CSSPositionTop) && isPosDefined(currentAbsoluteChild, CSSPositionBottom)) {
+ childHeight = node->layout.measuredDimensions[CSSDimensionHeight] -
+ (getLeadingBorder(node, CSSFlexDirectionColumn) + getTrailingBorder(node, CSSFlexDirectionColumn)) -
+ (currentAbsoluteChild->style.position[CSSPositionTop] + currentAbsoluteChild->style.position[CSSPositionBottom]);
+ childHeight = boundAxis(currentAbsoluteChild, CSSFlexDirectionColumn, childHeight);
}
}
// If we're still missing one or the other dimension, measure the content.
if (isUndefined(childWidth) || isUndefined(childHeight)) {
- childWidthMeasureMode = isUndefined(childWidth) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_EXACTLY;
- childHeightMeasureMode = isUndefined(childHeight) ? CSS_MEASURE_MODE_UNDEFINED : CSS_MEASURE_MODE_EXACTLY;
+ childWidthMeasureMode = isUndefined(childWidth) ? CSSMeasureModeUndefined : CSSMeasureModeExactly;
+ childHeightMeasureMode = isUndefined(childHeight) ? CSSMeasureModeUndefined : CSSMeasureModeExactly;
// According to the spec, if the main size is not definite and the
// child's inline axis is parallel to the main axis (i.e. it's
@@ -1468,43 +1468,43 @@ static void layoutNodeImpl(css_node_t* node, float availableWidth, float availab
// the main size. Otherwise use "AT_MOST" in the cross axis.
if (!isMainAxisRow && isUndefined(childWidth) && !isUndefined(availableInnerWidth)) {
childWidth = availableInnerWidth;
- childWidthMeasureMode = CSS_MEASURE_MODE_AT_MOST;
+ childWidthMeasureMode = CSSMeasureModeAtMost;
}
// The W3C spec doesn't say anything about the 'overflow' property,
// but all major browsers appear to implement the following logic.
- if (node->style.overflow == CSS_OVERFLOW_HIDDEN) {
+ if (node->style.overflow == CSSOverflowHidden) {
if (isMainAxisRow && isUndefined(childHeight) && !isUndefined(availableInnerHeight)) {
childHeight = availableInnerHeight;
- childHeightMeasureMode = CSS_MEASURE_MODE_AT_MOST;
+ childHeightMeasureMode = CSSMeasureModeAtMost;
}
}
layoutNodeInternal(currentAbsoluteChild, childWidth, childHeight, direction, childWidthMeasureMode, childHeightMeasureMode, false, "abs-measure");
- childWidth = currentAbsoluteChild->layout.measured_dimensions[CSS_WIDTH] + getMarginAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_ROW);
- childHeight = currentAbsoluteChild->layout.measured_dimensions[CSS_HEIGHT] + getMarginAxis(currentAbsoluteChild, CSS_FLEX_DIRECTION_COLUMN);
+ childWidth = currentAbsoluteChild->layout.measuredDimensions[CSSDimensionWidth] + getMarginAxis(currentAbsoluteChild, CSSFlexDirectionRow);
+ childHeight = currentAbsoluteChild->layout.measuredDimensions[CSSDimensionHeight] + getMarginAxis(currentAbsoluteChild, CSSFlexDirectionColumn);
}
- layoutNodeInternal(currentAbsoluteChild, childWidth, childHeight, direction, CSS_MEASURE_MODE_EXACTLY, CSS_MEASURE_MODE_EXACTLY, true, "abs-layout");
+ layoutNodeInternal(currentAbsoluteChild, childWidth, childHeight, direction, CSSMeasureModeExactly, CSSMeasureModeExactly, true, "abs-layout");
- if (isPosDefined(currentAbsoluteChild, trailing[CSS_FLEX_DIRECTION_ROW]) &&
- !isPosDefined(currentAbsoluteChild, leading[CSS_FLEX_DIRECTION_ROW])) {
- currentAbsoluteChild->layout.position[leading[CSS_FLEX_DIRECTION_ROW]] =
- node->layout.measured_dimensions[dim[CSS_FLEX_DIRECTION_ROW]] -
- currentAbsoluteChild->layout.measured_dimensions[dim[CSS_FLEX_DIRECTION_ROW]] -
- getPosition(currentAbsoluteChild, trailing[CSS_FLEX_DIRECTION_ROW]);
+ if (isPosDefined(currentAbsoluteChild, trailing[CSSFlexDirectionRow]) &&
+ !isPosDefined(currentAbsoluteChild, leading[CSSFlexDirectionRow])) {
+ currentAbsoluteChild->layout.position[leading[CSSFlexDirectionRow]] =
+ node->layout.measuredDimensions[dim[CSSFlexDirectionRow]] -
+ currentAbsoluteChild->layout.measuredDimensions[dim[CSSFlexDirectionRow]] -
+ getPosition(currentAbsoluteChild, trailing[CSSFlexDirectionRow]);
}
- if (isPosDefined(currentAbsoluteChild, trailing[CSS_FLEX_DIRECTION_COLUMN]) &&
- !isPosDefined(currentAbsoluteChild, leading[CSS_FLEX_DIRECTION_COLUMN])) {
- currentAbsoluteChild->layout.position[leading[CSS_FLEX_DIRECTION_COLUMN]] =
- node->layout.measured_dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] -
- currentAbsoluteChild->layout.measured_dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] -
- getPosition(currentAbsoluteChild, trailing[CSS_FLEX_DIRECTION_COLUMN]);
+ if (isPosDefined(currentAbsoluteChild, trailing[CSSFlexDirectionColumn]) &&
+ !isPosDefined(currentAbsoluteChild, leading[CSSFlexDirectionColumn])) {
+ currentAbsoluteChild->layout.position[leading[CSSFlexDirectionColumn]] =
+ node->layout.measuredDimensions[dim[CSSFlexDirectionColumn]] -
+ currentAbsoluteChild->layout.measuredDimensions[dim[CSSFlexDirectionColumn]] -
+ getPosition(currentAbsoluteChild, trailing[CSSFlexDirectionColumn]);
}
}
- currentAbsoluteChild = currentAbsoluteChild->next_child;
+ currentAbsoluteChild = currentAbsoluteChild->nextChild;
}
}
@@ -1523,19 +1523,19 @@ static const char* getSpacer(unsigned long level) {
return &spacer[spacerLen - level];
}
-static const char* getModeName(css_measure_mode_t mode, bool performLayout) {
- const char* kMeasureModeNames[CSS_MEASURE_MODE_COUNT] = {
+static const char* getModeName(CSSMeasureMode mode, bool performLayout) {
+ const char* kMeasureModeNames[CSSMeasureModeCount] = {
"UNDEFINED",
"EXACTLY",
"AT_MOST"
};
- const char* kLayoutModeNames[CSS_MEASURE_MODE_COUNT] = {
+ const char* kLayoutModeNames[CSSMeasureModeCount] = {
"LAY_UNDEFINED",
"LAY_EXACTLY",
"LAY_AT_MOST"
};
- if (mode >= CSS_MEASURE_MODE_COUNT) {
+ if (mode >= CSSMeasureModeCount) {
return "";
}
@@ -1543,38 +1543,38 @@ static const char* getModeName(css_measure_mode_t mode, bool performLayout) {
}
static bool canUseCachedMeasurement(
- bool is_text_node,
- float available_width,
- float available_height,
+ bool isTextNode,
+ float availableWidth,
+ float availableHeight,
float margin_row,
float margin_column,
- css_measure_mode_t width_measure_mode,
- css_measure_mode_t height_measure_mode,
- css_cached_measurement_t cached_layout) {
+ CSSMeasureMode widthMeasureMode,
+ CSSMeasureMode heightMeasureMode,
+ CSSCachedMeasurement cached_layout) {
bool is_height_same =
- (cached_layout.height_measure_mode == CSS_MEASURE_MODE_UNDEFINED && height_measure_mode == CSS_MEASURE_MODE_UNDEFINED) ||
- (cached_layout.height_measure_mode == height_measure_mode && eq(cached_layout.available_height, available_height));
+ (cached_layout.heightMeasureMode == CSSMeasureModeUndefined && heightMeasureMode == CSSMeasureModeUndefined) ||
+ (cached_layout.heightMeasureMode == heightMeasureMode && eq(cached_layout.availableHeight, availableHeight));
bool is_width_same =
- (cached_layout.width_measure_mode == CSS_MEASURE_MODE_UNDEFINED && width_measure_mode == CSS_MEASURE_MODE_UNDEFINED) ||
- (cached_layout.width_measure_mode == width_measure_mode && eq(cached_layout.available_width, available_width));
+ (cached_layout.widthMeasureMode == CSSMeasureModeUndefined && widthMeasureMode == CSSMeasureModeUndefined) ||
+ (cached_layout.widthMeasureMode == widthMeasureMode && eq(cached_layout.availableWidth, availableWidth));
if (is_height_same && is_width_same) {
return true;
}
bool is_height_valid =
- (cached_layout.height_measure_mode == CSS_MEASURE_MODE_UNDEFINED && height_measure_mode == CSS_MEASURE_MODE_AT_MOST && cached_layout.computed_height <= (available_height - margin_column)) ||
- (height_measure_mode == CSS_MEASURE_MODE_EXACTLY && eq(cached_layout.computed_height, available_height - margin_column));
+ (cached_layout.heightMeasureMode == CSSMeasureModeUndefined && heightMeasureMode == CSSMeasureModeAtMost && cached_layout.computedHeight <= (availableHeight - margin_column)) ||
+ (heightMeasureMode == CSSMeasureModeExactly && eq(cached_layout.computedHeight, availableHeight - margin_column));
if (is_width_same && is_height_valid) {
return true;
}
bool is_width_valid =
- (cached_layout.width_measure_mode == CSS_MEASURE_MODE_UNDEFINED && width_measure_mode == CSS_MEASURE_MODE_AT_MOST && cached_layout.computed_width <= (available_width - margin_row)) ||
- (width_measure_mode == CSS_MEASURE_MODE_EXACTLY && eq(cached_layout.computed_width, available_width - margin_row));
+ (cached_layout.widthMeasureMode == CSSMeasureModeUndefined && widthMeasureMode == CSSMeasureModeAtMost && cached_layout.computedWidth <= (availableWidth - margin_row)) ||
+ (widthMeasureMode == CSSMeasureModeExactly && eq(cached_layout.computedWidth, availableWidth - margin_row));
if (is_height_same && is_width_valid) {
return true;
@@ -1585,29 +1585,29 @@ static bool canUseCachedMeasurement(
}
// We know this to be text so we can apply some more specialized heuristics.
- if (is_text_node) {
+ if (isTextNode) {
if (is_width_same) {
- if (height_measure_mode == CSS_MEASURE_MODE_UNDEFINED) {
+ if (heightMeasureMode == CSSMeasureModeUndefined) {
// Width is the same and height is not restricted. Re-use cahced value.
return true;
}
- if (height_measure_mode == CSS_MEASURE_MODE_AT_MOST &&
- cached_layout.computed_height < (available_height - margin_column)) {
+ if (heightMeasureMode == CSSMeasureModeAtMost &&
+ cached_layout.computedHeight < (availableHeight - margin_column)) {
// Width is the same and height restriction is greater than the cached height. Re-use cached value.
return true;
}
// Width is the same but height restriction imposes smaller height than previously measured.
// Update the cached value to respect the new height restriction.
- cached_layout.computed_height = available_height - margin_column;
+ cached_layout.computedHeight = availableHeight - margin_column;
return true;
}
- if (cached_layout.width_measure_mode == CSS_MEASURE_MODE_UNDEFINED) {
- if (width_measure_mode == CSS_MEASURE_MODE_UNDEFINED ||
- (width_measure_mode == CSS_MEASURE_MODE_AT_MOST &&
- cached_layout.computed_width <= (available_width - margin_row))) {
+ if (cached_layout.widthMeasureMode == CSSMeasureModeUndefined) {
+ if (widthMeasureMode == CSSMeasureModeUndefined ||
+ (widthMeasureMode == CSSMeasureModeAtMost &&
+ cached_layout.computedWidth <= (availableWidth - margin_row))) {
// Previsouly this text was measured with no width restriction, if width is now restricted
// but to a larger value than the previsouly measured width we can re-use the measurement
// as we know it will fit.
@@ -1627,23 +1627,23 @@ static bool canUseCachedMeasurement(
// Input parameters are the same as layoutNodeImpl (see above)
// Return parameter is true if layout was performed, false if skipped
//
-bool layoutNodeInternal(css_node_t* node, float availableWidth, float availableHeight,
- css_direction_t parentDirection, css_measure_mode_t widthMeasureMode, css_measure_mode_t heightMeasureMode, bool performLayout, char* reason) {
- css_layout_t* layout = &node->layout;
+bool layoutNodeInternal(CSSNode* node, float availableWidth, float availableHeight,
+ CSSDirection parentDirection, CSSMeasureMode widthMeasureMode, CSSMeasureMode heightMeasureMode, bool performLayout, char* reason) {
+ CSSLayout* layout = &node->layout;
gDepth++;
- bool needToVisitNode = (node->is_dirty(node->context) && layout->generation_count != gCurrentGenerationCount) ||
- layout->last_parent_direction != parentDirection;
+ bool needToVisitNode = (node->isDirty(node->context) && layout->generationCount != gCurrentGenerationCount) ||
+ layout->lastParentDirection != parentDirection;
if (needToVisitNode) {
// Invalidate the cached results.
- layout->next_cached_measurements_index = 0;
- layout->cached_layout.width_measure_mode = (css_measure_mode_t)-1;
- layout->cached_layout.height_measure_mode = (css_measure_mode_t)-1;
+ layout->nextCachedMeasurementsIndex = 0;
+ layout->cached_layout.widthMeasureMode = (CSSMeasureMode)-1;
+ layout->cached_layout.heightMeasureMode = (CSSMeasureMode)-1;
}
- css_cached_measurement_t* cachedResults = NULL;
+ CSSCachedMeasurement* cachedResults = NULL;
// Determine whether the results are already cached. We maintain a separate
// cache for layouts and measurements. A layout operation modifies the positions
@@ -1653,47 +1653,47 @@ bool layoutNodeInternal(css_node_t* node, float availableWidth, float availableH
// We handle nodes with measure functions specially here because they are the most
// expensive to measure, so it's worth avoiding redundant measurements if at all possible.
if (isMeasureDefined(node)) {
- float marginAxisRow = getMarginAxis(node, CSS_FLEX_DIRECTION_ROW);
- float marginAxisColumn = getMarginAxis(node, CSS_FLEX_DIRECTION_COLUMN);
+ float marginAxisRow = getMarginAxis(node, CSSFlexDirectionRow);
+ float marginAxisColumn = getMarginAxis(node, CSSFlexDirectionColumn);
// First, try to use the layout cache.
- if (canUseCachedMeasurement(node->is_text_node && node->is_text_node(node->context), availableWidth, availableHeight, marginAxisRow, marginAxisColumn,
+ if (canUseCachedMeasurement(node->isTextNode && node->isTextNode(node->context), availableWidth, availableHeight, marginAxisRow, marginAxisColumn,
widthMeasureMode, heightMeasureMode, layout->cached_layout)) {
cachedResults = &layout->cached_layout;
} else {
// Try to use the measurement cache.
- for (int i = 0; i < layout->next_cached_measurements_index; i++) {
- if (canUseCachedMeasurement(node->is_text_node && node->is_text_node(node->context), availableWidth, availableHeight, marginAxisRow, marginAxisColumn,
- widthMeasureMode, heightMeasureMode, layout->cached_measurements[i])) {
- cachedResults = &layout->cached_measurements[i];
+ for (int i = 0; i < layout->nextCachedMeasurementsIndex; i++) {
+ if (canUseCachedMeasurement(node->isTextNode && node->isTextNode(node->context), availableWidth, availableHeight, marginAxisRow, marginAxisColumn,
+ widthMeasureMode, heightMeasureMode, layout->cachedMeasurements[i])) {
+ cachedResults = &layout->cachedMeasurements[i];
break;
}
}
}
} else if (performLayout) {
- if (eq(layout->cached_layout.available_width, availableWidth) &&
- eq(layout->cached_layout.available_height, availableHeight) &&
- layout->cached_layout.width_measure_mode == widthMeasureMode &&
- layout->cached_layout.height_measure_mode == heightMeasureMode) {
+ if (eq(layout->cached_layout.availableWidth, availableWidth) &&
+ eq(layout->cached_layout.availableHeight, availableHeight) &&
+ layout->cached_layout.widthMeasureMode == widthMeasureMode &&
+ layout->cached_layout.heightMeasureMode == heightMeasureMode) {
cachedResults = &layout->cached_layout;
}
} else {
- for (int i = 0; i < layout->next_cached_measurements_index; i++) {
- if (eq(layout->cached_measurements[i].available_width, availableWidth) &&
- eq(layout->cached_measurements[i].available_height, availableHeight) &&
- layout->cached_measurements[i].width_measure_mode == widthMeasureMode &&
- layout->cached_measurements[i].height_measure_mode == heightMeasureMode) {
+ for (int i = 0; i < layout->nextCachedMeasurementsIndex; i++) {
+ if (eq(layout->cachedMeasurements[i].availableWidth, availableWidth) &&
+ eq(layout->cachedMeasurements[i].availableHeight, availableHeight) &&
+ layout->cachedMeasurements[i].widthMeasureMode == widthMeasureMode &&
+ layout->cachedMeasurements[i].heightMeasureMode == heightMeasureMode) {
- cachedResults = &layout->cached_measurements[i];
+ cachedResults = &layout->cachedMeasurements[i];
break;
}
}
}
if (!needToVisitNode && cachedResults != NULL) {
- layout->measured_dimensions[CSS_WIDTH] = cachedResults->computed_width;
- layout->measured_dimensions[CSS_HEIGHT] = cachedResults->computed_height;
+ layout->measuredDimensions[CSSDimensionWidth] = cachedResults->computedWidth;
+ layout->measuredDimensions[CSSDimensionHeight] = cachedResults->computedHeight;
if (gPrintChanges && gPrintSkips) {
printf("%s%d.{[skipped] ", getSpacer(gDepth), gDepth);
@@ -1704,7 +1704,7 @@ bool layoutNodeInternal(css_node_t* node, float availableWidth, float availableH
getModeName(widthMeasureMode, performLayout),
getModeName(heightMeasureMode, performLayout),
availableWidth, availableHeight,
- cachedResults->computed_width, cachedResults->computed_height, reason);
+ cachedResults->computedWidth, cachedResults->computedHeight, reason);
}
} else {
@@ -1729,76 +1729,76 @@ bool layoutNodeInternal(css_node_t* node, float availableWidth, float availableH
printf("wm: %s, hm: %s, d: (%f, %f) %s\n",
getModeName(widthMeasureMode, performLayout),
getModeName(heightMeasureMode, performLayout),
- layout->measured_dimensions[CSS_WIDTH], layout->measured_dimensions[CSS_HEIGHT], reason);
+ layout->measuredDimensions[CSSDimensionWidth], layout->measuredDimensions[CSSDimensionHeight], reason);
}
- layout->last_parent_direction = parentDirection;
+ layout->lastParentDirection = parentDirection;
if (cachedResults == NULL) {
- if (layout->next_cached_measurements_index == CSS_MAX_CACHED_RESULT_COUNT) {
+ if (layout->nextCachedMeasurementsIndex == CSS_MAX_CACHED_RESULT_COUNT) {
if (gPrintChanges) {
printf("Out of cache entries!\n");
}
- layout->next_cached_measurements_index = 0;
+ layout->nextCachedMeasurementsIndex = 0;
}
- css_cached_measurement_t* newCacheEntry;
+ CSSCachedMeasurement* newCacheEntry;
if (performLayout) {
// Use the single layout cache entry.
newCacheEntry = &layout->cached_layout;
} else {
// Allocate a new measurement cache entry.
- newCacheEntry = &layout->cached_measurements[layout->next_cached_measurements_index];
- layout->next_cached_measurements_index++;
+ newCacheEntry = &layout->cachedMeasurements[layout->nextCachedMeasurementsIndex];
+ layout->nextCachedMeasurementsIndex++;
}
- newCacheEntry->available_width = availableWidth;
- newCacheEntry->available_height = availableHeight;
- newCacheEntry->width_measure_mode = widthMeasureMode;
- newCacheEntry->height_measure_mode = heightMeasureMode;
- newCacheEntry->computed_width = layout->measured_dimensions[CSS_WIDTH];
- newCacheEntry->computed_height = layout->measured_dimensions[CSS_HEIGHT];
+ newCacheEntry->availableWidth = availableWidth;
+ newCacheEntry->availableHeight = availableHeight;
+ newCacheEntry->widthMeasureMode = widthMeasureMode;
+ newCacheEntry->heightMeasureMode = heightMeasureMode;
+ newCacheEntry->computedWidth = layout->measuredDimensions[CSSDimensionWidth];
+ newCacheEntry->computedHeight = layout->measuredDimensions[CSSDimensionHeight];
}
}
if (performLayout) {
- node->layout.dimensions[CSS_WIDTH] = node->layout.measured_dimensions[CSS_WIDTH];
- node->layout.dimensions[CSS_HEIGHT] = node->layout.measured_dimensions[CSS_HEIGHT];
- layout->should_update = true;
+ node->layout.dimensions[CSSDimensionWidth] = node->layout.measuredDimensions[CSSDimensionWidth];
+ node->layout.dimensions[CSSDimensionHeight] = node->layout.measuredDimensions[CSSDimensionHeight];
+ layout->shouldUpdate = true;
}
gDepth--;
- layout->generation_count = gCurrentGenerationCount;
+ layout->generationCount = gCurrentGenerationCount;
return (needToVisitNode || cachedResults == NULL);
}
-void layoutNode(css_node_t* node, float availableWidth, float availableHeight, css_direction_t parentDirection) {
+void layoutNode(CSSNode* node, float availableWidth, float availableHeight, CSSDirection parentDirection) {
// Increment the generation count. This will force the recursive routine to visit
// all dirty nodes at least once. Subsequent visits will be skipped if the input
// parameters don't change.
gCurrentGenerationCount++;
- css_measure_mode_t widthMeasureMode = CSS_MEASURE_MODE_UNDEFINED;
- css_measure_mode_t heightMeasureMode = CSS_MEASURE_MODE_UNDEFINED;
+ CSSMeasureMode widthMeasureMode = CSSMeasureModeUndefined;
+ CSSMeasureMode heightMeasureMode = CSSMeasureModeUndefined;
if (!isUndefined(availableWidth)) {
- widthMeasureMode = CSS_MEASURE_MODE_EXACTLY;
- } else if (isStyleDimDefined(node, CSS_FLEX_DIRECTION_ROW)) {
- availableWidth = node->style.dimensions[dim[CSS_FLEX_DIRECTION_ROW]] + getMarginAxis(node, CSS_FLEX_DIRECTION_ROW);
- widthMeasureMode = CSS_MEASURE_MODE_EXACTLY;
- } else if (node->style.maxDimensions[CSS_WIDTH] >= 0.0) {
- availableWidth = node->style.maxDimensions[CSS_WIDTH];
- widthMeasureMode = CSS_MEASURE_MODE_AT_MOST;
+ widthMeasureMode = CSSMeasureModeExactly;
+ } else if (isStyleDimDefined(node, CSSFlexDirectionRow)) {
+ availableWidth = node->style.dimensions[dim[CSSFlexDirectionRow]] + getMarginAxis(node, CSSFlexDirectionRow);
+ widthMeasureMode = CSSMeasureModeExactly;
+ } else if (node->style.maxDimensions[CSSDimensionWidth] >= 0.0) {
+ availableWidth = node->style.maxDimensions[CSSDimensionWidth];
+ widthMeasureMode = CSSMeasureModeAtMost;
}
if (!isUndefined(availableHeight)) {
- heightMeasureMode = CSS_MEASURE_MODE_EXACTLY;
- } else if (isStyleDimDefined(node, CSS_FLEX_DIRECTION_COLUMN)) {
- availableHeight = node->style.dimensions[dim[CSS_FLEX_DIRECTION_COLUMN]] + getMarginAxis(node, CSS_FLEX_DIRECTION_COLUMN);
- heightMeasureMode = CSS_MEASURE_MODE_EXACTLY;
- } else if (node->style.maxDimensions[CSS_HEIGHT] >= 0.0) {
- availableHeight = node->style.maxDimensions[CSS_HEIGHT];
- heightMeasureMode = CSS_MEASURE_MODE_AT_MOST;
+ heightMeasureMode = CSSMeasureModeExactly;
+ } else if (isStyleDimDefined(node, CSSFlexDirectionColumn)) {
+ availableHeight = node->style.dimensions[dim[CSSFlexDirectionColumn]] + getMarginAxis(node, CSSFlexDirectionColumn);
+ heightMeasureMode = CSSMeasureModeExactly;
+ } else if (node->style.maxDimensions[CSSDimensionHeight] >= 0.0) {
+ availableHeight = node->style.maxDimensions[CSSDimensionHeight];
+ heightMeasureMode = CSSMeasureModeAtMost;
}
if (layoutNodeInternal(node, availableWidth, availableHeight, parentDirection, widthMeasureMode, heightMeasureMode, true, "initial")) {
@@ -1806,7 +1806,7 @@ void layoutNode(css_node_t* node, float availableWidth, float availableHeight, c
setPosition(node, node->layout.direction);
if (gPrintTree) {
- print_css_node(node, CSS_PRINT_LAYOUT | CSS_PRINT_CHILDREN | CSS_PRINT_STYLE);
+ CSSNodePrint(node, CSSPrintOptionsLayout | CSSPrintOptionsChildren | CSSPrintOptionsStyle);
}
}
}
diff --git a/React/CSSLayout/CSSLayout.h b/React/CSSLayout/CSSLayout.h
index 91835281b969cd..f85c72970571c1 100644
--- a/React/CSSLayout/CSSLayout.h
+++ b/React/CSSLayout/CSSLayout.h
@@ -21,132 +21,132 @@ static const unsigned long __nan[2] = {0xffffffff, 0x7fffffff};
#define NAN (*(const float *)__nan)
#endif
-#define CSS_UNDEFINED NAN
+#define CSSUndefined NAN
-#include "CSSMacros.h"
+#include
CSS_EXTERN_C_BEGIN
-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;
+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 {
- 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;
+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 {
- 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;
-
+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 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 {
- // 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 {
+typedef struct CSSLayout {
float position[4];
float dimensions[2];
- css_direction_t direction;
+ CSSDirection direction;
- float flex_basis;
+ float flexBasis;
// 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;
+ bool shouldUpdate;
+ int generationCount;
+ CSSDirection lastParentDirection;
- int next_cached_measurements_index;
- css_cached_measurement_t cached_measurements[CSS_MAX_CACHED_RESULT_COUNT];
- float measured_dimensions[2];
+ int nextCachedMeasurementsIndex;
+ CSSCachedMeasurement cachedMeasurements[CSS_MAX_CACHED_RESULT_COUNT];
+ float measuredDimensions[2];
- css_cached_measurement_t cached_layout;
-} css_layout_t;
+ CSSCachedMeasurement cached_layout;
+} CSSLayout;
-typedef struct {
+typedef struct CSSMeasureResult {
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;
+} CSSMeasureResult;
+
+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];
@@ -165,40 +165,40 @@ typedef struct {
float dimensions[2];
float minDimensions[2];
float maxDimensions[2];
-} css_style_t;
+} CSSStyle;
-typedef struct css_node css_node_t;
-struct css_node {
- css_style_t style;
- css_layout_t layout;
- int children_count;
- int line_index;
+typedef struct CSSNode {
+ CSSStyle style;
+ CSSLayout layout;
+ int childCount;
+ int lineIndex;
- css_node_t* next_child;
+ struct CSSNode* nextChild;
- css_dim_t (*measure)(void *context, float width, css_measure_mode_t widthMode, float height, css_measure_mode_t heightMode);
+ CSSMeasureResult (*measure)(void *context, float width, CSSMeasureMode widthMode, float height, CSSMeasureMode 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);
+ struct CSSNode* (*getChild)(void *context, int i);
+ bool (*isDirty)(void *context);
+ bool (*isTextNode)(void *context);
void *context;
-};
+} CSSNode;
// 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);
+CSSNode *CSSNodeNew();
+void CSSNodeInit(CSSNode *node);
+void CSSNodeFree(CSSNode *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);
+typedef enum CSSPrintOptions {
+ CSSPrintOptionsLayout = 1,
+ CSSPrintOptionsStyle = 2,
+ CSSPrintOptionsChildren = 4,
+} CSSPrintOptions;
+
+void CSSNodePrint(CSSNode *node, CSSPrintOptions options);
// Function that computes the layout!
-void layoutNode(css_node_t *node, float availableWidth, float availableHeight, css_direction_t parentDirection);
+void layoutNode(CSSNode *node, float availableWidth, float availableHeight, CSSDirection parentDirection);
bool isUndefined(float value);
CSS_EXTERN_C_END
diff --git a/React/Views/RCTRootShadowView.m b/React/Views/RCTRootShadowView.m
index e012358966aa37..d6d8cfe270b542 100644
--- a/React/Views/RCTRootShadowView.m
+++ b/React/Views/RCTRootShadowView.m
@@ -21,7 +21,7 @@ - (instancetype)init
self = [super init];
if (self) {
if ([[RCTI18nUtil sharedInstance] isRTL]) {
- self.cssNode->style.direction = CSS_DIRECTION_RTL;
+ self.cssNode->style.direction = CSSDirectionRTL;
}
}
return self;
@@ -33,14 +33,14 @@ - (void)applySizeConstraints
case RCTRootViewSizeFlexibilityNone:
break;
case RCTRootViewSizeFlexibilityWidth:
- self.cssNode->style.dimensions[CSS_WIDTH] = CSS_UNDEFINED;
+ self.cssNode->style.dimensions[CSSDimensionWidth] = CSSUndefined;
break;
case RCTRootViewSizeFlexibilityHeight:
- self.cssNode->style.dimensions[CSS_HEIGHT] = CSS_UNDEFINED;
+ self.cssNode->style.dimensions[CSSDimensionHeight] = CSSUndefined;
break;
case RCTRootViewSizeFlexibilityWidthAndHeight:
- self.cssNode->style.dimensions[CSS_WIDTH] = CSS_UNDEFINED;
- self.cssNode->style.dimensions[CSS_HEIGHT] = CSS_UNDEFINED;
+ self.cssNode->style.dimensions[CSSDimensionWidth] = CSSUndefined;
+ self.cssNode->style.dimensions[CSSDimensionHeight] = CSSUndefined;
break;
}
}
@@ -49,8 +49,7 @@ - (void)applySizeConstraints
{
[self applySizeConstraints];
- [self fillCSSNode:self.cssNode];
- layoutNode(self.cssNode, CSS_UNDEFINED, CSS_UNDEFINED, CSS_DIRECTION_INHERIT);
+ layoutNode(self.cssNode, CSSUndefined, CSSUndefined, CSSDirectionInherit);
NSMutableSet *viewsWithNewFrame = [NSMutableSet set];
[self applyLayoutNode:self.cssNode viewsWithNewFrame:viewsWithNewFrame absolutePosition:CGPointZero];
diff --git a/React/Views/RCTShadowView.h b/React/Views/RCTShadowView.h
index b76e3000da95c0..454a8e8e406492 100644
--- a/React/Views/RCTShadowView.h
+++ b/React/Views/RCTShadowView.h
@@ -44,7 +44,7 @@ typedef void (^RCTApplierBlock)(NSDictionary *viewRegistry
- (void)removeReactSubview:(RCTShadowView *)subview NS_REQUIRES_SUPER;
@property (nonatomic, weak, readonly) RCTShadowView *superview;
-@property (nonatomic, assign, readonly) css_node_t *cssNode;
+@property (nonatomic, assign, readonly) CSSNode *cssNode;
@property (nonatomic, copy) NSString *viewName;
@property (nonatomic, strong) UIColor *backgroundColor; // Used to propagate to children
@property (nonatomic, assign) RCTUpdateLifecycle layoutLifecycle;
@@ -127,12 +127,12 @@ typedef void (^RCTApplierBlock)(NSDictionary *viewRegistry
/**
* Flexbox properties. All zero/disabled by default
*/
-@property (nonatomic, assign) css_flex_direction_t flexDirection;
-@property (nonatomic, assign) css_justify_t justifyContent;
-@property (nonatomic, assign) css_align_t alignSelf;
-@property (nonatomic, assign) css_align_t alignItems;
-@property (nonatomic, assign) css_position_type_t position;
-@property (nonatomic, assign) css_wrap_type_t flexWrap;
+@property (nonatomic, assign) CSSFlexDirection flexDirection;
+@property (nonatomic, assign) CSSJustify justifyContent;
+@property (nonatomic, assign) CSSAlign alignSelf;
+@property (nonatomic, assign) CSSAlign alignItems;
+@property (nonatomic, assign) CSSPositionType position;
+@property (nonatomic, assign) CSSWrapType flexWrap;
@property (nonatomic, assign) CGFloat flex;
/**
@@ -172,24 +172,30 @@ typedef void (^RCTApplierBlock)(NSDictionary *viewRegistry
* is split into two methods so subclasses can override `applyLayoutToChildren:`
* while using default implementation of `applyLayoutNode:`.
*/
-- (void)applyLayoutNode:(css_node_t *)node
+- (void)applyLayoutNode:(CSSNode *)node
viewsWithNewFrame:(NSMutableSet *)viewsWithNewFrame
absolutePosition:(CGPoint)absolutePosition NS_REQUIRES_SUPER;
/**
* Enumerate the child nodes and tell them to apply layout.
*/
-- (void)applyLayoutToChildren:(css_node_t *)node
+- (void)applyLayoutToChildren:(CSSNode *)node
viewsWithNewFrame:(NSMutableSet *)viewsWithNewFrame
absolutePosition:(CGPoint)absolutePosition;
/**
* The following are implementation details exposed to subclasses. Do not call them directly
*/
-- (void)fillCSSNode:(css_node_t *)node NS_REQUIRES_SUPER;
- (void)dirtyLayout NS_REQUIRES_SUPER;
- (BOOL)isLayoutDirty;
+/**
+ * Return whether or not this node acts as a leaf node in the eyes of CSSLayout. For example
+ * RCTShadowText has children which it does not want CSSLayout to lay out so in the eyes of
+ * CSSLayout it is a leaf node.
+ */
+- (BOOL)isCSSLeafNode;
+
- (void)dirtyPropagation NS_REQUIRES_SUPER;
- (BOOL)isPropagationDirty;
diff --git a/React/Views/RCTShadowView.m b/React/Views/RCTShadowView.m
index 2ff78efc187a2e..4dd78a1cbff057 100644
--- a/React/Views/RCTShadowView.m
+++ b/React/Views/RCTShadowView.m
@@ -48,7 +48,7 @@ @implementation RCTShadowView
@synthesize reactTag = _reactTag;
-// css_node api
+// cssNode api
static void RCTPrint(void *context)
{
@@ -56,7 +56,7 @@ static void RCTPrint(void *context)
printf("%s(%zd), ", shadowView.viewName.UTF8String, shadowView.reactTag.integerValue);
}
-static css_node_t *RCTGetChild(void *context, int i)
+static CSSNode *RCTGetChild(void *context, int i)
{
RCTShadowView *shadowView = (__bridge RCTShadowView *)context;
RCTShadowView *child = [shadowView reactSubviews][i];
@@ -70,30 +70,25 @@ static bool RCTIsDirty(void *context)
}
// Enforces precedence rules, e.g. marginLeft > marginHorizontal > margin.
-static void RCTProcessMetaProps(const float metaProps[META_PROP_COUNT], float style[CSS_POSITION_COUNT]) {
- style[CSS_LEFT] = !isUndefined(metaProps[META_PROP_LEFT]) ? metaProps[META_PROP_LEFT]
+static void RCTProcessMetaProps(const float metaProps[META_PROP_COUNT], float style[CSSPositionCount]) {
+ style[CSSPositionLeft] = !isUndefined(metaProps[META_PROP_LEFT]) ? metaProps[META_PROP_LEFT]
: !isUndefined(metaProps[META_PROP_HORIZONTAL]) ? metaProps[META_PROP_HORIZONTAL]
: !isUndefined(metaProps[META_PROP_ALL]) ? metaProps[META_PROP_ALL]
: 0;
- style[CSS_RIGHT] = !isUndefined(metaProps[META_PROP_RIGHT]) ? metaProps[META_PROP_RIGHT]
+ style[CSSPositionRight] = !isUndefined(metaProps[META_PROP_RIGHT]) ? metaProps[META_PROP_RIGHT]
: !isUndefined(metaProps[META_PROP_HORIZONTAL]) ? metaProps[META_PROP_HORIZONTAL]
: !isUndefined(metaProps[META_PROP_ALL]) ? metaProps[META_PROP_ALL]
: 0;
- style[CSS_TOP] = !isUndefined(metaProps[META_PROP_TOP]) ? metaProps[META_PROP_TOP]
+ style[CSSPositionTop] = !isUndefined(metaProps[META_PROP_TOP]) ? metaProps[META_PROP_TOP]
: !isUndefined(metaProps[META_PROP_VERTICAL]) ? metaProps[META_PROP_VERTICAL]
: !isUndefined(metaProps[META_PROP_ALL]) ? metaProps[META_PROP_ALL]
: 0;
- style[CSS_BOTTOM] = !isUndefined(metaProps[META_PROP_BOTTOM]) ? metaProps[META_PROP_BOTTOM]
+ style[CSSPositionBottom] = !isUndefined(metaProps[META_PROP_BOTTOM]) ? metaProps[META_PROP_BOTTOM]
: !isUndefined(metaProps[META_PROP_VERTICAL]) ? metaProps[META_PROP_VERTICAL]
: !isUndefined(metaProps[META_PROP_ALL]) ? metaProps[META_PROP_ALL]
: 0;
}
-- (void)fillCSSNode:(css_node_t *)node
-{
- node->children_count = (int)_reactSubviews.count;
-}
-
// The absolute stuff is so that we can take into account our absolute position when rounding in order to
// snap to the pixel grid. For example, say you have the following structure:
//
@@ -123,29 +118,29 @@ - (void)fillCSSNode:(css_node_t *)node
// width = 213.5 - 106.5 = 107
// You'll notice that this is the same width we calculated for the parent view because we've taken its position into account.
-- (void)applyLayoutNode:(css_node_t *)node
+- (void)applyLayoutNode:(CSSNode *)node
viewsWithNewFrame:(NSMutableSet *)viewsWithNewFrame
absolutePosition:(CGPoint)absolutePosition
{
- if (!node->layout.should_update) {
+ if (!node->layout.shouldUpdate) {
return;
}
- node->layout.should_update = false;
+ node->layout.shouldUpdate = false;
_layoutLifecycle = RCTUpdateLifecycleComputed;
CGPoint absoluteTopLeft = {
- absolutePosition.x + node->layout.position[CSS_LEFT],
- absolutePosition.y + node->layout.position[CSS_TOP]
+ absolutePosition.x + node->layout.position[CSSPositionLeft],
+ absolutePosition.y + node->layout.position[CSSPositionTop]
};
CGPoint absoluteBottomRight = {
- absolutePosition.x + node->layout.position[CSS_LEFT] + node->layout.dimensions[CSS_WIDTH],
- absolutePosition.y + node->layout.position[CSS_TOP] + node->layout.dimensions[CSS_HEIGHT]
+ absolutePosition.x + node->layout.position[CSSPositionLeft] + node->layout.dimensions[CSSDimensionWidth],
+ absolutePosition.y + node->layout.position[CSSPositionTop] + node->layout.dimensions[CSSDimensionHeight]
};
CGRect frame = {{
- RCTRoundPixelValue(node->layout.position[CSS_LEFT]),
- RCTRoundPixelValue(node->layout.position[CSS_TOP]),
+ RCTRoundPixelValue(node->layout.position[CSSPositionLeft]),
+ RCTRoundPixelValue(node->layout.position[CSSPositionTop]),
}, {
RCTRoundPixelValue(absoluteBottomRight.x - absoluteTopLeft.x),
RCTRoundPixelValue(absoluteBottomRight.y - absoluteTopLeft.y)
@@ -156,19 +151,19 @@ - (void)applyLayoutNode:(css_node_t *)node
[viewsWithNewFrame addObject:self];
}
- absolutePosition.x += node->layout.position[CSS_LEFT];
- absolutePosition.y += node->layout.position[CSS_TOP];
+ absolutePosition.x += node->layout.position[CSSPositionLeft];
+ absolutePosition.y += node->layout.position[CSSPositionTop];
[self applyLayoutToChildren:node viewsWithNewFrame:viewsWithNewFrame absolutePosition:absolutePosition];
}
-- (void)applyLayoutToChildren:(css_node_t *)node
+- (void)applyLayoutToChildren:(CSSNode *)node
viewsWithNewFrame:(NSMutableSet *)viewsWithNewFrame
absolutePosition:(CGPoint)absolutePosition
{
- for (int i = 0; i < node->children_count; ++i) {
+ for (int i = 0; i < node->childCount; ++i) {
RCTShadowView *child = (RCTShadowView *)_reactSubviews[i];
- [child applyLayoutNode:node->get_child(node->context, i)
+ [child applyLayoutNode:node->getChild(node->context, i)
viewsWithNewFrame:viewsWithNewFrame
absolutePosition:absolutePosition];
}
@@ -242,19 +237,18 @@ - (void)collectUpdatedFrames:(NSMutableSet *)viewsWithNewFrame
}
if (!CGRectEqualToRect(frame, _frame)) {
- _cssNode->style.position_type = CSS_POSITION_ABSOLUTE;
- _cssNode->style.dimensions[CSS_WIDTH] = frame.size.width;
- _cssNode->style.dimensions[CSS_HEIGHT] = frame.size.height;
- _cssNode->style.position[CSS_LEFT] = frame.origin.x;
- _cssNode->style.position[CSS_TOP] = frame.origin.y;
+ _cssNode->style.positionType = CSSPositionTypeAbsolute;
+ _cssNode->style.dimensions[CSSDimensionWidth] = frame.size.width;
+ _cssNode->style.dimensions[CSSDimensionHeight] = frame.size.height;
+ _cssNode->style.position[CSSPositionLeft] = frame.origin.x;
+ _cssNode->style.position[CSSPositionTop] = frame.origin.y;
// Our parent has asked us to change our cssNode->styles. Dirty the layout
// so that we can rerun layout on this node. The request came from our parent
// so there's no need to dirty our ancestors by calling dirtyLayout.
_layoutLifecycle = RCTUpdateLifecycleDirtied;
}
- [self fillCSSNode:_cssNode];
- layoutNode(_cssNode, frame.size.width, frame.size.height, CSS_DIRECTION_INHERIT);
+ layoutNode(_cssNode, frame.size.width, frame.size.height, CSSDirectionInherit);
[self applyLayoutNode:_cssNode viewsWithNewFrame:viewsWithNewFrame absolutePosition:absolutePosition];
}
@@ -279,12 +273,12 @@ - (instancetype)init
{
if ((self = [super init])) {
- _frame = CGRectMake(0, 0, CSS_UNDEFINED, CSS_UNDEFINED);
+ _frame = CGRectMake(0, 0, CSSUndefined, CSSUndefined);
for (unsigned int ii = 0; ii < META_PROP_COUNT; ii++) {
- _paddingMetaProps[ii] = CSS_UNDEFINED;
- _marginMetaProps[ii] = CSS_UNDEFINED;
- _borderMetaProps[ii] = CSS_UNDEFINED;
+ _paddingMetaProps[ii] = CSSUndefined;
+ _marginMetaProps[ii] = CSSUndefined;
+ _borderMetaProps[ii] = CSSUndefined;
}
_newView = YES;
@@ -294,12 +288,11 @@ - (instancetype)init
_reactSubviews = [NSMutableArray array];
- _cssNode = new_css_node();
+ _cssNode = CSSNodeNew();
_cssNode->context = (__bridge void *)self;
_cssNode->print = RCTPrint;
- _cssNode->get_child = RCTGetChild;
- _cssNode->is_dirty = RCTIsDirty;
- [self fillCSSNode:_cssNode];
+ _cssNode->getChild = RCTGetChild;
+ _cssNode->isDirty = RCTIsDirty;
}
return self;
}
@@ -311,7 +304,7 @@ - (BOOL)isReactRootView
- (void)dealloc
{
- free_css_node(_cssNode);
+ CSSNodeFree(_cssNode);
}
- (void)dirtyLayout
@@ -327,6 +320,11 @@ - (BOOL)isLayoutDirty
return _layoutLifecycle != RCTUpdateLifecycleComputed;
}
+- (BOOL)isCSSLeafNode
+{
+ return NO;
+}
+
- (void)dirtyPropagation
{
if (_propagationLifecycle != RCTUpdateLifecycleDirtied) {
@@ -361,7 +359,7 @@ - (void)setTextComputed
- (void)insertReactSubview:(RCTShadowView *)subview atIndex:(NSInteger)atIndex
{
[_reactSubviews insertObject:subview atIndex:atIndex];
- _cssNode->children_count = (int)_reactSubviews.count;
+ _cssNode->childCount = [self isCSSLeafNode] ? 0 : (int)_reactSubviews.count;
subview->_superview = self;
_didUpdateSubviews = YES;
[self dirtyText];
@@ -377,7 +375,7 @@ - (void)removeReactSubview:(RCTShadowView *)subview
_didUpdateSubviews = YES;
subview->_superview = nil;
[_reactSubviews removeObject:subview];
- _cssNode->children_count = (int)_reactSubviews.count;
+ _cssNode->childCount = [self isCSSLeafNode] ? 0 : (int)_reactSubviews.count;
}
- (NSArray *)reactSubviews
@@ -477,10 +475,10 @@ - (CGFloat)padding##prop \
- (UIEdgeInsets)paddingAsInsets
{
return (UIEdgeInsets){
- _cssNode->style.padding[CSS_TOP],
- _cssNode->style.padding[CSS_LEFT],
- _cssNode->style.padding[CSS_BOTTOM],
- _cssNode->style.padding[CSS_RIGHT]
+ _cssNode->style.padding[CSSPositionTop],
+ _cssNode->style.padding[CSSPositionLeft],
+ _cssNode->style.padding[CSSPositionBottom],
+ _cssNode->style.padding[CSSPositionRight]
};
}
@@ -509,47 +507,47 @@ - (CGFloat)border##prop##Width \
#define RCT_DIMENSION_PROPERTY(setProp, getProp, cssProp, category) \
- (void)set##setProp:(CGFloat)value \
{ \
- _cssNode->style.category[CSS_##cssProp] = value; \
+ _cssNode->style.category[CSS##cssProp] = value; \
[self dirtyLayout]; \
[self dirtyText]; \
} \
- (CGFloat)getProp \
{ \
- return _cssNode->style.category[CSS_##cssProp]; \
+ return _cssNode->style.category[CSS##cssProp]; \
}
-RCT_DIMENSION_PROPERTY(Width, width, WIDTH, dimensions)
-RCT_DIMENSION_PROPERTY(Height, height, HEIGHT, dimensions)
+RCT_DIMENSION_PROPERTY(Width, width, DimensionWidth, dimensions)
+RCT_DIMENSION_PROPERTY(Height, height, DimensionHeight, dimensions)
-RCT_DIMENSION_PROPERTY(MinWidth, minWidth, WIDTH, minDimensions)
-RCT_DIMENSION_PROPERTY(MaxWidth, maxWidth, WIDTH, maxDimensions)
-RCT_DIMENSION_PROPERTY(MinHeight, minHeight, HEIGHT, minDimensions)
-RCT_DIMENSION_PROPERTY(MaxHeight, maxHeight, HEIGHT, maxDimensions)
+RCT_DIMENSION_PROPERTY(MinWidth, minWidth, DimensionWidth, minDimensions)
+RCT_DIMENSION_PROPERTY(MaxWidth, maxWidth, DimensionWidth, maxDimensions)
+RCT_DIMENSION_PROPERTY(MinHeight, minHeight, DimensionHeight, minDimensions)
+RCT_DIMENSION_PROPERTY(MaxHeight, maxHeight, DimensionHeight, maxDimensions)
// Position
#define RCT_POSITION_PROPERTY(setProp, getProp, cssProp) \
RCT_DIMENSION_PROPERTY(setProp, getProp, cssProp, position)
-RCT_POSITION_PROPERTY(Top, top, TOP)
-RCT_POSITION_PROPERTY(Right, right, RIGHT)
-RCT_POSITION_PROPERTY(Bottom, bottom, BOTTOM)
-RCT_POSITION_PROPERTY(Left, left, LEFT)
+RCT_POSITION_PROPERTY(Top, top, PositionTop)
+RCT_POSITION_PROPERTY(Right, right, PositionRight)
+RCT_POSITION_PROPERTY(Bottom, bottom, PositionBottom)
+RCT_POSITION_PROPERTY(Left, left, PositionLeft)
- (void)setFrame:(CGRect)frame
{
- _cssNode->style.position[CSS_LEFT] = CGRectGetMinX(frame);
- _cssNode->style.position[CSS_TOP] = CGRectGetMinY(frame);
- _cssNode->style.dimensions[CSS_WIDTH] = CGRectGetWidth(frame);
- _cssNode->style.dimensions[CSS_HEIGHT] = CGRectGetHeight(frame);
+ _cssNode->style.position[CSSPositionLeft] = CGRectGetMinX(frame);
+ _cssNode->style.position[CSSPositionTop] = CGRectGetMinY(frame);
+ _cssNode->style.dimensions[CSSDimensionWidth] = CGRectGetWidth(frame);
+ _cssNode->style.dimensions[CSSDimensionHeight] = CGRectGetHeight(frame);
[self dirtyLayout];
}
-static inline BOOL RCTAssignSuggestedDimension(css_node_t *css_node, int dimension, CGFloat amount)
+static inline BOOL RCTAssignSuggestedDimension(CSSNode *cssNode, int dimension, CGFloat amount)
{
if (amount != UIViewNoIntrinsicMetric
- && isnan(css_node->style.dimensions[dimension])) {
- css_node->style.dimensions[dimension] = amount;
+ && isnan(cssNode->style.dimensions[dimension])) {
+ cssNode->style.dimensions[dimension] = amount;
return YES;
}
return NO;
@@ -559,8 +557,8 @@ - (void)setIntrinsicContentSize:(CGSize)size
{
if (_cssNode->style.flex == 0) {
BOOL dirty = NO;
- dirty |= RCTAssignSuggestedDimension(_cssNode, CSS_HEIGHT, size.height);
- dirty |= RCTAssignSuggestedDimension(_cssNode, CSS_WIDTH, size.width);
+ dirty |= RCTAssignSuggestedDimension(_cssNode, CSSDimensionHeight, size.height);
+ dirty |= RCTAssignSuggestedDimension(_cssNode, CSSDimensionWidth, size.width);
if (dirty) {
[self dirtyLayout];
}
@@ -569,15 +567,15 @@ - (void)setIntrinsicContentSize:(CGSize)size
- (void)setTopLeft:(CGPoint)topLeft
{
- _cssNode->style.position[CSS_LEFT] = topLeft.x;
- _cssNode->style.position[CSS_TOP] = topLeft.y;
+ _cssNode->style.position[CSSPositionLeft] = topLeft.x;
+ _cssNode->style.position[CSSPositionTop] = topLeft.y;
[self dirtyLayout];
}
- (void)setSize:(CGSize)size
{
- _cssNode->style.dimensions[CSS_WIDTH] = size.width;
- _cssNode->style.dimensions[CSS_HEIGHT] = size.height;
+ _cssNode->style.dimensions[CSSDimensionWidth] = size.width;
+ _cssNode->style.dimensions[CSSDimensionHeight] = size.height;
[self dirtyLayout];
}
@@ -595,12 +593,12 @@ - (type)getProp \
}
RCT_STYLE_PROPERTY(Flex, flex, flex, CGFloat)
-RCT_STYLE_PROPERTY(FlexDirection, flexDirection, flex_direction, css_flex_direction_t)
-RCT_STYLE_PROPERTY(JustifyContent, justifyContent, justify_content, css_justify_t)
-RCT_STYLE_PROPERTY(AlignSelf, alignSelf, align_self, css_align_t)
-RCT_STYLE_PROPERTY(AlignItems, alignItems, align_items, css_align_t)
-RCT_STYLE_PROPERTY(Position, position, position_type, css_position_type_t)
-RCT_STYLE_PROPERTY(FlexWrap, flexWrap, flex_wrap, css_wrap_type_t)
+RCT_STYLE_PROPERTY(FlexDirection, flexDirection, flexDirection, CSSFlexDirection)
+RCT_STYLE_PROPERTY(JustifyContent, justifyContent, justifyContent, CSSJustify)
+RCT_STYLE_PROPERTY(AlignSelf, alignSelf, alignSelf, CSSAlign)
+RCT_STYLE_PROPERTY(AlignItems, alignItems, alignItems, CSSAlign)
+RCT_STYLE_PROPERTY(Position, position, positionType, CSSPositionType)
+RCT_STYLE_PROPERTY(FlexWrap, flexWrap, flexWrap, CSSWrapType)
- (void)setBackgroundColor:(UIColor *)color
{
@@ -637,7 +635,6 @@ - (void)didSetProps:(__unused NSArray *)changedProps
if (_recomputePadding || _recomputeMargin || _recomputeBorder) {
[self dirtyLayout];
}
- [self fillCSSNode:_cssNode];
_recomputeMargin = NO;
_recomputePadding = NO;
_recomputeBorder = NO;
diff --git a/React/Views/RCTViewManager.m b/React/Views/RCTViewManager.m
index 4b6cb0a0e4d78a..d14cc32a90671c 100644
--- a/React/Views/RCTViewManager.m
+++ b/React/Views/RCTViewManager.m
@@ -288,12 +288,12 @@ - (RCTViewManagerUIBlock)uiBlockToAmendWithShadowViewRegistry:(__unused NSDictio
RCT_EXPORT_SHADOW_PROPERTY(padding, CGFloat)
RCT_EXPORT_SHADOW_PROPERTY(flex, CGFloat)
-RCT_EXPORT_SHADOW_PROPERTY(flexDirection, css_flex_direction_t)
-RCT_EXPORT_SHADOW_PROPERTY(flexWrap, css_wrap_type_t)
-RCT_EXPORT_SHADOW_PROPERTY(justifyContent, css_justify_t)
-RCT_EXPORT_SHADOW_PROPERTY(alignItems, css_align_t)
-RCT_EXPORT_SHADOW_PROPERTY(alignSelf, css_align_t)
-RCT_EXPORT_SHADOW_PROPERTY(position, css_position_type_t)
+RCT_EXPORT_SHADOW_PROPERTY(flexDirection, CSSFlexDirection)
+RCT_EXPORT_SHADOW_PROPERTY(flexWrap, CSSWrapType)
+RCT_EXPORT_SHADOW_PROPERTY(justifyContent, CSSJustify)
+RCT_EXPORT_SHADOW_PROPERTY(alignItems, CSSAlign)
+RCT_EXPORT_SHADOW_PROPERTY(alignSelf, CSSAlign)
+RCT_EXPORT_SHADOW_PROPERTY(position, CSSPositionType)
RCT_EXPORT_SHADOW_PROPERTY(onLayout, RCTDirectEventBlock)
diff --git a/ReactAndroid/build.gradle b/ReactAndroid/build.gradle
index 7a142cefe04c2c..52dd2258899967 100644
--- a/ReactAndroid/build.gradle
+++ b/ReactAndroid/build.gradle
@@ -269,10 +269,10 @@ dependencies {
compile 'com.facebook.soloader:soloader:0.1.0'
compile 'com.fasterxml.jackson.core:jackson-core:2.2.3'
compile 'com.google.code.findbugs:jsr305:3.0.0'
- compile 'com.squareup.okhttp3:okhttp:3.2.0'
- compile 'com.squareup.okhttp3:okhttp-urlconnection:3.2.0'
- compile 'com.squareup.okhttp3:okhttp-ws:3.2.0'
- compile 'com.squareup.okio:okio:1.8.0'
+ compile 'com.squareup.okhttp3:okhttp:3.4.1'
+ compile 'com.squareup.okhttp3:okhttp-urlconnection:3.4.1'
+ compile 'com.squareup.okhttp3:okhttp-ws:3.4.1'
+ compile 'com.squareup.okio:okio:1.9.0'
compile 'org.webkit:android-jsc:r174650'
testCompile "junit:junit:${JUNIT_VERSION}"
diff --git a/ReactAndroid/src/androidTest/java/com/facebook/react/tests/BUCK b/ReactAndroid/src/androidTest/java/com/facebook/react/tests/BUCK
index f052dc129744b9..b9ba1265462874 100644
--- a/ReactAndroid/src/androidTest/java/com/facebook/react/tests/BUCK
+++ b/ReactAndroid/src/androidTest/java/com/facebook/react/tests/BUCK
@@ -3,7 +3,6 @@ include_defs('//ReactAndroid/DEFS')
# Tests that are too flaky to run on SandCastle
# TODO t11057216 stabilise them
SANDCASTLE_FLAKY = [
- 'ReactScrollViewTestCase.java',
]
deps = [
diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/toast/ToastModule.java b/ReactAndroid/src/main/java/com/facebook/react/modules/toast/ToastModule.java
index af128a96149532..243c917a6fe207 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/modules/toast/ToastModule.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/modules/toast/ToastModule.java
@@ -9,11 +9,11 @@
package com.facebook.react.modules.toast;
+import android.view.Gravity;
import android.widget.Toast;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
-import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.common.MapBuilder;
@@ -29,6 +29,10 @@ public class ToastModule extends ReactContextBaseJavaModule {
private static final String DURATION_SHORT_KEY = "SHORT";
private static final String DURATION_LONG_KEY = "LONG";
+ private static final String GRAVITY_TOP_KEY = "TOP";
+ private static final String GRAVITY_BOTTOM_KEY = "BOTTOM";
+ private static final String GRAVITY_CENTER = "CENTER";
+
public ToastModule(ReactApplicationContext reactContext) {
super(reactContext);
}
@@ -43,6 +47,9 @@ public Map getConstants() {
final Map constants = MapBuilder.newHashMap();
constants.put(DURATION_SHORT_KEY, Toast.LENGTH_SHORT);
constants.put(DURATION_LONG_KEY, Toast.LENGTH_LONG);
+ constants.put(GRAVITY_TOP_KEY, Gravity.TOP | Gravity.CENTER_HORIZONTAL);
+ constants.put(GRAVITY_BOTTOM_KEY, Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL);
+ constants.put(GRAVITY_CENTER, Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL);
return constants;
}
@@ -50,9 +57,21 @@ public Map getConstants() {
public void show(final String message, final int duration) {
UiThreadUtil.runOnUiThread(new Runnable() {
@Override
- public void run(){
+ public void run() {
Toast.makeText(getReactApplicationContext(), message, duration).show();
}
});
}
+
+ @ReactMethod
+ public void showWithGravity(final String message, final int duration, final int gravity) {
+ UiThreadUtil.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ Toast toast = Toast.makeText(getReactApplicationContext(), message, duration);
+ toast.setGravity(gravity, 0, 0);
+ toast.show();
+ }
+ });
+ }
}
diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyOptimizer.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyOptimizer.java
index 7b9741bd8ddbd5..2d921bb0f1c230 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyOptimizer.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyOptimizer.java
@@ -52,6 +52,16 @@
*/
public class NativeViewHierarchyOptimizer {
+ private static class NodeIndexPair {
+ public final ReactShadowNode node;
+ public final int index;
+
+ NodeIndexPair(ReactShadowNode node, int index) {
+ this.node = node;
+ this.index = index;
+ }
+ }
+
private static final boolean ENABLED = true;
private final UIViewOperationQueue mUIViewOperationQueue;
@@ -221,21 +231,39 @@ public void onBatchComplete() {
mTagsWithLayoutVisited.clear();
}
+ private NodeIndexPair walkUpUntilNonLayoutOnly(
+ ReactShadowNode node,
+ int indexInNativeChildren) {
+ while (node.isLayoutOnly()) {
+ ReactShadowNode parent = node.getParent();
+ if (parent == null) {
+ return null;
+ }
+
+ indexInNativeChildren = indexInNativeChildren + parent.getNativeOffsetForChild(node);
+ node = parent;
+ }
+
+ return new NodeIndexPair(node, indexInNativeChildren);
+ }
+
private void addNodeToNode(ReactShadowNode parent, ReactShadowNode child, int index) {
int indexInNativeChildren = parent.getNativeOffsetForChild(parent.getChildAt(index));
- boolean parentIsLayoutOnly = parent.isLayoutOnly();
- boolean childIsLayoutOnly = child.isLayoutOnly();
-
- // Switch on the four cases of:
- // add (layout-only|not layout-only) to (layout-only|not layout-only)
- if (!parentIsLayoutOnly && !childIsLayoutOnly) {
- addNonLayoutNodeToNonLayoutNode(parent, child, indexInNativeChildren);
- } else if (!childIsLayoutOnly) {
- addNonLayoutOnlyNodeToLayoutOnlyNode(parent, child, indexInNativeChildren);
- } else if (!parentIsLayoutOnly) {
- addLayoutOnlyNodeToNonLayoutOnlyNode(parent, child, indexInNativeChildren);
+ if (parent.isLayoutOnly()) {
+ NodeIndexPair result = walkUpUntilNonLayoutOnly(parent, indexInNativeChildren);
+ if (result == null) {
+ // If the parent hasn't been attached to its native parent yet, don't issue commands to the
+ // native hierarchy. We'll do that when the parent node actually gets attached somewhere.
+ return;
+ }
+ parent = result.node;
+ indexInNativeChildren = result.index;
+ }
+
+ if (!child.isLayoutOnly()) {
+ addNonLayoutNode(parent, child, indexInNativeChildren);
} else {
- addLayoutOnlyNodeToLayoutOnlyNode(parent, child, indexInNativeChildren);
+ addLayoutOnlyNode(parent, child, indexInNativeChildren);
}
}
@@ -262,73 +290,14 @@ private void removeNodeFromParent(ReactShadowNode nodeToRemove, boolean shouldDe
}
}
- private void addLayoutOnlyNodeToLayoutOnlyNode(
- ReactShadowNode parent,
- ReactShadowNode child,
- int index) {
- ReactShadowNode parentParent = parent.getParent();
-
- // If the parent hasn't been attached to its parent yet, don't issue commands to the native
- // hierarchy. We'll do that when the parent node actually gets attached somewhere.
- if (parentParent == null) {
- return;
- }
-
- int transformedIndex = index + parentParent.getNativeOffsetForChild(parent);
- if (parentParent.isLayoutOnly()) {
- addLayoutOnlyNodeToLayoutOnlyNode(parentParent, child, transformedIndex);
- } else {
- addLayoutOnlyNodeToNonLayoutOnlyNode(parentParent, child, transformedIndex);
- }
- }
-
- private void addNonLayoutOnlyNodeToLayoutOnlyNode(
- ReactShadowNode layoutOnlyNode,
- ReactShadowNode nonLayoutOnlyNode,
- int index) {
- ReactShadowNode parent = layoutOnlyNode.getParent();
-
- // If the parent hasn't been attached to its parent yet, don't issue commands to the native
- // hierarchy. We'll do that when the parent node actually gets attached somewhere.
- if (parent == null) {
- return;
- }
-
- int transformedIndex = index + parent.getNativeOffsetForChild(layoutOnlyNode);
- if (parent.isLayoutOnly()) {
- addNonLayoutOnlyNodeToLayoutOnlyNode(parent, nonLayoutOnlyNode, transformedIndex);
- } else {
- addNonLayoutNodeToNonLayoutNode(parent, nonLayoutOnlyNode, transformedIndex);
- }
- }
-
- private void addLayoutOnlyNodeToNonLayoutOnlyNode(
+ private void addLayoutOnlyNode(
ReactShadowNode nonLayoutOnlyNode,
ReactShadowNode layoutOnlyNode,
int index) {
- // Add all of the layout-only node's children to its parent instead
- int currentIndex = index;
- for (int i = 0; i < layoutOnlyNode.getChildCount(); i++) {
- ReactShadowNode childToAdd = layoutOnlyNode.getChildAt(i);
- Assertions.assertCondition(childToAdd.getNativeParent() == null);
-
- if (childToAdd.isLayoutOnly()) {
- // Adding this layout-only child could result in adding multiple native views
- int childCountBefore = nonLayoutOnlyNode.getNativeChildCount();
- addLayoutOnlyNodeToNonLayoutOnlyNode(
- nonLayoutOnlyNode,
- childToAdd,
- currentIndex);
- int childCountAfter = nonLayoutOnlyNode.getNativeChildCount();
- currentIndex += childCountAfter - childCountBefore;
- } else {
- addNonLayoutNodeToNonLayoutNode(nonLayoutOnlyNode, childToAdd, currentIndex);
- currentIndex++;
- }
- }
+ addGrandchildren(nonLayoutOnlyNode, layoutOnlyNode, index);
}
- private void addNonLayoutNodeToNonLayoutNode(
+ private void addNonLayoutNode(
ReactShadowNode parent,
ReactShadowNode child,
int index) {
@@ -340,6 +309,31 @@ private void addNonLayoutNodeToNonLayoutNode(
null);
}
+ private void addGrandchildren(
+ ReactShadowNode nativeParent,
+ ReactShadowNode child,
+ int index) {
+ Assertions.assertCondition(!nativeParent.isLayoutOnly());
+
+ // `child` can't hold native children. Add all of `child`'s children to `parent`.
+ int currentIndex = index;
+ for (int i = 0; i < child.getChildCount(); i++) {
+ ReactShadowNode grandchild = child.getChildAt(i);
+ Assertions.assertCondition(grandchild.getNativeParent() == null);
+
+ if (grandchild.isLayoutOnly()) {
+ // Adding this child could result in adding multiple native views
+ int grandchildCountBefore = nativeParent.getNativeChildCount();
+ addLayoutOnlyNode(nativeParent, grandchild, currentIndex);
+ int grandchildCountAfter = nativeParent.getNativeChildCount();
+ currentIndex += grandchildCountAfter - grandchildCountBefore;
+ } else {
+ addNonLayoutNode(nativeParent, grandchild, currentIndex);
+ currentIndex++;
+ }
+ }
+ }
+
private void applyLayoutBase(ReactShadowNode node) {
int tag = node.getReactTag();
if (mTagsWithLayoutVisited.get(tag)) {
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java
index ae623bf0e69763..5178281a1d8c7a 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java
@@ -190,12 +190,17 @@ protected static Spannable fromTextCSSNode(ReactTextShadowNode textCSSNode) {
}
textCSSNode.mContainsImages = false;
+ textCSSNode.mHeightOfTallestInlineImage = Float.NaN;
// While setting the Spans on the final text, we also check whether any of them are images
for (int i = ops.size() - 1; i >= 0; i--) {
SetSpanOperation op = ops.get(i);
if (op.what instanceof TextInlineImageSpan) {
+ int height = ((TextInlineImageSpan)op.what).getHeight();
textCSSNode.mContainsImages = true;
+ if (Float.isNaN(textCSSNode.mHeightOfTallestInlineImage) || height > textCSSNode.mHeightOfTallestInlineImage) {
+ textCSSNode.mHeightOfTallestInlineImage = height;
+ }
}
op.execute(sb);
}
@@ -226,6 +231,14 @@ public void measure(
// technically, width should never be negative, but there is currently a bug in
boolean unconstrainedWidth = widthMode == CSSMeasureMode.UNDEFINED || width < 0;
+ float effectiveLineHeight = reactCSSNode.getEffectiveLineHeight();
+ float lineSpacingExtra = 0;
+ float lineSpacingMultiplier = 1;
+ if (!Float.isNaN(effectiveLineHeight)) {
+ lineSpacingExtra = effectiveLineHeight;
+ lineSpacingMultiplier = 0;
+ }
+
if (boring == null &&
(unconstrainedWidth ||
(!CSSConstants.isUndefined(desiredWidth) && desiredWidth <= width))) {
@@ -236,8 +249,8 @@ public void measure(
textPaint,
(int) Math.ceil(desiredWidth),
Layout.Alignment.ALIGN_NORMAL,
- 1,
- 0,
+ lineSpacingMultiplier,
+ lineSpacingExtra,
true);
} else if (boring != null && (unconstrainedWidth || boring.width <= width)) {
// Is used for single-line, boring text when the width is either unknown or bigger
@@ -247,8 +260,8 @@ public void measure(
textPaint,
boring.width,
Layout.Alignment.ALIGN_NORMAL,
- 1,
- 0,
+ lineSpacingMultiplier,
+ lineSpacingExtra,
boring,
true);
} else {
@@ -258,8 +271,8 @@ public void measure(
textPaint,
(int) width,
Layout.Alignment.ALIGN_NORMAL,
- 1,
- 0,
+ lineSpacingMultiplier,
+ lineSpacingExtra,
true);
}
@@ -269,13 +282,6 @@ public void measure(
reactCSSNode.mNumberOfLines < layout.getLineCount()) {
measureOutput.height = layout.getLineBottom(reactCSSNode.mNumberOfLines - 1);
}
- if (reactCSSNode.mLineHeight != UNSET) {
- int lines = reactCSSNode.mNumberOfLines != UNSET
- ? Math.min(reactCSSNode.mNumberOfLines, layout.getLineCount())
- : layout.getLineCount();
- float lineHeight = PixelUtil.toPixelFromSP(reactCSSNode.mLineHeight);
- measureOutput.height = lineHeight * lines;
- }
}
};
@@ -293,7 +299,7 @@ private static int parseNumericFontWeight(String fontWeightString) {
100 * (fontWeightString.charAt(0) - '0') : -1;
}
- private int mLineHeight = UNSET;
+ private float mLineHeight = Float.NaN;
private boolean mIsColorSet = false;
private int mColor;
private boolean mIsBackgroundColorSet = false;
@@ -340,6 +346,7 @@ private static int parseNumericFontWeight(String fontWeightString) {
private final boolean mIsVirtual;
protected boolean mContainsImages = false;
+ private float mHeightOfTallestInlineImage = Float.NaN;
public ReactTextShadowNode(boolean isVirtual) {
mIsVirtual = isVirtual;
@@ -348,6 +355,15 @@ public ReactTextShadowNode(boolean isVirtual) {
}
}
+ // Returns a line height which takes into account the requested line height
+ // and the height of the inline images.
+ public float getEffectiveLineHeight() {
+ boolean useInlineViewHeight = !Float.isNaN(mLineHeight) &&
+ !Float.isNaN(mHeightOfTallestInlineImage) &&
+ mHeightOfTallestInlineImage > mLineHeight;
+ return useInlineViewHeight ? mHeightOfTallestInlineImage : mLineHeight;
+ }
+
@Override
public void onBeforeLayout() {
if (mIsVirtual) {
@@ -380,7 +396,7 @@ public void setNumberOfLines(int numberOfLines) {
@ReactProp(name = ViewProps.LINE_HEIGHT, defaultInt = UNSET)
public void setLineHeight(int lineHeight) {
- mLineHeight = lineHeight;
+ mLineHeight = lineHeight == UNSET ? Float.NaN : PixelUtil.toPixelFromSP(lineHeight);
markUpdated();
}
@@ -530,7 +546,7 @@ public void onCollectExtraUpdates(UIViewOperationQueue uiViewOperationQueue) {
super.onCollectExtraUpdates(uiViewOperationQueue);
if (mPreparedSpannableText != null) {
ReactTextUpdate reactTextUpdate =
- new ReactTextUpdate(mPreparedSpannableText, UNSET, mContainsImages, getPadding());
+ new ReactTextUpdate(mPreparedSpannableText, UNSET, mContainsImages, getPadding(), getEffectiveLineHeight());
uiViewOperationQueue.enqueueUpdateExtraData(getReactTag(), reactTextUpdate);
}
}
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextUpdate.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextUpdate.java
index dca68669d1d72e..5acb167c56acf0 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextUpdate.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextUpdate.java
@@ -27,12 +27,14 @@ public class ReactTextUpdate {
private final float mPaddingTop;
private final float mPaddingRight;
private final float mPaddingBottom;
+ private final float mLineHeight;
public ReactTextUpdate(
Spannable text,
int jsEventCounter,
boolean containsImages,
- Spacing padding) {
+ Spacing padding,
+ float lineHeight) {
mText = text;
mJsEventCounter = jsEventCounter;
mContainsImages = containsImages;
@@ -40,6 +42,7 @@ public ReactTextUpdate(
mPaddingTop = padding.get(Spacing.TOP);
mPaddingRight = padding.get(Spacing.RIGHT);
mPaddingBottom = padding.get(Spacing.BOTTOM);
+ mLineHeight = lineHeight;
}
public Spannable getText() {
@@ -69,4 +72,8 @@ public float getPaddingRight() {
public float getPaddingBottom() {
return mPaddingBottom;
}
+
+ public float getLineHeight() {
+ return mLineHeight;
+ }
}
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java
index 71bb5ccf10d245..9ef3df91a8ab58 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java
@@ -17,6 +17,7 @@
import android.view.ViewGroup;
import android.widget.TextView;
+import com.facebook.csslayout.FloatUtil;
import com.facebook.react.uimanager.ReactCompoundView;
public class ReactTextView extends TextView implements ReactCompoundView {
@@ -28,6 +29,7 @@ public class ReactTextView extends TextView implements ReactCompoundView {
private int mDefaultGravityHorizontal;
private int mDefaultGravityVertical;
private boolean mTextIsSelectable;
+ private float mLineHeight = Float.NaN;
public ReactTextView(Context context) {
super(context);
@@ -50,6 +52,16 @@ public void setText(ReactTextUpdate update) {
(int) Math.ceil(update.getPaddingTop()),
(int) Math.ceil(update.getPaddingRight()),
(int) Math.ceil(update.getPaddingBottom()));
+
+ float nextLineHeight = update.getLineHeight();
+ if (!FloatUtil.floatsEqual(mLineHeight, nextLineHeight)) {
+ mLineHeight = nextLineHeight;
+ if (Float.isNaN(mLineHeight)) { // NaN will be used if property gets reset
+ setLineSpacing(0, 1);
+ } else {
+ setLineSpacing(mLineHeight, 0);
+ }
+ }
}
@Override
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManager.java
index 97e780a6d0f59e..dc200c1fcb7a74 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManager.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManager.java
@@ -103,15 +103,6 @@ public void setTextAlignVertical(ReactTextView view, @Nullable String textAlignV
}
}
- @ReactProp(name = ViewProps.LINE_HEIGHT, defaultFloat = Float.NaN)
- public void setLineHeight(ReactTextView view, float lineHeight) {
- if (Float.isNaN(lineHeight)) { // NaN will be used if property gets reset
- view.setLineSpacing(0, 1);
- } else {
- view.setLineSpacing(PixelUtil.toPixelFromSP(lineHeight), 0);
- }
- }
-
@ReactProp(name = "selectable")
public void setSelectable(ReactTextView view, boolean isSelectable) {
view.setTextIsSelectable(isSelectable);
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/TextInlineImageSpan.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/TextInlineImageSpan.java
index 0308ee20c28c87..c987260fd0f380 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/views/text/TextInlineImageSpan.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/TextInlineImageSpan.java
@@ -67,4 +67,14 @@ public static void possiblyUpdateInlineImageSpans(Spannable spannable, TextView
* Set the textview that will contain this span.
*/
public abstract void setTextView(TextView textView);
+
+ /**
+ * Get the width of the span.
+ */
+ public abstract int getWidth();
+
+ /**
+ * Get the height of the span.
+ */
+ public abstract int getHeight();
}
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/frescosupport/FrescoBasedReactTextInlineImageSpan.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/frescosupport/FrescoBasedReactTextInlineImageSpan.java
index 0613457e59f7b2..0c0c5c1246768c 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/views/text/frescosupport/FrescoBasedReactTextInlineImageSpan.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/frescosupport/FrescoBasedReactTextInlineImageSpan.java
@@ -146,13 +146,21 @@ public void draw(
canvas.save();
- int transY = bottom - mDrawable.getBounds().bottom;
-
// Align to baseline by default
- transY -= paint.getFontMetricsInt().descent;
+ int transY = y - mDrawable.getBounds().bottom;
canvas.translate(x, transY);
mDrawable.draw(canvas);
canvas.restore();
}
+
+ @Override
+ public int getWidth() {
+ return mWidth;
+ }
+
+ @Override
+ public int getHeight() {
+ return mHeight;
+ }
}
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputShadowNode.java
index c75e9797beda38..cc71f6b88c13b0 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputShadowNode.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputShadowNode.java
@@ -119,7 +119,7 @@ public void onCollectExtraUpdates(UIViewOperationQueue uiViewOperationQueue) {
if (mJsEventCount != UNSET) {
Spannable preparedSpannableText = fromTextCSSNode(this);
ReactTextUpdate reactTextUpdate =
- new ReactTextUpdate(preparedSpannableText, mJsEventCount, mContainsImages, getPadding());
+ new ReactTextUpdate(preparedSpannableText, mJsEventCount, mContainsImages, getPadding(), getEffectiveLineHeight());
uiViewOperationQueue.enqueueUpdateExtraData(getReactTag(), reactTextUpdate);
}
}
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/webview/ReactWebViewManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/webview/ReactWebViewManager.java
index 3ed60497b8886a..9f4c5a7adf727c 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/views/webview/ReactWebViewManager.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/views/webview/ReactWebViewManager.java
@@ -18,6 +18,7 @@
import android.graphics.Bitmap;
import android.os.Build;
import android.text.TextUtils;
+import android.webkit.GeolocationPermissions;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.webkit.WebChromeClient;
@@ -259,7 +260,12 @@ public String getName() {
@Override
protected WebView createViewInstance(ThemedReactContext reactContext) {
ReactWebView webView = new ReactWebView(reactContext);
- webView.setWebChromeClient(new WebChromeClient());
+ webView.setWebChromeClient(new WebChromeClient() {
+ @Override
+ public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
+ callback.invoke(origin, true, false);
+ }
+ });
reactContext.addLifecycleEventListener(webView);
mWebViewConfig.configWebView(webView);
webView.getSettings().setBuiltInZoomControls(true);
diff --git a/ReactAndroid/src/main/third-party/java/okhttp/BUCK b/ReactAndroid/src/main/third-party/java/okhttp/BUCK
index 07d870bdbbe52d..a6d9925259e7f6 100644
--- a/ReactAndroid/src/main/third-party/java/okhttp/BUCK
+++ b/ReactAndroid/src/main/third-party/java/okhttp/BUCK
@@ -6,8 +6,8 @@ prebuilt_jar(
remote_file(
name = 'okhttp3-binary-jar',
- url = 'mvn:com.squareup.okhttp3:okhttp:jar:3.2.0',
- sha1 = 'f7873a2ebde246a45c2a8d6f3247108b4c88a879'
+ url = 'mvn:com.squareup.okhttp3:okhttp:jar:3.4.1',
+ sha1 = 'c7c4f9e35c2fd5900da24f9872e3971801f08ce0'
)
prebuilt_jar(
@@ -18,8 +18,8 @@ prebuilt_jar(
remote_file(
name = 'okhttp3-urlconnection-binary-jar',
- url = 'mvn:com.squareup.okhttp3:okhttp-urlconnection:jar:3.2.0',
- sha1 = '6f8a4b1435c9e0a6f9c5fe4a1be46627b848fd0c'
+ url = 'mvn:com.squareup.okhttp3:okhttp-urlconnection:jar:3.4.1',
+ sha1 = '63994437f62bc861bc20c605d12962f7246116d1'
)
prebuilt_jar(
@@ -30,6 +30,6 @@ prebuilt_jar(
remote_file(
name = 'okhttp3-ws-binary-jar',
- url = 'mvn:com.squareup.okhttp3:okhttp-ws:jar:3.2.0',
- sha1 = '1ea229d6984444c8c58b8e97ba4c8429d9d135b3',
+ url = 'mvn:com.squareup.okhttp3:okhttp-ws:jar:3.4.1',
+ sha1 = '8ace66ef7002d98f633377c9e67daeeb196d8c3b',
)
diff --git a/ReactAndroid/src/main/third-party/java/okio/BUCK b/ReactAndroid/src/main/third-party/java/okio/BUCK
index 3f3339840c4265..900a79732a3541 100644
--- a/ReactAndroid/src/main/third-party/java/okio/BUCK
+++ b/ReactAndroid/src/main/third-party/java/okio/BUCK
@@ -6,6 +6,6 @@ prebuilt_jar(
remote_file(
name = 'okio-binary-jar',
- url = 'mvn:com.squareup.okio:okio:jar:1.8.0',
- sha1 = '05ea7af56cc7c567ed9856d99efb30740e9b17ff',
+ url = 'mvn:com.squareup.okio:okio:jar:1.9.0',
+ sha1 = 'f824591a0016efbaeddb8300bee54832a1398cfa',
)
diff --git a/ReactCommon/cxxreact/JSCExecutor.cpp b/ReactCommon/cxxreact/JSCExecutor.cpp
index 25efa9f3ecb120..42967be0c879d2 100644
--- a/ReactCommon/cxxreact/JSCExecutor.cpp
+++ b/ReactCommon/cxxreact/JSCExecutor.cpp
@@ -596,7 +596,7 @@ JSValueRef JSCExecutor::nativeRequireModuleConfig(
std::string moduleName = Value(m_context, arguments[0]).toString().str();
folly::dynamic config = m_delegate->getModuleConfig(moduleName);
- return JSValueMakeString(m_context, String(folly::toJson(config).c_str()));
+ return Value::fromDynamic(m_context, config);
}
JSValueRef JSCExecutor::nativeFlushQueueImmediate(
@@ -681,7 +681,7 @@ JSValueRef JSCExecutor::nativeCallSyncHook(
if (result.isUndefined) {
return JSValueMakeUndefined(m_context);
}
- return Value::fromJSON(m_context, String(folly::toJson(result.result).c_str()));
+ return Value::fromDynamic(m_context, result.result);
}
static JSValueRef nativeInjectHMRUpdate(
diff --git a/ReactCommon/cxxreact/Value.cpp b/ReactCommon/cxxreact/Value.cpp
index c328701ec362d3..7bc40b20fd6e45 100644
--- a/ReactCommon/cxxreact/Value.cpp
+++ b/ReactCommon/cxxreact/Value.cpp
@@ -6,6 +6,9 @@
#include "JSCHelpers.h"
+// See the comment under Value::fromDynamic()
+#define USE_FAST_FOLLY_DYNAMIC_CONVERSION !defined(__APPLE__) && defined(WITH_FB_JSC_TUNING)
+
namespace facebook {
namespace react {
@@ -51,9 +54,78 @@ Value Value::fromJSON(JSContextRef ctx, const String& json) throw(JSException) {
return Value(ctx, result);
}
-Value Value::fromDynamic(JSContextRef ctx, folly::dynamic value) throw(JSException) {
+JSValueRef Value::fromDynamic(JSContextRef ctx, const folly::dynamic& value) {
+// JavaScriptCore's iOS APIs have their own version of this direct conversion.
+// In addition, using this requires exposing some of JSC's private APIs,
+// so it's limited to non-apple platforms and to builds that use the custom JSC.
+// Otherwise, we use the old way of converting through JSON.
+#if USE_FAST_FOLLY_DYNAMIC_CONVERSION
+ // Defer GC during the creation of the JSValue, as we don't want
+ // intermediate objects to be collected.
+ // We could use JSValueProtect(), but it will make the process much slower.
+ JSDeferredGCRef deferGC = JSDeferGarbageCollection(ctx);
+ // Set a global lock for the whole process,
+ // instead of re-acquiring the lock for each operation.
+ JSLock(ctx);
+ JSValueRef jsVal = Value::fromDynamicInner(ctx, value);
+ JSUnlock(ctx);
+ JSResumeGarbageCollection(ctx, deferGC);
+ return jsVal;
+#else
auto json = folly::toJson(value);
return fromJSON(ctx, String(json.c_str()));
+#endif
+}
+
+JSValueRef Value::fromDynamicInner(JSContextRef ctx, const folly::dynamic& obj) {
+ switch (obj.type()) {
+ // For premitive types (and strings), just create and return an equivalent JSValue
+ case folly::dynamic::Type::NULLT:
+ return JSValueMakeNull(ctx);
+
+ case folly::dynamic::Type::BOOL:
+ return JSValueMakeBoolean(ctx, obj.getBool());
+
+ case folly::dynamic::Type::DOUBLE:
+ return JSValueMakeNumber(ctx, obj.getDouble());
+
+ case folly::dynamic::Type::INT64:
+ return JSValueMakeNumber(ctx, obj.asDouble());
+
+ case folly::dynamic::Type::STRING:
+ return JSValueMakeString(ctx, String(obj.getString().c_str()));
+
+ case folly::dynamic::Type::ARRAY: {
+ // Collect JSValue for every element in the array
+ JSValueRef vals[obj.size()];
+ for (size_t i = 0; i < obj.size(); ++i) {
+ vals[i] = fromDynamicInner(ctx, obj[i]);
+ }
+ // Create a JSArray with the values
+ JSValueRef arr = JSObjectMakeArray(ctx, obj.size(), vals, nullptr);
+ return arr;
+ }
+
+ case folly::dynamic::Type::OBJECT: {
+ // Create an empty object
+ JSObjectRef jsObj = JSObjectMake(ctx, nullptr, nullptr);
+ // Create a JSValue for each of the object's children and set them in the object
+ for (auto it = obj.items().begin(); it != obj.items().end(); ++it) {
+ JSObjectSetProperty(
+ ctx,
+ jsObj,
+ String(it->first.asString().c_str()),
+ fromDynamicInner(ctx, it->second),
+ kJSPropertyAttributeNone,
+ nullptr);
+ }
+ return jsObj;
+ }
+ default:
+ // Assert not reached
+ LOG(FATAL) << "Trying to convert a folly object of unsupported type.";
+ return JSValueMakeNull(ctx);
+ }
}
Object Value::asObject() {
diff --git a/ReactCommon/cxxreact/Value.h b/ReactCommon/cxxreact/Value.h
index 1aa965e9c31415..044f3a52256f8a 100644
--- a/ReactCommon/cxxreact/Value.h
+++ b/ReactCommon/cxxreact/Value.h
@@ -284,11 +284,12 @@ class Value : public noncopyable {
std::string toJSONString(unsigned indent = 0) const throw(JSException);
static Value fromJSON(JSContextRef ctx, const String& json) throw(JSException);
- static Value fromDynamic(JSContextRef ctx, folly::dynamic value) throw(JSException);
+ static JSValueRef fromDynamic(JSContextRef ctx, const folly::dynamic& value);
JSContextRef context() const;
protected:
JSContextRef m_context;
JSValueRef m_value;
+ static JSValueRef fromDynamicInner(JSContextRef ctx, const folly::dynamic& obj);
};
} }