Skip to content

Commit

Permalink
Fix handling 'auto' checks in absolute layout (#1689)
Browse files Browse the repository at this point in the history
Summary:
X-link: facebook/react-native#46216

Regarding [issue](facebook/react-native#45817) with incorrect layout when `left` is set to `auto`. This PR introduces handling `auto` whenever inline or flex position is checked to be defined and it fixes above issue.

Changelog:
[General][Fixed] - Fix handling 'auto' checks in absolute layout

## Tests:
 I have run the provided unit tests and everything passes.

Pull Request resolved: #1689

Reviewed By: cipolleschi

Differential Revision: D61737876

Pulled By: NickGerleman

fbshipit-source-id: 531199a91c5e122b930b49725ea567cbb1d592ce
  • Loading branch information
coado authored and facebook-github-bot committed Aug 27, 2024
1 parent 596f8df commit 6d6f69b
Show file tree
Hide file tree
Showing 21 changed files with 529 additions and 27 deletions.
12 changes: 12 additions & 0 deletions gentest/fixtures/YGAbsolutePositionTest.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@
<div style="width:10px; height: 10px; position: absolute; start: 10px; top: 10px;"></div>
</div>

<div id="absolute_layout_width_height_left_auto_right" style="width: 100px; height: 100px">
<div style="width: 10px; height: 10px; position: absolute; left: auto; right: 10px;"></div>
</div>

<div id="absolute_layout_width_height_left_right_auto" style="width: 100px; height: 100px">
<div style="width: 10px; height: 10px; position: absolute; left: 10px; right: auto;"></div>
</div>

<div id="absolute_layout_width_height_left_auto_right_auto" style="width: 100px; height: 100px">
<div style="width: 10px; height: 10px; position: absolute; left: auto; right: auto;"></div>
</div>

<div id="absolute_layout_width_height_end_bottom" style="width: 100px; height: 100px;">
<div style="width:10px; height: 10px; position: absolute; end: 10px; bottom: 10px;"></div>
</div>
Expand Down
9 changes: 7 additions & 2 deletions gentest/gentest-cpp.js
Original file line number Diff line number Diff line change
Expand Up @@ -451,15 +451,20 @@ CPPEmitter.prototype = Object.create(Emitter.prototype, {

YGNodeStyleSetPosition: {
value: function (nodeName, edge, value) {
let valueStr = toValueCpp(value);
if (valueStr != 'YGAuto') {
valueStr = ', ' + valueStr;
} else {
valueStr = '';
}
this.push(
'YGNodeStyleSetPosition' +
toFunctionName(value) +
'(' +
nodeName +
', ' +
edge +
', ' +
toValueCpp(value) +
valueStr +
');',
);
},
Expand Down
12 changes: 9 additions & 3 deletions gentest/gentest-java.js
Original file line number Diff line number Diff line change
Expand Up @@ -420,15 +420,21 @@ JavaEmitter.prototype = Object.create(Emitter.prototype, {

YGNodeStyleSetPosition: {
value: function (nodeName, edge, value) {
let valueStr = toValueJava(value);

if (valueStr == 'YogaConstants.AUTO') {
valueStr = '';
} else {
valueStr = ', ' + valueStr + 'f';
}
this.push(
nodeName +
'.setPosition' +
toMethodName(value) +
'(' +
edge +
', ' +
toValueJava(value) +
'f);',
valueStr +
');',
);
},
},
Expand Down
24 changes: 16 additions & 8 deletions gentest/gentest-javascript.js
Original file line number Diff line number Diff line change
Expand Up @@ -364,14 +364,22 @@ JavascriptEmitter.prototype = Object.create(Emitter.prototype, {

YGNodeStyleSetPosition: {
value: function (nodeName, edge, value) {
this.push(
nodeName +
'.setPosition(' +
toValueJavascript(edge) +
', ' +
toValueJavascript(value) +
');',
);
const valueStr = toValueJavascript(value);

if (valueStr == "'auto'") {
this.push(
nodeName + '.setPositionAuto(' + toValueJavascript(edge) + ');',
);
} else {
this.push(
nodeName +
'.setPosition(' +
toValueJavascript(edge) +
', ' +
valueStr +
');',
);
}
},
},

Expand Down
1 change: 1 addition & 0 deletions java/com/facebook/yoga/YogaNative.java
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ public class YogaNative {
static native long jni_YGNodeStyleGetPositionJNI(long nativePointer, int edge);
static native void jni_YGNodeStyleSetPositionJNI(long nativePointer, int edge, float position);
static native void jni_YGNodeStyleSetPositionPercentJNI(long nativePointer, int edge, float percent);
static native void jni_YGNodeStyleSetPositionAutoJNI(long nativePointer, int edge);
static native long jni_YGNodeStyleGetWidthJNI(long nativePointer);
static native void jni_YGNodeStyleSetWidthJNI(long nativePointer, float width);
static native void jni_YGNodeStyleSetWidthPercentJNI(long nativePointer, float percent);
Expand Down
2 changes: 2 additions & 0 deletions java/com/facebook/yoga/YogaNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ public interface Inputs {

public abstract void setPositionPercent(YogaEdge edge, float percent);

public abstract void setPositionAuto(YogaEdge edge);

public abstract YogaValue getWidth();

public abstract void setWidth(float width);
Expand Down
4 changes: 4 additions & 0 deletions java/com/facebook/yoga/YogaNodeJNIBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,10 @@ public void setPositionPercent(YogaEdge edge, float percent) {
YogaNative.jni_YGNodeStyleSetPositionPercentJNI(mNativePointer, edge.intValue(), percent);
}

public void setPositionAuto(YogaEdge edge) {
YogaNative.jni_YGNodeStyleSetPositionAutoJNI(mNativePointer, edge.intValue());
}

public YogaValue getWidth() {
return valueFromLong(YogaNative.jni_YGNodeStyleGetWidthJNI(mNativePointer));
}
Expand Down
13 changes: 12 additions & 1 deletion java/jni/YGJNIVanilla.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,14 @@ static void jni_YGNodeCopyStyleJNI(
static_cast<float>(value)); \
}

#define YG_NODE_JNI_STYLE_EDGE_UNIT_PROP_AUTO(name) \
YG_NODE_JNI_STYLE_EDGE_UNIT_PROP(name) \
static void jni_YGNodeStyleSet##name##AutoJNI( \
JNIEnv* /*env*/, jobject /*obj*/, jlong nativePointer, jint edge) { \
YGNodeStyleSet##name##Auto( \
_jlong2YGNodeRef(nativePointer), static_cast<YGEdge>(edge)); \
}

YG_NODE_JNI_STYLE_PROP(jint, YGDirection, Direction);
YG_NODE_JNI_STYLE_PROP(jint, YGFlexDirection, FlexDirection);
YG_NODE_JNI_STYLE_PROP(jint, YGJustify, JustifyContent);
Expand All @@ -482,7 +490,7 @@ YG_NODE_JNI_STYLE_UNIT_PROP_AUTO(Height);
YG_NODE_JNI_STYLE_UNIT_PROP(MinHeight);
YG_NODE_JNI_STYLE_UNIT_PROP(MaxHeight);

YG_NODE_JNI_STYLE_EDGE_UNIT_PROP(Position);
YG_NODE_JNI_STYLE_EDGE_UNIT_PROP_AUTO(Position);

static jlong jni_YGNodeStyleGetMarginJNI(
JNIEnv* /*env*/,
Expand Down Expand Up @@ -891,6 +899,9 @@ static JNINativeMethod methods[] = {
{"jni_YGNodeStyleSetPositionPercentJNI",
"(JIF)V",
(void*)jni_YGNodeStyleSetPositionPercentJNI},
{"jni_YGNodeStyleSetPositionAutoJNI",
"(JI)V",
(void*)jni_YGNodeStyleSetPositionAutoJNI},
{"jni_YGNodeStyleGetWidthJNI", "(J)J", (void*)jni_YGNodeStyleGetWidthJNI},
{"jni_YGNodeStyleSetWidthJNI", "(JF)V", (void*)jni_YGNodeStyleSetWidthJNI},
{"jni_YGNodeStyleSetWidthPercentJNI",
Expand Down
131 changes: 130 additions & 1 deletion java/tests/generated/com/facebook/yoga/YGAbsolutePositionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<30a9046ab7f9c7bda2d4f3b2ae12afcd>>
* @generated SignedSource<<c4a613bef526a87ca88e3b28e1abc215>>
* generated by gentest/gentest-driver.ts from gentest/fixtures/YGAbsolutePositionTest.html
*/

Expand Down Expand Up @@ -70,6 +70,135 @@ public void test_absolute_layout_width_height_start_top() {
assertEquals(10f, root_child0.getLayoutHeight(), 0.0f);
}

@Test
public void test_absolute_layout_width_height_left_auto_right() {
YogaConfig config = YogaConfigFactory.create();

final YogaNode root = createNode(config);
root.setPositionType(YogaPositionType.ABSOLUTE);
root.setWidth(100f);
root.setHeight(100f);

final YogaNode root_child0 = createNode(config);
root_child0.setPositionType(YogaPositionType.ABSOLUTE);
root_child0.setPositionAuto(YogaEdge.LEFT);
root_child0.setPosition(YogaEdge.RIGHT, 10f);
root_child0.setWidth(10f);
root_child0.setHeight(10f);
root.addChildAt(root_child0, 0);
root.setDirection(YogaDirection.LTR);
root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED);

assertEquals(0f, root.getLayoutX(), 0.0f);
assertEquals(0f, root.getLayoutY(), 0.0f);
assertEquals(100f, root.getLayoutWidth(), 0.0f);
assertEquals(100f, root.getLayoutHeight(), 0.0f);

assertEquals(80f, root_child0.getLayoutX(), 0.0f);
assertEquals(0f, root_child0.getLayoutY(), 0.0f);
assertEquals(10f, root_child0.getLayoutWidth(), 0.0f);
assertEquals(10f, root_child0.getLayoutHeight(), 0.0f);

root.setDirection(YogaDirection.RTL);
root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED);

assertEquals(0f, root.getLayoutX(), 0.0f);
assertEquals(0f, root.getLayoutY(), 0.0f);
assertEquals(100f, root.getLayoutWidth(), 0.0f);
assertEquals(100f, root.getLayoutHeight(), 0.0f);

assertEquals(80f, root_child0.getLayoutX(), 0.0f);
assertEquals(0f, root_child0.getLayoutY(), 0.0f);
assertEquals(10f, root_child0.getLayoutWidth(), 0.0f);
assertEquals(10f, root_child0.getLayoutHeight(), 0.0f);
}

@Test
public void test_absolute_layout_width_height_left_right_auto() {
YogaConfig config = YogaConfigFactory.create();

final YogaNode root = createNode(config);
root.setPositionType(YogaPositionType.ABSOLUTE);
root.setWidth(100f);
root.setHeight(100f);

final YogaNode root_child0 = createNode(config);
root_child0.setPositionType(YogaPositionType.ABSOLUTE);
root_child0.setPosition(YogaEdge.LEFT, 10f);
root_child0.setPositionAuto(YogaEdge.RIGHT);
root_child0.setWidth(10f);
root_child0.setHeight(10f);
root.addChildAt(root_child0, 0);
root.setDirection(YogaDirection.LTR);
root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED);

assertEquals(0f, root.getLayoutX(), 0.0f);
assertEquals(0f, root.getLayoutY(), 0.0f);
assertEquals(100f, root.getLayoutWidth(), 0.0f);
assertEquals(100f, root.getLayoutHeight(), 0.0f);

assertEquals(10f, root_child0.getLayoutX(), 0.0f);
assertEquals(0f, root_child0.getLayoutY(), 0.0f);
assertEquals(10f, root_child0.getLayoutWidth(), 0.0f);
assertEquals(10f, root_child0.getLayoutHeight(), 0.0f);

root.setDirection(YogaDirection.RTL);
root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED);

assertEquals(0f, root.getLayoutX(), 0.0f);
assertEquals(0f, root.getLayoutY(), 0.0f);
assertEquals(100f, root.getLayoutWidth(), 0.0f);
assertEquals(100f, root.getLayoutHeight(), 0.0f);

assertEquals(10f, root_child0.getLayoutX(), 0.0f);
assertEquals(0f, root_child0.getLayoutY(), 0.0f);
assertEquals(10f, root_child0.getLayoutWidth(), 0.0f);
assertEquals(10f, root_child0.getLayoutHeight(), 0.0f);
}

@Test
public void test_absolute_layout_width_height_left_auto_right_auto() {
YogaConfig config = YogaConfigFactory.create();

final YogaNode root = createNode(config);
root.setPositionType(YogaPositionType.ABSOLUTE);
root.setWidth(100f);
root.setHeight(100f);

final YogaNode root_child0 = createNode(config);
root_child0.setPositionType(YogaPositionType.ABSOLUTE);
root_child0.setPositionAuto(YogaEdge.LEFT);
root_child0.setPositionAuto(YogaEdge.RIGHT);
root_child0.setWidth(10f);
root_child0.setHeight(10f);
root.addChildAt(root_child0, 0);
root.setDirection(YogaDirection.LTR);
root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED);

assertEquals(0f, root.getLayoutX(), 0.0f);
assertEquals(0f, root.getLayoutY(), 0.0f);
assertEquals(100f, root.getLayoutWidth(), 0.0f);
assertEquals(100f, root.getLayoutHeight(), 0.0f);

assertEquals(0f, root_child0.getLayoutX(), 0.0f);
assertEquals(0f, root_child0.getLayoutY(), 0.0f);
assertEquals(10f, root_child0.getLayoutWidth(), 0.0f);
assertEquals(10f, root_child0.getLayoutHeight(), 0.0f);

root.setDirection(YogaDirection.RTL);
root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED);

assertEquals(0f, root.getLayoutX(), 0.0f);
assertEquals(0f, root.getLayoutY(), 0.0f);
assertEquals(100f, root.getLayoutWidth(), 0.0f);
assertEquals(100f, root.getLayoutHeight(), 0.0f);

assertEquals(90f, root_child0.getLayoutX(), 0.0f);
assertEquals(0f, root_child0.getLayoutY(), 0.0f);
assertEquals(10f, root_child0.getLayoutWidth(), 0.0f);
assertEquals(10f, root_child0.getLayoutHeight(), 0.0f);
}

@Test
public void test_absolute_layout_width_height_end_bottom() {
YogaConfig config = YogaConfigFactory.create();
Expand Down
4 changes: 4 additions & 0 deletions javascript/src/Node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ void Node::setPositionPercent(int edge, double position) {
YGNodeStyleSetPositionPercent(m_node, static_cast<YGEdge>(edge), position);
}

void Node::setPositionAuto(int edge) {
YGNodeStyleSetPositionAuto(m_node, static_cast<YGEdge>(edge));
}

void Node::setAlignContent(int alignContent) {
YGNodeStyleSetAlignContent(m_node, static_cast<YGAlign>(alignContent));
}
Expand Down
1 change: 1 addition & 0 deletions javascript/src/Node.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class Node {
void setPositionType(int positionType);
void setPosition(int edge, double position);
void setPositionPercent(int edge, double position);
void setPositionAuto(int edge);

void setAlignContent(int alignContent);
void setAlignItems(int alignItems);
Expand Down
1 change: 1 addition & 0 deletions javascript/src/embind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ EMSCRIPTEN_BINDINGS(YOGA_LAYOUT) {
.function("setPositionType", &Node::setPositionType)
.function("setPosition", &Node::setPosition)
.function("setPositionPercent", &Node::setPositionPercent)
.function("setPositionAuto", &Node::setPositionAuto)

.function("setAlignContent", &Node::setAlignContent)
.function("setAlignItems", &Node::setAlignItems)
Expand Down
1 change: 1 addition & 0 deletions javascript/src/wrapAssembly.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ export type Node = {
setPosition(edge: Edge, position: number | `${number}%` | undefined): void;
setPositionPercent(edge: Edge, position: number | undefined): void;
setPositionType(positionType: PositionType): void;
setPositionAuto(edge: Edge): void;
setWidth(width: number | 'auto' | `${number}%` | undefined): void;
setWidthAuto(): void;
setWidthPercent(width: number | undefined): void;
Expand Down
Loading

0 comments on commit 6d6f69b

Please sign in to comment.