Commit Graph

2593 Commits

Author SHA1 Message Date
Nick Gerleman
1232761571 YGPersistentNodeCloningTest (#1813)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1813

This adds a unit test to Yoga, which emulates the model of "persistent Yoga nodes" and cloning used by React Fabric, including the private (but relied on) Yoga APIs.

It models the over-invalidation exposed in D75287261, which reproduces (due to Yoga incorrectly measuring flex-basis under fit-content, and that constraint changing when sibling changes) but this test for now sets a definite height on A, to show that we only clone what is neccesary, when measure constraints do not have to change.

Having a minimal version of Fabric's model in Yoga unit tests should make some of these interesting interactions a bit easier to debug.

Changelog: [Internal]

Reviewed By: javache

Differential Revision: D75572762

fbshipit-source-id: cda8b3fdd6e538a55dd100494518688c864bd233
2025-06-02 19:32:45 -07:00
Nick Gerleman
c935fd5e10 Resubmit: Expose Unsnapped Dimensions (#1811)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1811

X-link: https://github.com/facebook/react-native/pull/51298

## Resubmit

This was backed out due to being up the stack from another change that was backed out, but should be safe by itself.

## Original

We want to know if an artifact created during measurement can fully be reused after final layout, but the final layout is allowed to be slightly larger due to pixel grid rounding (while still allowing reuse). It's hard to tell after the fact, whether it is larger because of this rounding (though the measure is used), or if it may be a pixel larger for valid reasons.

We can expose the unsnapped dimensions of a node to give us this information, and to correlate measurement artifacts.

This is most of the time the same as the layout's measured dimension, though I don't think it's safe to use this, since anything else measuring the node after could clobber this (I think `YGNodeLayoutGetOverflow` may also be prone to this as a bug).

Changelog: [Internal]

Reviewed By: joevilches

Differential Revision: D74673119

fbshipit-source-id: 06d2eb21e28b76458ec88f4dfcaec809707d0390
2025-05-13 18:21:04 -07:00
Yannick Loriot
624325302c Revert D74292949: Expose Unsnapped Dimensions
Differential Revision:
D74292949

Original commit changeset: 05011c66a9a9

Original Phabricator Diff: D74292949

fbshipit-source-id: c6ca51c7b882950d54b6a43e206973774db40429
2025-05-09 01:45:16 -07:00
Nick Gerleman
37a94a86de Expose Unsnapped Dimensions (#1809)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1809

X-link: https://github.com/facebook/react-native/pull/51181

We want to know if an artifact created during measurement can fully be reused after final layout, but the final layout is allowed to be slightly larger due to pixel grid rounding (while still allowing reuse). It's hard to tell after the fact, whether it is larger because of this rounding (though the measure is used), or if it may be a pixel larger for valid reasons.

We can expose the unsnapped dimensions of a node to give us this information, and to correlate measurement artifacts.

This is most of the time the same as the layout's measured dimension, though I don't think it's safe to use this, since anything else measuring the node after could clobber this (I think `YGNodeLayoutGetOverflow` may also be prone to this as a bug).

Changelog: [Internal]

Reviewed By: rshest

Differential Revision: D74292949

fbshipit-source-id: 05011c66a9a9480544313eb1dfe2c46bf7742bac
2025-05-08 17:45:16 -07:00
Santhosh Kumar
4abc1a7d5f Fix documentation of 'alignContent' property configured with spaces (#1808)
Summary:
The documentation shall be corrected to specify in which axis the spaces are distributed when flex container is configured 'alignContent' property.

Pull Request resolved: https://github.com/facebook/yoga/pull/1808

Reviewed By: joevilches

Differential Revision: D74347272

Pulled By: philIip

fbshipit-source-id: 1b05840028bca774c9d4a68562bcf537d5a72500
2025-05-07 14:40:02 -07:00
Yurii Nakonechnyi
51e6095005 LayoutData - added explicit default fields values initialization (#1802)
Summary:
X-link: https://github.com/facebook/react-native/pull/50227

Explicit defaults add 'strictness' and take the guesswork out of what's going on in places like this:

6455a848a7/yoga/algorithm/CalculateLayout.cpp (L2345)

Changelog: [Internal]

Pull Request resolved: https://github.com/facebook/yoga/pull/1802

Reviewed By: javache

Differential Revision: D71687310

Pulled By: NickGerleman

fbshipit-source-id: f11d18aa68ce7ccd17fb1d5af0e729e8c0711cf9
2025-03-24 12:23:46 -07:00
Yurii Nakonechnyi
79cef614ce fatalWithMessage() - added warning suppression: unused 'message' argument (#1803)
Summary:
X-link: https://github.com/facebook/react-native/pull/50148

## Changelog:

[Internal] - suppression: unused 'message' argument

Pull Request resolved: https://github.com/facebook/yoga/pull/1803

Reviewed By: NickGerleman

Differential Revision: D71492528

Pulled By: lunaleaps

fbshipit-source-id: 6fc7a665066351d15e09f0b6c82ed1fe3f688a94
2025-03-19 19:06:50 -07:00
Rob Hogan
6455a848a7 Update GHA actions/upload-artifact to v4, unbreak CI (#1799)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1799

Pull Request resolved: https://github.com/facebook/yoga/pull/1800

`actions/upload-artifact@v3` is deprecated and will no longer execute, causing CI to fail - eg:

https://github.com/facebook/yoga/actions/runs/13789185831/job/38564343959

See https://github.blog/changelog/2024-04-16-deprecation-notice-v3-of-the-artifact-actions/ for context

Reviewed By: NickGerleman

Differential Revision: D70986391

fbshipit-source-id: 66cec50bb485e89c0948c752ba7dc2a4f42617d6
2025-03-11 13:40:51 -07:00
Nicola Corti
1b7d2c8d48 Enable RTTI to fix exception pointer issue on React Native (#1791)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1791

Disabling RTTI for Yoga is causing std::exception to don't work properly in OSS.
Fixes: https://github.com/facebook/react-native/issues/48027

Not sure why we originally disabled RTTI for Yoga, but we have it enable for the whole
React Native build so it probably makes sense to have it enabled for Yoga as well.

Changelog:
[Internal] [Changed] - Enable RTTI to fix exception pointer issue on React Native

bypass-github-export-checks

Reviewed By: javache, NickGerleman

Differential Revision: D70386744

fbshipit-source-id: 36e3a1ddb38346d31979d5c1b77d6e9796d6a855
2025-03-04 04:51:38 -08:00
Nicola Corti
3aa594c1f9 Gradle to 8.13 (#1790)
Summary:
X-link: https://github.com/facebook/react-native/pull/49689

Pull Request resolved: https://github.com/facebook/yoga/pull/1790

X-link: https://github.com/facebook/react-native/pull/49703

I'm bumping Gradle to the latest minor.
https://docs.gradle.org/8.13/release-notes.html

I'm also changing the distribution from `all` to `bin` as
this reduces the download time of the distribution.

Changelog:
[Android] [Changed] - Gradle to 8.13

Reviewed By: NickGerleman

Differential Revision: D70239710

fbshipit-source-id: 89808242a93344f540bfe82f4178cf6db72597d1
2025-02-27 03:13:26 -08:00
Mihaela Ogrezeanu
c2ae39167e Update yoga aar targets (#1786)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1786

Follow up on comments from D68152410

- Removes minsdk version from manifest
- Update to MIT licence
- Rename targets that don't export existing libs

I've looked into using yoga_java_library and adding a param to pass what libs to exclude, but ultimately provided_deps does what we need and it simpler to maintain; we still need to add the different targets because the aar needs to depend on :jni-server and not :jni.

Reviewed By: NickGerleman

Differential Revision: D69455682

fbshipit-source-id: aa08bc030495d13da9545ec368ab63a7a946dad0
2025-02-12 02:28:59 -08:00
Mihaela Ogrezeanu
49ee855f99 Add aar BUCK targets to export Litho libraries as aars (#1782)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1782

This adds fb_native.android_aar targets for resources that are needed by Litho at runtime and cannot be exported as jars.
- resource modules referenced by Litho
- Yoga library. Some dependencies required by Yoga neded to be added as "provided_deps" so they don't get exported with the aar

Reviewed By: astreet

Differential Revision: D68152410

fbshipit-source-id: 7dc2ffa0b60a4ca160a011d16d2dc5ab91f608a6
2025-01-24 07:57:56 -08:00
Nick Gerleman
b12e0a2a15 Fix CI after GHA Update to Ubuntu 24.04 (#1781)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1781

This new image removed preinstalled libc++, and the ability to install old version of Clang Format we were installing.

This manually installs libc++ when setting up Clang jobs, and fully removes the clang-format validation job, since it wasn't correctly running before, and it's probably more a pain to ask people to run this than to just run Arcanist when importing a change.

Changelog: [Internal]

Reviewed By: joevilches

Differential Revision: D68455129

fbshipit-source-id: b5767be832b2b5d46db7e60e18b66823819ba15a
2025-01-21 13:34:22 -08:00
Ruslan Shestopalyuk
9591210a7a Add more unit tests for rounding values to pixel grid (#1776)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1776

# Changelog:
[Internal] -

I was looking into some profiling results and noticed that Yoga has some quirky custom logic when it comes to rounding to the pixel grid, especially for the values that are halfway through.

There are already unit tests in place, but those cases weren't covered, so I am adding these extra corner cases here, to make sure they are covered in case that the actual rounding function may get modified (which it might make sense to, as it's currently can be more expensive than it could have been in some scenarios).

Reviewed By: christophpurrer

Differential Revision: D67712673

fbshipit-source-id: da1b7339a8939ced8d91f15441bc7d1f8af768c8
2024-12-30 12:38:48 -08:00
Ruslan Shestopalyuk
91997d6cd3 Avoid calling fmod twice in roundLayoutResultsToPixelGrid (#1775)
Summary:
X-link: https://github.com/facebook/litho/pull/1036

Pull Request resolved: https://github.com/facebook/yoga/pull/1775

X-link: https://github.com/facebook/react-native/pull/48404

## Changelog:
[Internal] -

This popped up when profiling some heavy UI performance, calling `fmod` operation in Yoga's `roundLayoutResultsToPixelGrid` in `PixelGrid.cpp` can be expensive, furthermore it turns out that some of the calls were redundant.

This replaces the duplicate calls to fmod with an equivalent single round operation, which for e.g. clang compiler on Windows brings the code in question from ~50 instructions (including 4 call instructions to the fmod function) down to ~30 instructions (without any external calls), and the layout operation being **~1% more efficient** for the particular benchmark I was looking into.

Reviewed By: christophpurrer

Differential Revision: D67689065

fbshipit-source-id: 2a074a1cb81bd7f7a3c414050b9ddda2ba90180f
2024-12-30 12:38:48 -08:00
Joe Vilches
909e4bea6e Fix test util to measure text properly based on flex direction (#1768)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1768

Depending on the flex direction text will either be capped to the measured size or to the longest word, so I added that functionality

Reviewed By: mlord93

Differential Revision: D67106199

fbshipit-source-id: 0b4691768809004043a847f3fc5f7b94e92f1575
2024-12-12 11:11:49 -08:00
Nicola Corti
13f4adbbcd Add 16K support for standalone Yoga (#1766)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1766

While we added support for 16K pages for yoga through React Native,
the standalone version we upload to Maven Central wasn't handled.
This fixes it.

Reviewed By: NickGerleman

Differential Revision: D66975933

fbshipit-source-id: 36a8404e2f2a60a44b9a39e478b23d1829bc542e
2024-12-10 09:34:38 -08:00
heoblitz
ae2d06d0f5 Update YGNodeStyleGetGap to return YGValue (#1753)
Summary:
X-link: https://github.com/facebook/react-native/pull/47973

Gap can be styled using both `points` and `percentages`, but YGNodeStyleGetGap currently returns a float value.

To maintain alignment with the `padding` and `margin` functionalities and allow it to be handled in bridging code, this function has been updated to return YGValue.

Pull Request resolved: https://github.com/facebook/yoga/pull/1753

Reviewed By: joevilches

Differential Revision: D66513236

Pulled By: NickGerleman

fbshipit-source-id: b7110855c037f20780f031f22a945bde4446687d
2024-12-09 13:38:05 -08:00
Joe Vilches
5478812db3 Use crossAxisOwnerSize instead of ownerHeight in cross axis bound call (#1763)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1763

X-link: https://github.com/facebook/react-native/pull/48080

Small bug that I noticed while doing intrinsic sizing. We have the ownerHeight as the axis size despite bounding the length of the cross axis. This should therefore be the crossAxisOwnerSize, which might be the width in some cases

Changelog: [Internal]

Reviewed By: NickGerleman

Differential Revision: D66736539

fbshipit-source-id: 528fc438b3327cd6f7890ea0ba408e4ce7b0f02c
2024-12-06 15:34:06 -08:00
Joe Vilches
050ac8a413 Properly camelcase mainAxisownerSize in FlexLine (#1762)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1762

X-link: https://github.com/facebook/react-native/pull/48077

OCD strikes again. Grepped this time to make sure we didn't miss any cases for this specific param name

Changelog: [Internal]

Reviewed By: NickGerleman

Differential Revision: D66715777

fbshipit-source-id: 3e881a15b3b2836a4a55b11d7ec621541b92a05d
2024-12-03 19:16:56 -08:00
Nick Gerleman
733ba24064 Add Yoga 3.2 Release notes (#1761)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1761

Whips up some release notes for what is new since Yoga 3.1.

https://github.com/facebook/yoga/compare/v3.1.0...v3.2.0

The relevant packages have already been published.

Reviewed By: joevilches

Differential Revision: D66679637

fbshipit-source-id: dd94e2a52f2bdc80541c331d1fb39de82669cc7a
2024-12-02 17:39:41 -08:00
Joe Vilches
e177477144 Add text based intrinsic sizing tests (#1759)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1759

We just have block based tests right now. Intrinsic sizing is commonly used with text so lets add a few there.

Reviewed By: NickGerleman

Differential Revision: D66662940

fbshipit-source-id: f8b91419c89d22d79a91d3bd8c7da70429c827fb
2024-12-02 17:29:49 -08:00
Joe Vilches
76ffdbc25d Back out "Back out "[yoga][gentest][intrinsic sizing] Gentest and initial tests for intrinsic sizing"" (#1758)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1758

Original commit changeset: 52d6cc754cb9

Original Phabricator Diff: D66332308

Reviewed By: NickGerleman

Differential Revision: D66662663

fbshipit-source-id: fb3a0d10ec0f0149aeee510148f26ada8eff7e47
2024-12-02 17:29:49 -08:00
Joe Vilches
f99e657acd Back out "Back out "[yoga][intrinsic sizing] Update public API for intrinsic sizing setters""
Summary:
Original commit changeset: 793f77dad021

Original Phabricator Diff: D66332309

Changelog: [Internal]

Reviewed By: NickGerleman

Differential Revision: D66662661

fbshipit-source-id: 22ed3ac9492f0a563c041ce4cb5fba4b65b53211
2024-12-02 17:29:49 -08:00
Joe Vilches
a9246bc7db Back out "Back out "[yoga][intrinsic sizing] Modify private apis to set, store, and get intrinsic sizing keywords"" (#1756)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1756

X-link: https://github.com/facebook/react-native/pull/48049

Changelog: [Internal]

Original commit changeset: 1d596964e0c8

Original Phabricator Diff: D66332307

Reviewed By: NickGerleman

Differential Revision: D66662662

fbshipit-source-id: 4f9ac2b1557b848f519dcd728d7097b52f1190b3
2024-12-02 17:29:49 -08:00
Joe Vilches
be72b8e8aa Align order of params between calculateLayoutInternal and calculateLayoutImpl (#1755)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1755

X-link: https://github.com/facebook/react-native/pull/47975

I've been working with callsites here and its annoying if you switch these that you need to move these params around too. Let's just make them the same order

Changelog: [Internal]

Reviewed By: NickGerleman

Differential Revision: D66519836

fbshipit-source-id: 2e98e671270a053c6e62372e2003f1ca67774ec9
2024-11-26 22:48:24 -08:00
Joe Vilches
b876f596d9 Camel case LengthValue in Node.cpp (#1754)
Summary:
X-link: https://github.com/facebook/react-native/pull/47971

Pull Request resolved: https://github.com/facebook/yoga/pull/1754

This was annoying me

Changelog: [Internal]

Reviewed By: NickGerleman

Differential Revision: D66510734

fbshipit-source-id: d1b952f2e82e7018b16dc0c572d9b98aec18c0e5
2024-11-26 15:23:08 -08:00
Joe Vilches
be00354b71 Back out "Modify private apis to set, store, and get intrinsic sizing keywords" (#1750)
Summary:
X-link: https://github.com/facebook/react-native/pull/47895

Pull Request resolved: https://github.com/facebook/yoga/pull/1750

These APIs were only added so that we could do TDD as we work on intrinsic sizing functionality. As of right now they do nothing. We are aiming on publishing a new version of Yoga soon so for the time being we are going to back these out so as not to confuse anyone with this new functionality. Ideally we get to a point where we have some temporary experimental header to stage these in but this is a bit time sensitive so just backing out for now

Changelog: [Internal]

Reviewed By: NickGerleman

Differential Revision: D66332307

fbshipit-source-id: 1d596964e0c893091c541988506e8b80fa6d1957
2024-11-25 00:40:03 -08:00
Joe Vilches
0c995496c8 Back out "Update public API for intrinsic sizing setters" (#1752)
Summary:
X-link: https://github.com/facebook/react-native/pull/47896

Pull Request resolved: https://github.com/facebook/yoga/pull/1752

These APIs were only added so that we could do TDD as we work on intrinsic sizing functionality. As of right now they do nothing. We are aiming on publishing a new version of Yoga soon so for the time being we are going to back these out so as not to confuse anyone with this new functionality. Ideally we get to a point where we have some temporary experimental header to stage these in but this is a bit time sensitive so just backing out for now

Changelog: [Internal]

Reviewed By: NickGerleman

Differential Revision: D66332309

fbshipit-source-id: 793f77dad021fa5e57b52c36ae954307636bcbf0
2024-11-25 00:40:03 -08:00
Joe Vilches
c12e732fab Back out "Gentest and initial tests for intrinsic sizing" (#1751)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1751

Original commit changeset: 1e3e7214fab0

Original Phabricator Diff: D64145117

Reviewed By: NickGerleman

Differential Revision: D66332308

fbshipit-source-id: 52d6cc754cb931e851e444bac2c946907a098235
2024-11-25 00:40:03 -08:00
Eric Rozell
0b25796676 Update docusaurus to 3.6.0 (#1749)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1749

Resolves a few NPM security vulnerabilities in webpack and cookie dependencies.

Reviewed By: NickGerleman

Differential Revision: D66299077

fbshipit-source-id: 805eff24486ab120bc5658c0c5d0de1e4db81ba0
2024-11-21 11:09:17 -08:00
Jakub Piasecki
262f868ce0 Fix the nodes' owners not being updated when display: contents is used (#1743)
Summary:
X-link: https://github.com/facebook/react-native/pull/47733

In https://github.com/facebook/yoga/pull/1729 I moved the cleanup of `display: contents` nodes to happen before all the early returns, but that change also made it be called **before** `cloneChildrenIfNeeded`. It actually needs to be called after `cloneChildrenIfNeeded` to make sure that children of `display: contents` nodes are properly owned.

It also needs to be called in every short-path, so it's being called in four places in this PR. Please let me know whether it's ok or not.

Pull Request resolved: https://github.com/facebook/yoga/pull/1743

Reviewed By: NickGerleman

Differential Revision: D65953902

Pulled By: zeyap

fbshipit-source-id: 0b18a5651f19c23564f5b3aa2a50833426e9ca5f
2024-11-20 20:01:50 -08:00
phuccvx12
77c9987012 Fix: Correct Layout Behavior for Combined align-content and align-items (#1742)
Summary:
X-link: https://github.com/facebook/react-native/pull/47732

This pull request addresses the issue where combining align-content and align-items properties resulted in incorrect layout behavior in Yoga version 3.1.0, as reported in [Issue https://github.com/facebook/yoga/issues/1739](https://github.com/facebook/yoga/issues/1739).

# Changes Made:

Alignment Logic Update: Modified the alignment calculations to ensure that the combination of align-content and align-items properties produces the expected layout, consistent with CSS Flexbox standards and previous Yoga versions.

Test Cases Added: Introduced new test cases to cover scenarios involving various combinations of align-content and align-items properties to prevent future regressions.

# Testing:

All existing tests pass successfully.

New test cases confirm that the layout behaves as expected when align-content and align-items are used together.

# Impact:

This fix ensures that layouts using both align-content and align-items properties render correctly, aligning with the behavior observed in Yoga version 1.19.0 and standard web browsers.

Pull Request resolved: https://github.com/facebook/yoga/pull/1742

Reviewed By: joevilches

Differential Revision: D65953882

Pulled By: zeyap

fbshipit-source-id: 7e12a21b1d442b35c3f3536cad32dc4b82130d15
2024-11-20 19:59:42 -08:00
Joe Vilches
26b21ae23c Update some Justify tests following Chrome changes (#1746)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1746

Chrome made some changes for how overflowed row-reverse containers are laid out which was causing some issues on CI. I updated them here and skipped the new failing tests which we would want to followup on.

For LTR, the differences are seen below
|Before|After|
|--|
|{F1962694149} | {F1962694151}|

The extra space is now extending past the flex start edge vs flex end. RTL is the opposite. NickGerleman had deviated from the spec back in the day to match Chrome and it seems they made the adjustment recently. T208209388 is tracking the followup to align with the spec again. Basically, there is a notion of fallback alignment when certain justification/alignment values cannot actually apply. Right now we are falling back to flex start in all cases but we should fallback to start sometimes.

Changelog: [Internal]

Reviewed By: NickGerleman

Differential Revision: D66138361

fbshipit-source-id: c46d2e9b0cd297069b9cc544e3bded995e4867a6
2024-11-19 15:43:04 -08:00
Eric Rozell
5b962c0801 Revert "Extra log for case where availableHeight is undefined and sizing mode != max content (#1687)" (#1741)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1741

X-link: https://github.com/facebook/react-native/pull/47581

Reverting https://github.com/facebook/yoga/pull/1687 as it appears to regress Yoga performance anywhere from 10-33%.

## Changelog

[Internal]

Reviewed By: rshest

Differential Revision: D65863569

fbshipit-source-id: e6992e05dd59ba75548a5d633cb7f5c3fa99a6e4
2024-11-13 06:29:35 -08:00
Nick Gerleman
8f69ac776e Minor display: contents optimizations (#1736)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1736

X-link: https://github.com/facebook/react-native/pull/47358

`LayoutableChildren<yoga::Node>::Iterator` showed up to a surprising extent on a recent trace. Part of this was during pixel grid rounding, which does full tree traversal (we should fix that...), where the iterator is the first thing to read from the node.

I ran Yoga microbenchmark with Yoga compiled with `-O2`, where we saw a regression of synthetic performance by ~10%, but it turns out this build also had ASAN and some other heavy bits enabled, so the real impact was quite lower (~6%).

I was able to make some optimizations in the meantime against that, which still show some minor wins, reducing that overhead to ~4% in the properly optimized build (and a bit more before that). This is still measurable on the beefy server, and the code is a bit cleaner, so let's commit these!

Note that, in real scenarios, measure functions may dominate layout time, so display: contents does not mean end-to-end 4% regression, even after this change.

This change makes a few different optimizations
1. Removes redundant copies
2. Removes redundant index keeping
3. Mark which branches are likely vs unlikely
4. Shrink iterator size from 6 pointers to 3 pointers
5. Avoid usage in pixel grid rounding (so we don't need to have cache read for style)

In "Huge nested layout" example

| Before display: contents support | After display: contents support | After optimizations |
| 9.77ms | 10.39ms | 10.17ms |

Changelog: [Internal]

Reviewed By: rozele

Differential Revision: D65336148

fbshipit-source-id: 01c592771ed7accf2d87dddd5a3a9e0225098b56
2024-11-05 11:28:37 -08:00
Joe Vilches
867bfae3a3 Gentest and initial tests for intrinsic sizing (#1723)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1723

Adds gentest support for intrinsic sizing keywords and creates an initial batch of somewhat interesting tests for these keywords on `width`, `height`, `min-width`, `min-height`, `max-width`, `max-height`, and `flex-basis`

Reviewed By: NickGerleman

Differential Revision: D64145117

fbshipit-source-id: 1e3e7214fab062ab6f260cfe7bdfaf3c0aca3bf7
2024-11-04 16:02:37 -08:00
Joe Vilches
488288e291 Update public API for intrinsic sizing setters (#1722)
Summary:
X-link: https://github.com/facebook/react-native/pull/46939

Pull Request resolved: https://github.com/facebook/yoga/pull/1722

tsia! opted for one function for each keyword just like auto. This is kinda annoying and not the most sustainable, so maybe it makes more sense to make a new enum here and just add one function

Changelog: [Internal]

Reviewed By: NickGerleman

Differential Revision: D64002837

fbshipit-source-id: f15fae9fc0103175e1d85850fc9aa68579989fd3
2024-11-04 16:02:37 -08:00
Joe Vilches
f52ec78584 Modify private apis to set, store, and get intrinsic sizing keywords (#1721)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1721

X-link: https://github.com/facebook/react-native/pull/46938

The private internals of how we store styles needed to change a bit to support 3 new keyword values. Right now the only other keyword that can be stored is `auto`. As a result there isn't much fancy logic to support storing this and its just stored as a specific type inside of `StyleValueHandle`. There are only 3 bits for types (8 values), so it is not sustainable to just stuff every keyword in there. So the change writes the keyword as a value with a new `keyword` `Type`.

I chose not to put `auto` in there even though it is a keyword since it is a hot path, I did not want to regress perf when I did not need to.

I also make a new `StyleSizeValue` class to store size values - so values for `width`, `height`, etc. This way these new keywords are kept specific to sizes and we will not be able to create, for example, a margin: `max-content`.

Changelog: [Internal]

Reviewed By: NickGerleman

Differential Revision: D63927512

fbshipit-source-id: 7285469d37ac4b05226183b56275c77f0c06996c
2024-11-04 16:02:37 -08:00
Jakub Piasecki
6fed4dfe30 Add tests for LayoutableChildren iterator (#1731)
Summary:
Adds unit tests that directly cover the order in which `LayoutableChildren` iterator goes over the descendant nodes. The covered cases are as follows (nodes with `display: contents` are marked green):

### Single `display: contents` node

```mermaid
flowchart TD
R((R)) --> A((A))
R --> B((B))
R --> C((C))

B --> D((D))
B --> E((E))

style B fill:https://github.com/facebook/yoga/issues/090
```

Correct order: `A, D, E, C`

### Multiple `display: contents` nodes

```mermaid
flowchart TD
R((R)) --> A((A))
R --> B((B))
R --> C((C))

A --> D((D))
A --> E((E))

B --> F((F))
B --> G((G))

C --> H((H))
C --> I((I))

style A fill:https://github.com/facebook/yoga/issues/090
style B fill:https://github.com/facebook/yoga/issues/090
style C fill:https://github.com/facebook/yoga/issues/090
```

Correct order: `D, E, F, G, H, I`

### Nested `display: contents` nodes

```mermaid
flowchart TD
R((R)) --> A((A))
R --> B((B))
R --> C((C))

B --> D((D))
B --> E((E))

E --> F((F))
E --> G((G))

style B fill:https://github.com/facebook/yoga/issues/090
style E fill:https://github.com/facebook/yoga/issues/090
```

Correct order: `A, D, F, G, C`

### Leaf `display: contents` node

```mermaid
flowchart TD
R((R)) --> A((A))
R --> B((B))
R --> C((C))

style B fill:https://github.com/facebook/yoga/issues/090
```

Correct order: `A, C`

### Root `display: contents` node

```mermaid
flowchart TD
R((R)) --> A((A))
R --> B((B))
R --> C((C))

style R fill:https://github.com/facebook/yoga/issues/090
```

Correct order: `A, B, C` - `LayoutableChildren` goes over the children with `display: contents` property, setting it on the root node should have no effect.

Changelog: [Internal]

Pull Request resolved: https://github.com/facebook/yoga/pull/1731

Reviewed By: joevilches

Differential Revision: D64981779

Pulled By: NickGerleman

fbshipit-source-id: ee39759c663a40f96ad313f1b775d53ab68fb442
2024-10-25 18:01:20 -07:00
Jakub Piasecki
8dc2fa52c1 Fix for nodes with display: contents not being cleaned in some cases (#1729)
Summary:
X-link: https://github.com/facebook/react-native/pull/47194

Fixes a case where a node with `display: contents` would not be cleaned up in some cases. This was caused by it being called after some early returns handling different quick paths. This PR moves the call to `cleanupContentsNodesRecursively` earlier so that it's always called.

The problem here wasn't mutating before cloning, but leaving a node marked as dirty after the layout has finished.

The exact case in which I found this was a node with a single `display: contents` child which needs to be a leaf. Then in the parent node [this](b0b842d5e7/yoga/algorithm/CalculateLayout.cpp (L1339)) condition is true, so `cleanupContentsNodesRecursively` doesn't get called and the child node is never visited and cleaned. I assume the same will happen in the other paths with an early return here.

Changelog:
[General][Fixed] - Fix for nodes with `display: contents` not being cleaned in some cases

Pull Request resolved: https://github.com/facebook/yoga/pull/1729

Reviewed By: rozele

Differential Revision: D64910099

Pulled By: NickGerleman

fbshipit-source-id: 6d56f8fbf687b7ee5af889c0b868406213c9cee8
2024-10-25 17:34:36 -07:00
Alan Lee
e696b8c456 Bump to Gradle 8.9, AGP 8.7.1 and NDK 27
Summary:
Bumping Gradle to 8.9 and NDK to 27.1.12297006 in prep to build native libraries with 16KB page size support

See:
- Changelog r27: https://github.com/android/ndk/wiki/Changelog-r27
- 16KB page sizes: https://developer.android.com/guide/practices/page-sizes

Changelog:
[Android][Updated] - Bump Gradle to 8.9, AGP to 8.7.1 and NDK to 27

Reviewed By: cortinico

Differential Revision: D64381441

fbshipit-source-id: 5e4236c166568a3990deabfd628f0f34e52ea855
2024-10-24 13:34:03 -07:00
Jakub Piasecki
68bb2343d2 Add support for display: contents style (#1726)
Summary:
X-link: https://github.com/facebook/react-native/pull/47035

This PR adds support for `display: contents` style by effectively skipping nodes with `display: contents` set during layout.

This required changes in the logic related to children traversal - before this PR a node would be always laid out in the context of its direct parent. After this PR that assumption is no longer true - `display: contents` allows nodes to be skipped, i.e.:

```html
<div id="node1">
  <div id="node2" style="display: contents;">
    <div id="node3" />
  </div>
</div>
```

`node3` will be laid out as if it were a child of `node1`.

Because of this, iterating over direct children of a node is no longer correct to achieve the correct layout. This PR introduces `LayoutableChildren::Iterator` which can traverse the subtree of a given node in a way that nodes with `display: contents` are replaced with their concrete children.

A tree like this:
```mermaid
flowchart TD
    A((A))
    B((B))
    C((C))
    D((D))
    E((E))
    F((F))
    G((G))
    H((H))
    I((I))
    J((J))

    A --> B
    A --> C
    B --> D
    B --> E
    C --> F
    D --> G
    F --> H
    G --> I
    H --> J

    style B fill:https://github.com/facebook/yoga/issues/050
    style C fill:https://github.com/facebook/yoga/issues/050
    style D fill:https://github.com/facebook/yoga/issues/050
    style H fill:https://github.com/facebook/yoga/issues/050
    style I fill:https://github.com/facebook/yoga/issues/050
```

would be laid out as if the green nodes (ones with `display: contents`) did not exist. It also changes the logic where children were accessed by index to use the iterator instead as random access would be non-trivial to implement and it's not really necessary - the iteration was always sequential and indices were only used as boundaries.

There's one place where knowledge of layoutable children is required to calculate the gap. An optimization for this is for a node to keep a counter of how many `display: contents` nodes are its children. If there are none, a short path of just returning the size of the children vector can be taken, otherwise it needs to iterate over layoutable children and count them, since the structure may be complex.

One more major change this PR introduces is `cleanupContentsNodesRecursively`. Since nodes with `display: contents` would be entirely skipped during the layout pass, they would keep previous metrics, would be kept as dirty, and, in the case of nested `contents` nodes, would not be cloned, breaking `doesOwn` relation. All of this is handled in the new method which clones `contents` nodes recursively, sets empty layout, and marks them as clean and having a new layout so that it can be used on the React Native side.

Relies on https://github.com/facebook/yoga/pull/1725

Changelog: [Internal]

Pull Request resolved: https://github.com/facebook/yoga/pull/1726

Test Plan: Added tests for `display: contents` based on existing tests for `display: none` and ensured that all the tests were passing.

Reviewed By: joevilches

Differential Revision: D64404340

Pulled By: NickGerleman

fbshipit-source-id: f6f6e9a6fad82873f18c8a0ead58aad897df5d09
2024-10-18 22:05:41 -07:00
Nick Gerleman
568718242d Remove legacy absolute positioning path (#1725)
Summary:
X-link: https://github.com/facebook/react-native/pull/46984

Pull Request resolved: https://github.com/facebook/yoga/pull/1725

The legacy (wrong) absolute positioning path positions in two places, including work that is definitely always overwritten in the new absolute layout path.

This came up before for position: static, but we didn't clean this up at the time. This code is also now leading display: contents impl being more annoying.

This diff tries to converge to the more spec correct implementation of positioning here, that also only happens in one place.

Previous path would potentially also incorrectly justify when `justify-content` was non-default, but not handled in the previous few cases? We don't have access to the flexLine at this point later, and apart from the existing tests now passing I reused the new correct logic for justification (spec says we should position child as if its the only child in the container https://www.w3.org/TR/css-flexbox-1/#abspos-items).

I added a new, more scoped errata `AbsolutePositionWithoutInsetsExcludesPadding` to preserve some of the legacy behavior that showed as very breaking.

I also did not try removing `AbsolutePercentAgainstInnerSize` which I suspect would be more breaking than this change.

Changelog:
[General][Breaking] - More spec compliant absolute positioning

Reviewed By: joevilches

Differential Revision: D64244949

fbshipit-source-id: ca97570e0de82e8f0424a0912adfd0b05254559e
2024-10-17 22:40:16 -07:00
Joe Vilches
43be5888c4 Add boxsizing to playground (#1724)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1724

tsia!

Reviewed By: NickGerleman

Differential Revision: D64200150

fbshipit-source-id: f3ee6df648ec8ff29d8e26b0a3b3a5980fc8926b
2024-10-11 09:55:12 -07:00
Joe Vilches
2437d26ca5 Sunset the value namespace (#1720)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1720

X-link: https://github.com/facebook/react-native/pull/46930

This is not really needed anymore, we can just use `StyleLength` statics instead

Changelog: [Internal]

Reviewed By: NickGerleman

Differential Revision: D63922280

fbshipit-source-id: cd953bae8e9f68574463eafc49c33c2e85ac1856
2024-10-09 19:20:15 -07:00
Joe Vilches
820a4d5bf6 Let gentest properly create *Auto methods for sizes (#1719)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1719

Right now there is no way to test fixtures with `auto` widths, heights, or flex basis - even though we expose those functions. I updated gentest to generate those functions. Notably, position and margin (the other auto-able props) already account for this.

 I also created `YGAutoTest.html` to test this. Not really testing the capabilities of `auto` here, just if we can create a test about it.

Reviewed By: NickGerleman

Differential Revision: D64125522

fbshipit-source-id: 291ec82003cf53f99c21943142a63e2ef30402a5
2024-10-09 19:20:15 -07:00
Joe Vilches
ef9ae63268 Make it so that we can console.log in browser to debug gentest (#1718)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1718

Our gentest works by console.logging the contents of the test it is generating to the browser powered by the driver. The driver then reads the logs and writes it to a file. An unfortunate side effect here is that we cannot console.log to debug how the gentest logic actually works since the driver is expecting formatted code. To get around this I had the driver filter out logs with a certain prefix and add that a helper that logs a message with this prefix to the scripts.

Reviewed By: NickGerleman

Differential Revision: D64011035

fbshipit-source-id: 1f113fde425d1d7db1c16ab85f4bb16b0e18f41d
2024-10-09 19:20:15 -07:00
Joe Vilches
e69fcb26bb Fix issue where padding for box sizing is resolved against wrong reference length (#1715)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1715

X-link: https://github.com/facebook/react-native/pull/46799

Content box impl had a bug where we resolved padding % against the same reference length as the dimensions. Padding should always be against containing block's width. This is also true for width, but not for height, which should be against containing block's height.

This just pipes the width into our box sizing functions.

Changelog: [Internal]

Reviewed By: NickGerleman

Differential Revision: D63787577

fbshipit-source-id: e512338770f25b66506cabab5a7cde8f04397ea0
2024-10-04 17:07:05 -07:00
Joe Vilches
990ec920ad Add default test for box sizing (#1716)
Summary:
X-link: https://github.com/facebook/react-native/pull/46800

Pull Request resolved: https://github.com/facebook/yoga/pull/1716

Had a mini heart attack thinking I set the default to content box. Wrote this to double check and it passed. Might as well check it in

Technically the default to BoxSizing.h is ContentBox, but in the style we override that. Regardless I switched that around so border box was the default.

Changelog: [Internal]

Reviewed By: NickGerleman

Differential Revision: D63802722

fbshipit-source-id: 49ed29657c964bc12a2bf70988061ab4599267ec
2024-10-03 12:21:16 -07:00