Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,14 @@
# default on new configs to preserve the pre-fix geometry. Clear this
# bit to opt into the spec-correct single distribution.
("FlexFirstPassUsesRunningTotals", 1 << 4),
# In the multi-line alignment pass, which runs for wrapping containers
# and for rows with baseline alignment, position items on the cross
# axis without all of their margins and relative insets: `flex-start`
# applies the inset in place of the leading margin, `stretch` and
# `flex-end` drop the inset, and `center` centers the border box.
# Set by default on new configs to preserve the pre-fix geometry.
# Clear this bit to opt into the spec-correct positions.
("WrapCrossAlignmentIgnoresMarginAndInset", 1 << 5),
# Enable all incorrect behavior (preserve compatibility)
("All", 0x7FFFFFFF),
# Enable all errata except for "StretchFlexBasis" (Defaults behavior
Expand Down
6 changes: 6 additions & 0 deletions gentest/fixtures/YGAlignItemsTest.html
Original file line number Diff line number Diff line change
Expand Up @@ -225,3 +225,9 @@
</div>
</div>
</div>

<div id="align_baseline_cross_margin_and_inset" data-errata="None" style="width: 300px; height: 100px; padding: 10px; flex-direction: row; align-items: baseline;">
<div style="width: 50px; height: 60px;"></div>
<div style="width: 50px; height: 20px; margin-top: 5px; top: 10px; align-self: flex-start;"></div>
<div style="width: 50px; height: 20px; bottom: 10px;"></div>
</div>
78 changes: 78 additions & 0 deletions gentest/fixtures/YGFlexWrapTest.html
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,81 @@
<div id="wrap_does_not_impose_min_cross_onto_single_flexline" style="min-height: 400px; flex-direction: row; align-items: stretch; align-content: flex-start; flex-wrap: wrap;">
<div style="flex: 1"></div>
</div>

<div id="wrap_row_cross_margin_and_inset" data-errata="None" style="width: 300px; height: 200px; padding: 10px; flex-direction: row; flex-wrap: wrap;">
<div style="width: 280px; height: 30px;"></div>
<div style="width: 50px; height: 20px; margin: 5px; left: 10px; top: 10px; align-self: flex-start;"></div>
<div style="width: 50px; height: 20px; margin: 5px; left: 10px; top: 10px; align-self: center;"></div>
<div style="width: 50px; height: 20px; margin: 5px; left: 10px; top: 10px; align-self: flex-end;"></div>
<div style="width: 50px; margin: 5px; left: 10px; top: 10px; align-self: stretch;"></div>
<div style="width: 30px; height: 60px;"></div>
</div>

<div id="wrap_reverse_row_cross_margin_and_inset" data-errata="None" style="width: 300px; height: 200px; padding: 10px; flex-direction: row; flex-wrap: wrap-reverse;">
<div style="width: 280px; height: 30px;"></div>
<div style="width: 50px; height: 20px; margin: 5px; left: 10px; top: 10px; align-self: flex-start;"></div>
<div style="width: 50px; height: 20px; margin: 5px; left: 10px; top: 10px; align-self: center;"></div>
<div style="width: 50px; height: 20px; margin: 5px; left: 10px; top: 10px; align-self: flex-end;"></div>
<div style="width: 50px; margin: 5px; left: 10px; top: 10px; align-self: stretch;"></div>
<div style="width: 30px; height: 60px;"></div>
</div>

<div id="wrap_column_cross_margin_and_inset" data-errata="None" style="width: 200px; height: 300px; padding: 10px; flex-wrap: wrap;">
<div style="width: 30px; height: 280px;"></div>
<div style="width: 20px; height: 50px; margin: 5px; left: 10px; top: 10px; align-self: flex-start;"></div>
<div style="width: 20px; height: 50px; margin: 5px; left: 10px; top: 10px; align-self: center;"></div>
<div style="width: 20px; height: 50px; margin: 5px; left: 10px; top: 10px; align-self: flex-end;"></div>
<div style="height: 50px; margin: 5px; left: 10px; top: 10px; align-self: stretch;"></div>
<div style="width: 60px; height: 30px;"></div>
</div>

<div id="wrap_reverse_column_cross_margin_and_inset" data-errata="None" style="width: 200px; height: 300px; padding: 10px; flex-wrap: wrap-reverse;">
<div style="width: 30px; height: 280px;"></div>
<div style="width: 20px; height: 50px; margin: 5px; left: 10px; top: 10px; align-self: flex-start;"></div>
<div style="width: 20px; height: 50px; margin: 5px; left: 10px; top: 10px; align-self: center;"></div>
<div style="width: 20px; height: 50px; margin: 5px; left: 10px; top: 10px; align-self: flex-end;"></div>
<div style="height: 50px; margin: 5px; left: 10px; top: 10px; align-self: stretch;"></div>
<div style="width: 60px; height: 30px;"></div>
</div>

<div id="wrap_reverse_row_cross_margin_top_only" data-errata="None" style="width: 260px; height: 100px; flex-direction: row; flex-wrap: wrap-reverse;">
<div style="width: 50px; height: 40px;"></div>
<div style="width: 50px; height: 20px; margin-top: 10px; align-self: flex-start;"></div>
<div style="width: 50px; height: 20px; margin-top: 10px; align-self: center;"></div>
<div style="width: 50px; height: 20px; margin-top: 10px; align-self: flex-end;"></div>
<div style="width: 50px; margin-top: 10px; align-self: stretch;"></div>
</div>

<div id="wrap_reverse_row_cross_margin_bottom_only" data-errata="None" style="width: 260px; height: 100px; flex-direction: row; flex-wrap: wrap-reverse;">
<div style="width: 50px; height: 40px;"></div>
<div style="width: 50px; height: 20px; margin-bottom: 10px; align-self: flex-start;"></div>
<div style="width: 50px; height: 20px; margin-bottom: 10px; align-self: center;"></div>
<div style="width: 50px; height: 20px; margin-bottom: 10px; align-self: flex-end;"></div>
<div style="width: 50px; margin-bottom: 10px; align-self: stretch;"></div>
</div>

<div id="wrap_reverse_column_cross_margin_left_only" data-errata="None" style="width: 100px; height: 210px; flex-wrap: wrap-reverse;">
<div style="width: 40px; height: 50px;"></div>
<div style="width: 20px; height: 50px; margin-left: 10px; align-self: flex-start;"></div>
<div style="width: 20px; height: 50px; margin-left: 10px; align-self: center;"></div>
<div style="width: 20px; height: 50px; margin-left: 10px; align-self: flex-end;"></div>
</div>

<div id="wrap_column_cross_relative_inset" data-errata="None" style="width: 200px; height: 250px; padding: 10px; flex-wrap: wrap;">
<div style="width: 50px; height: 50px; margin: 5px; left: 10px; top: 10px;"></div>
<div style="width: 50px; height: 50px; margin: 5px;"></div>
<div style="width: 50px; height: 50px; margin: 5px;"></div>
<div style="width: 50px; height: 50px; margin: 5px;"></div>
</div>

<div id="wrap_row_align_items_center_one_sided_cross_margin" data-errata="None" style="width: 300px; flex-direction: row; flex-wrap: wrap; align-items: center;">
<div style="width: 100px; height: 100px; margin-left: 100px; margin-top: 100px;"></div>
</div>

<div id="wrap_static_item_cross_inset" data-errata="None" style="width: 100px; height: 100px; flex-direction: row; flex-wrap: wrap; align-items: flex-start;">
<div style="width: 50px; height: 20px; margin-top: 5px; position: static; top: 10px;"></div>
</div>

<div id="wrap_row_percentage_cross_inset" data-errata="None" style="width: 100px; height: 200px; flex-direction: row; flex-wrap: wrap; align-items: flex-start;">
<div style="width: 50px; height: 20px; top: 10%;"></div>
</div>
2 changes: 2 additions & 0 deletions gentest/src/buildLayoutTree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ export default async function buildLayoutTree(
styleAttr: originalStyles.get(child) || '',
experiments: child.dataset.experiments ? child.dataset.experiments.split(' ') : [],
disabled: child.dataset.disabled === 'true',
errata: child.dataset.errata || null,
innerText: innerText,
children: walkTree(child, rect.left, rect.top)
});
Expand All @@ -93,6 +94,7 @@ interface RawNode {
styleAttr: string;
experiments: string[];
disabled: boolean;
errata: string | null;
innerText: string;
children: RawNode[];
}
1 change: 1 addition & 0 deletions gentest/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ async function processFixture(fixturePath: string): Promise<void> {
rtlLayout: rtlTree[i],
experiments: ltrNode.experiments,
disabled: ltrNode.disabled,
errata: ltrNode.errata,
}));

const cppCode = new CppEmitter().generateFixture(
Expand Down
4 changes: 4 additions & 0 deletions gentest/src/emitters/CppEmitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ export class CppEmitter extends Emitter {
name: string,
experiments: string[],
disabled: boolean,
errata: string | null,
): void {
this.push('TEST(YogaTest, ' + name + ') {');
this.pushIndent();
Expand All @@ -101,6 +102,9 @@ export class CppEmitter extends Emitter {
}

this.push('YGConfigRef config = YGConfigNew();');
if (errata != null) {
this.push('YGConfigSetErrata(config, YGErrata' + errata + ');');
}
for (const experiment of experiments) {
this.push(
'YGConfigSetExperimentalFeatureEnabled(config, YGExperimentalFeature' +
Expand Down
3 changes: 3 additions & 0 deletions gentest/src/emitters/Emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ interface TestCase {
rtlLayout: LayoutNode;
experiments: string[];
disabled: boolean;
errata: string | null;
}

/**
Expand Down Expand Up @@ -70,6 +71,7 @@ export default abstract class Emitter {
name: string,
experiments: string[],
disabled: boolean,
errata: string | null,
): void;
abstract emitTestEpilogue(experiments: string[]): void;
abstract emitTestTreePrologue(nodeName: string): void;
Expand Down Expand Up @@ -138,6 +140,7 @@ export default abstract class Emitter {
testCase.name,
testCase.experiments,
testCase.disabled,
testCase.errata,
);

this.setupTestTree(ltrTree, 'root', null, undefined);
Expand Down
4 changes: 4 additions & 0 deletions gentest/src/emitters/JavaEmitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ export class JavaEmitter extends Emitter {
name: string,
experiments: string[],
disabled: boolean,
errata: string | null,
): void {
this.push('@Test');
if (disabled) {
Expand All @@ -188,6 +189,9 @@ export class JavaEmitter extends Emitter {
this.pushIndent();

this.push('YogaConfig config = YogaConfigFactory.create();');
if (errata != null) {
this.push('config.setErrata(YogaErrata.' + toJavaUpper(errata) + ');');
}
for (const experiment of experiments) {
this.push(
'config.setExperimentalFeatureEnabled(YogaExperimentalFeature.' +
Expand Down
4 changes: 4 additions & 0 deletions gentest/src/emitters/JavascriptEmitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,11 +135,15 @@ export class JavascriptEmitter extends Emitter {
name: string,
experiments: string[],
disabled: boolean,
errata: string | null,
): void {
const testFn = disabled ? 'test.skip' : 'test';
this.push(`${testFn}('${name}', () => {`);
this.pushIndent();
this.push('const config = Yoga.Config.create();');
if (errata != null) {
this.push(`config.setErrata(Errata.${errata});`);
}
this.push('');

if (experiments.length > 0) {
Expand Down
2 changes: 2 additions & 0 deletions gentest/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export interface LayoutNode {
styleAttr: string;
experiments: string[];
disabled: boolean;
errata: string | null;
innerText: string;
children: LayoutNode[];
}
Expand All @@ -38,4 +39,5 @@ export interface TestCase {
styleAttr: string;
experiments: string[];
disabled: boolean;
errata: string | null;
}
2 changes: 2 additions & 0 deletions java/com/facebook/yoga/YogaErrata.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public enum class YogaErrata(public val intValue: Int) {
ABSOLUTE_PERCENT_AGAINST_INNER_SIZE(4),
MIN_SIZE_UNDEFINED_INSTEAD_OF_AUTO(8),
FLEX_FIRST_PASS_USES_RUNNING_TOTALS(16),
WRAP_CROSS_ALIGNMENT_IGNORES_MARGIN_AND_INSET(32),
ALL(2147483647),
CLASSIC(2147483646);

Expand All @@ -31,6 +32,7 @@ public enum class YogaErrata(public val intValue: Int) {
4 -> ABSOLUTE_PERCENT_AGAINST_INNER_SIZE
8 -> MIN_SIZE_UNDEFINED_INSTEAD_OF_AUTO
16 -> FLEX_FIRST_PASS_USES_RUNNING_TOTALS
32 -> WRAP_CROSS_ALIGNMENT_IGNORES_MARGIN_AND_INSET
2147483647 -> ALL
2147483646 -> CLASSIC
else -> throw IllegalArgumentException("Unknown enum value: $value")
Expand Down
80 changes: 79 additions & 1 deletion java/tests/generated/com/facebook/yoga/YGAlignItemsTest.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<<56bad92abb0a9a39d9e964bf4d5b2c48>>
* @generated SignedSource<<1cc22c5fca31b58563e5ce68b6ab24e8>>
* generated by gentest/src/GentestDriver.ts from gentest/fixtures/YGAlignItemsTest.html
*/

Expand Down Expand Up @@ -2126,6 +2126,84 @@ public void test_align_items_non_stretch_s526008() {
assertEquals(10f, root_child0_child0_child0_child0.getLayoutHeight(), 0.0f);
}

@Test
public void test_align_baseline_cross_margin_and_inset() {
YogaConfig config = YogaConfigFactory.create();
config.setErrata(YogaErrata.NONE);

final YogaNode root = createNode(config);
root.setPositionType(YogaPositionType.ABSOLUTE);
root.setWidth(300f);
root.setHeight(100f);
root.setPadding(YogaEdge.ALL, 10);
root.setFlexDirection(YogaFlexDirection.ROW);
root.setAlignItems(YogaAlign.BASELINE);

final YogaNode root_child0 = createNode(config);
root_child0.setWidth(50f);
root_child0.setHeight(60f);
root.addChildAt(root_child0, 0);

final YogaNode root_child1 = createNode(config);
root_child1.setWidth(50f);
root_child1.setHeight(20f);
root_child1.setMargin(YogaEdge.TOP, 5f);
root_child1.setPosition(YogaEdge.TOP, 10f);
root_child1.setAlignSelf(YogaAlign.FLEX_START);
root.addChildAt(root_child1, 1);

final YogaNode root_child2 = createNode(config);
root_child2.setWidth(50f);
root_child2.setHeight(20f);
root_child2.setPosition(YogaEdge.BOTTOM, 10f);
root.addChildAt(root_child2, 2);
root.setDirection(YogaDirection.LTR);
root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED);

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

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

assertEquals(60f, root_child1.getLayoutX(), 0.0f);
assertEquals(25f, root_child1.getLayoutY(), 0.0f);
assertEquals(50f, root_child1.getLayoutWidth(), 0.0f);
assertEquals(20f, root_child1.getLayoutHeight(), 0.0f);

assertEquals(110f, root_child2.getLayoutX(), 0.0f);
assertEquals(40f, root_child2.getLayoutY(), 0.0f);
assertEquals(50f, root_child2.getLayoutWidth(), 0.0f);
assertEquals(20f, root_child2.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(300f, root.getLayoutWidth(), 0.0f);
assertEquals(100f, root.getLayoutHeight(), 0.0f);

assertEquals(240f, root_child0.getLayoutX(), 0.0f);
assertEquals(10f, root_child0.getLayoutY(), 0.0f);
assertEquals(50f, root_child0.getLayoutWidth(), 0.0f);
assertEquals(60f, root_child0.getLayoutHeight(), 0.0f);

assertEquals(190f, root_child1.getLayoutX(), 0.0f);
assertEquals(25f, root_child1.getLayoutY(), 0.0f);
assertEquals(50f, root_child1.getLayoutWidth(), 0.0f);
assertEquals(20f, root_child1.getLayoutHeight(), 0.0f);

assertEquals(140f, root_child2.getLayoutX(), 0.0f);
assertEquals(40f, root_child2.getLayoutY(), 0.0f);
assertEquals(50f, root_child2.getLayoutWidth(), 0.0f);
assertEquals(20f, root_child2.getLayoutHeight(), 0.0f);
}

private YogaNode createNode(YogaConfig config) {
return mNodeFactory.create(config);
}
Expand Down
Loading
Loading