diff --git a/enums.py b/enums.py
index 47a74551..b67e5b10 100644
--- a/enums.py
+++ b/enums.py
@@ -51,6 +51,10 @@ ENUMS = {
'PositionType': [
'Relative',
'Absolute',
+ ],
+ 'Display': [
+ 'Flex',
+ 'None',
],
'Wrap': [
'NoWrap',
diff --git a/gentest/fixtures/YGDisplayTest.html b/gentest/fixtures/YGDisplayTest.html
new file mode 100644
index 00000000..e4f85222
--- /dev/null
+++ b/gentest/fixtures/YGDisplayTest.html
@@ -0,0 +1,6 @@
+
diff --git a/gentest/gentest-cpp.js b/gentest/gentest-cpp.js
index 4834b45a..76fdea5f 100644
--- a/gentest/gentest-cpp.js
+++ b/gentest/gentest-cpp.js
@@ -118,6 +118,9 @@ CPPEmitter.prototype = Object.create(Emitter.prototype, {
YGUndefined:{value:'YGUndefined'},
+ YGDisplayFlex:{value:'YGDisplayFlex'},
+ YGDisplayNone:{value:'YGDisplayNone'},
+
YGNodeCalculateLayout:{value:function(node, dir) {
this.push('YGNodeCalculateLayout(' + node + ', YGUndefined, YGUndefined, ' + dir + ');');
}},
@@ -162,6 +165,10 @@ CPPEmitter.prototype = Object.create(Emitter.prototype, {
this.push('YGNodeStyleSetDirection(' + nodeName + ', ' + toValueCpp(value) + ');');
}},
+ YGNodeStyleSetDisplay:{value:function(nodeName, value) {
+ this.push('YGNodeStyleSetDisplay(' + nodeName + ', ' + toValueCpp(value) + ');');
+ }},
+
YGNodeStyleSetFlexBasis:{value:function(nodeName, value) {
this.push('YGNodeStyleSetFlexBasis' + toFunctionName(value) + '(' + nodeName + ', ' + toValueCpp(value) + ');');
}},
diff --git a/gentest/gentest-cs.js b/gentest/gentest-cs.js
index 08b08588..3650d862 100644
--- a/gentest/gentest-cs.js
+++ b/gentest/gentest-cs.js
@@ -128,6 +128,9 @@ CSEmitter.prototype = Object.create(Emitter.prototype, {
YGUndefined:{value:'YogaConstants.Undefined'},
+ YGDisplayFlex:{value:'YogaDisplay.Flex'},
+ YGDisplayNone:{value:'YogaDisplay.None'},
+
YGWrapNoWrap:{value:'YogaWrap.NoWrap'},
YGWrapWrap:{value:'YogaWrap.Wrap'},
@@ -176,6 +179,10 @@ CSEmitter.prototype = Object.create(Emitter.prototype, {
this.push(nodeName + '.StyleDirection = ' + toValueCs(value) + ';');
}},
+ YGNodeStyleSetDisplay:{value:function(nodeName, value) {
+ this.push(nodeName + '.Display = ' + toValueCs(value) + ';');
+ }},
+
YGNodeStyleSetFlexBasis:{value:function(nodeName, value) {
this.push(nodeName + '.FlexBasis = ' + toCsUnitValue(value) + ';');
}},
diff --git a/gentest/gentest-java.js b/gentest/gentest-java.js
index 1c510c48..727c090d 100644
--- a/gentest/gentest-java.js
+++ b/gentest/gentest-java.js
@@ -132,6 +132,9 @@ JavaEmitter.prototype = Object.create(Emitter.prototype, {
YGUndefined:{value:'YogaConstants.UNDEFINED'},
+ YGDisplayFlex:{value:'YogaDisplay.FLEX'},
+ YGDisplayNone:{value:'YogaDisplay.NONE'},
+
YGWrapNoWrap:{value:'YogaWrap.NO_WRAP'},
YGWrapWrap:{value:'YogaWrap.WRAP'},
@@ -180,6 +183,10 @@ JavaEmitter.prototype = Object.create(Emitter.prototype, {
this.push(nodeName + '.setDirection(' + toValueJava(value) + ');');
}},
+ YGNodeStyleSetDisplay:{value:function(nodeName, value) {
+ this.push(nodeName + '.setDisplay(' + toValueJavascript(value) + ');');
+ }},
+
YGNodeStyleSetFlexBasis:{value:function(nodeName, value) {
this.push(nodeName + '.setFlexBasis' + toMethodName(value) + '(' + toValueJava(value) + 'f);');
}},
diff --git a/gentest/gentest-javascript.js b/gentest/gentest-javascript.js
index 8f56477e..67c38e83 100644
--- a/gentest/gentest-javascript.js
+++ b/gentest/gentest-javascript.js
@@ -125,6 +125,9 @@ JavascriptEmitter.prototype = Object.create(Emitter.prototype, {
YGUndefined:{value:'Yoga.UNDEFINED'},
+ YGDisplayFlex:{value:'Yoga.DISPLAY_FLEX'},
+ YGDisplayNone:{value:'Yoga.DISPLAY_NONE'},
+
YGNodeCalculateLayout:{value:function(node, dir) {
this.push(node + '.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, ' + dir + ');');
}},
@@ -169,6 +172,10 @@ JavascriptEmitter.prototype = Object.create(Emitter.prototype, {
this.push(nodeName + '.setDirection(' + toValueJavascript(value) + ');');
}},
+ YGNodeStyleSetDisplay:{value:function(nodeName, value) {
+ this.push(nodeName + '.setDisplay(' + toValueJavascript(value) + ');');
+ }},
+
YGNodeStyleSetFlexBasis:{value:function(nodeName, value) {
this.push(nodeName + '.setFlexBasis(' + toValueJavascript(value) + ');');
}},
diff --git a/gentest/gentest.js b/gentest/gentest.js
index 2c63d9ae..49f4e42b 100755
--- a/gentest/gentest.js
+++ b/gentest/gentest.js
@@ -140,6 +140,7 @@ function checkDefaultValues() {
{style:'top', value:'undefined'},
{style:'right', value:'undefined'},
{style:'bottom', value:'undefined'},
+ {style:'display', value:'flex'},
].forEach(function(item) {
assert(item.value === getDefaultStyleValue(item.style),
item.style + ' should be ' + item.value);
@@ -300,6 +301,9 @@ function setupTestTree(e, parent, node, genericNode, nodeName, parentName, index
case 'max-height':
e.YGNodeStyleSetMaxHeight(nodeName, pixelValue(e, node.style[style]));
break;
+ case 'display':
+ e.YGNodeStyleSetDisplay(nodeName, displayValue(e, node.style[style]))
+ break;
}
}
}
@@ -389,6 +393,13 @@ function pixelValue(e, value) {
}
}
+function displayValue(e, value){
+ switch(value){
+ case 'flex': return e.YGDisplayFlex;
+ case 'none': return e.YGDisplayNone;
+ }
+}
+
function getDefaultStyleValue(style) {
if (style == 'position') {
return 'relative';
@@ -466,6 +477,7 @@ function getYogaStyle(node) {
'height',
'min-height',
'max-height',
+ 'display',
].reduce(function(map, key) {
map[key] = node.style[key] || getComputedStyle(node, null).getPropertyValue(key);
return map;
diff --git a/tests/YGDisplayTest.cpp b/tests/YGDisplayTest.cpp
new file mode 100644
index 00000000..747faa47
--- /dev/null
+++ b/tests/YGDisplayTest.cpp
@@ -0,0 +1,95 @@
+/**
+ * Copyright (c) 2014-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+ // @Generated by gentest/gentest.rb from gentest/fixtures/YGDisplayTest.html
+
+#include
+#include
+
+TEST(YogaTest, display_none) {
+ const YGNodeRef root = YGNodeNew();
+ YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
+ YGNodeStyleSetWidth(root, 100);
+ YGNodeStyleSetHeight(root, 100);
+
+ const YGNodeRef root_child0 = YGNodeNew();
+ YGNodeStyleSetFlexGrow(root_child0, 1);
+ YGNodeInsertChild(root, root_child0, 0);
+
+ const YGNodeRef root_child1 = YGNodeNew();
+ YGNodeStyleSetFlexGrow(root_child1, 1);
+ YGNodeStyleSetDisplay(root_child1, YGDisplayNone);
+ YGNodeInsertChild(root, root_child1, 1);
+
+ const YGNodeRef root_child2 = YGNodeNew();
+ YGNodeStyleSetFlexGrow(root_child2, 1);
+ YGNodeStyleSetWidth(root_child2, 100);
+ YGNodeInsertChild(root, root_child2, 2);
+
+ const YGNodeRef root_child3 = YGNodeNew();
+ YGNodeStyleSetFlexGrow(root_child3, 1);
+ YGNodeStyleSetWidth(root_child3, 100);
+ YGNodeStyleSetDisplay(root_child3, YGDisplayNone);
+ YGNodeInsertChild(root, root_child3, 3);
+ YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
+
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
+ ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root));
+ ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root));
+
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0));
+ ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0));
+
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child1));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1));
+
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2));
+ ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2));
+ ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2));
+
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child3));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child3));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child3));
+
+ YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL);
+
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
+ ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root));
+ ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root));
+
+ ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0));
+ ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0));
+
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child1));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child1));
+
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2));
+ ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child2));
+ ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child2));
+
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child3));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child3));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child3));
+
+ YGNodeFreeRecursive(root);
+}
diff --git a/yoga/YGEnums.h b/yoga/YGEnums.h
index 21eb4809..576a8dbd 100644
--- a/yoga/YGEnums.h
+++ b/yoga/YGEnums.h
@@ -100,4 +100,10 @@ typedef YG_ENUM_BEGIN(YGUnit) {
}
YG_ENUM_END(YGUnit);
+#define YGDisplayCount 2
+typedef YG_ENUM_BEGIN(YGDisplay) {
+ YGDisplayFlex, YGDisplayNone,
+}
+YG_ENUM_END(YGDisplay);
+
YG_EXTERN_C_END
diff --git a/yoga/Yoga.c b/yoga/Yoga.c
index 792464b6..4381ed93 100644
--- a/yoga/Yoga.c
+++ b/yoga/Yoga.c
@@ -77,6 +77,7 @@ typedef struct YGStyle {
YGPositionType positionType;
YGWrap flexWrap;
YGOverflow overflow;
+ YGDisplay display;
float flex;
float flexGrow;
float flexShrink;
@@ -148,6 +149,7 @@ static YGNode gYGNodeDefaults = {
.direction = YGDirectionInherit,
.flexDirection = YGFlexDirectionColumn,
.overflow = YGOverflowVisible,
+ .display = YGDisplayFlex,
.dimensions = YG_DEFAULT_DIMENSION_VALUES_UNIT,
.minDimensions = YG_DEFAULT_DIMENSION_VALUES_UNIT,
.maxDimensions = YG_DEFAULT_DIMENSION_VALUES_UNIT,
@@ -568,6 +570,7 @@ YG_NODE_STYLE_PROPERTY_IMPL(YGAlign, AlignSelf, alignSelf, alignSelf);
YG_NODE_STYLE_PROPERTY_IMPL(YGPositionType, PositionType, positionType, positionType);
YG_NODE_STYLE_PROPERTY_IMPL(YGWrap, FlexWrap, flexWrap, flexWrap);
YG_NODE_STYLE_PROPERTY_IMPL(YGOverflow, Overflow, overflow, overflow);
+YG_NODE_STYLE_PROPERTY_IMPL(YGDisplay, Display, display, display);
YG_NODE_STYLE_PROPERTY_SETTER_IMPL(float, FlexGrow, flexGrow, flexGrow);
YG_NODE_STYLE_PROPERTY_SETTER_IMPL(float, FlexShrink, flexShrink, flexShrink);
@@ -1915,7 +1918,13 @@ static void YGNodelayoutImpl(const YGNodeRef node,
// STEP 3: DETERMINE FLEX BASIS FOR EACH ITEM
for (uint32_t i = 0; i < childCount; i++) {
const YGNodeRef child = YGNodeListGet(node->children, i);
-
+ if (child->style.display == YGDisplayNone) {
+ child->layout.dimensions[YGDimensionHeight] = 0;
+ child->layout.dimensions[YGDimensionWidth] = 0;
+ child->hasNewLayout = true;
+ child->isDirty = false;
+ continue;
+ }
if (performLayout) {
// Set the initial position (relative to the parent).
const YGDirection childDirection = YGNodeResolveDirection(child, direction);
@@ -1995,6 +2004,9 @@ static void YGNodelayoutImpl(const YGNodeRef node,
// Add items to the current line until it's full or we run out of items.
for (uint32_t i = startOfLineIndex; i < childCount; i++, endOfLineIndex++) {
const YGNodeRef child = YGNodeListGet(node->children, i);
+ if (child->style.display == YGDisplayNone) {
+ continue;
+ }
child->lineIndex = lineCount;
if (child->style.positionType != YGPositionTypeAbsolute) {
@@ -2386,7 +2398,9 @@ static void YGNodelayoutImpl(const YGNodeRef node,
for (uint32_t i = startOfLineIndex; i < endOfLineIndex; i++) {
const YGNodeRef child = YGNodeListGet(node->children, i);
-
+ if (child->style.display == YGDisplayNone) {
+ continue;
+ }
if (child->style.positionType == YGPositionTypeAbsolute &&
YGNodeIsLeadingPosDefined(child, mainAxis)) {
if (performLayout) {
@@ -2467,7 +2481,9 @@ static void YGNodelayoutImpl(const YGNodeRef node,
if (performLayout) {
for (uint32_t i = startOfLineIndex; i < endOfLineIndex; i++) {
const YGNodeRef child = YGNodeListGet(node->children, i);
-
+ if (child->style.display == YGDisplayNone) {
+ continue;
+ }
if (child->style.positionType == YGPositionTypeAbsolute) {
// If the child is absolutely positioned and has a
// top/left/bottom/right
@@ -2618,7 +2634,9 @@ static void YGNodelayoutImpl(const YGNodeRef node,
float maxDescentForCurrentLine = 0;
for (ii = startIndex; ii < childCount; ii++) {
const YGNodeRef child = YGNodeListGet(node->children, ii);
-
+ if (child->style.display == YGDisplayNone) {
+ continue;
+ }
if (child->style.positionType == YGPositionTypeRelative) {
if (child->lineIndex != i) {
break;
@@ -2647,7 +2665,9 @@ static void YGNodelayoutImpl(const YGNodeRef node,
if (performLayout) {
for (ii = startIndex; ii < endIndex; ii++) {
const YGNodeRef child = YGNodeListGet(node->children, ii);
-
+ if (child->style.display == YGDisplayNone) {
+ continue;
+ }
if (child->style.positionType == YGPositionTypeRelative) {
switch (YGNodeAlignItem(node, child)) {
case YGAlignFlexStart: {
@@ -2757,7 +2777,9 @@ static void YGNodelayoutImpl(const YGNodeRef node,
if (needsMainTrailingPos || needsCrossTrailingPos) {
for (uint32_t i = 0; i < childCount; i++) {
const YGNodeRef child = YGNodeListGet(node->children, i);
-
+ if (child->style.display == YGDisplayNone) {
+ continue;
+ }
if (needsMainTrailingPos) {
YGNodeSetChildTrailingPosition(node, child, mainAxis);
}
diff --git a/yoga/Yoga.h b/yoga/Yoga.h
index ab6a2f89..bf9bd3e8 100644
--- a/yoga/Yoga.h
+++ b/yoga/Yoga.h
@@ -157,6 +157,7 @@ YG_NODE_STYLE_PROPERTY(YGAlign, AlignSelf, alignSelf);
YG_NODE_STYLE_PROPERTY(YGPositionType, PositionType, positionType);
YG_NODE_STYLE_PROPERTY(YGWrap, FlexWrap, flexWrap);
YG_NODE_STYLE_PROPERTY(YGOverflow, Overflow, overflow);
+YG_NODE_STYLE_PROPERTY(YGDisplay, Display, display);
WIN_EXPORT void YGNodeStyleSetFlex(const YGNodeRef node, const float flex);
YG_NODE_STYLE_PROPERTY(float, FlexGrow, flexGrow);