Commit Graph

2594 Commits

Author SHA1 Message Date
Joe Vilches
19af9e6450 Move NodeToString.cpp to benchmark and remove interal usages (#1568)
Summary:
X-link: https://github.com/facebook/react-native/pull/42710

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

This is no longer going to be built with normal yoga so we are going to switch to a public API

Reviewed By: NickGerleman

Differential Revision: D53141235

fbshipit-source-id: 259270a4cd91ef0dab91cefba9c41953b6340d78
2024-02-02 15:44:23 -08:00
Joe Vilches
28975a6053 Remove public APIs for YGNodePrint and YGConfigSetPrintTreeFlag (#1567)
Summary:
X-link: https://github.com/facebook/react-native/pull/42688

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

We are planning on overhauling NodeToString to output JSON instead of HTML for the purposes of better benchmarking and capturing trees in JSON format to benchmark later. This gives us a bit of a headache as we have to revise several build files to ensure this new library works, ensure that it is only included in certain debug builds, and deal with the benchmark <-> internal cross boundary that arises as the benchmark code (which is a separate binary) tries to interact with it.

On top of it all this is really not used at all.

The plan is to rip out this functionality and just put it in a separate binary that one can include if they really want to debug. That means that it cannot exist in the public API, so I am removing it here.

Private internals come next

Changelog: [Internal]

Reviewed By: NickGerleman

Differential Revision: D53137544

fbshipit-source-id: 7571d243b914cd9bf09ac2418d9a1b86d1bee64a
2024-02-02 15:44:23 -08:00
Nick Gerleman
58aa090774 Fix flooring of border (#1562)
Summary:
X-link: https://github.com/facebook/react-native/pull/42411

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

I added a small regression D52605596, where negative border would not be correctly floored. This fixes that, and starts adding tests specifically targeting the computed style API, now decoupled from the yoga node.

Reviewed By: joevilches

Differential Revision: D52930827

fbshipit-source-id: e165dade705a8de54c92d65f3664c9081137788c
2024-01-22 22:07:49 -08:00
Joe Vilches
8fe38fc7a8 Fix mismatched cases of inlineStart/End and flexStart/End (#1561)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1561

Back when I introduced the inline functions that would get the edge according to the writing direction I swapped some instances of `setLayoutPosition` which wrote to the flexStart edge erroneously. We should basically never read from some inline style and write to the flex edge. This changes them all to use the flex values.

Reviewed By: NickGerleman

Differential Revision: D52921401

fbshipit-source-id: 92b74d652018596134c91827806272ed7418ef6c
2024-01-22 15:41:09 -08:00
Nick Gerleman
67154d47a3 Replace CompactValue with StyleValueHandle and StyleValuePool (#1534)
Summary:
X-link: https://github.com/facebook/react-native/pull/42131

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

Now that the storage method is a hidden implementation detail, this changes the underlying data structure used to store styles, from `CompactValue` (a customized 32-bit float with tag bits), to `StyleValuePool`.

This new structure operates on 16-bit handles, and a shared small buffer. The vast majority of real-world values can be stored directly in the handle, but we allow arbitrary 32 bit (and soon 64-bit) values to be stored, where the handle then becomes an index into the styles buffer.

This results in a real-world memory usage win, while also letting us store the 64-bit values we are wanting to use for math function support (compared to doubling the storage requirements).

This does seem to make style reads slower, which due to their heavy frequency, does have a performance impact observable by synthetics. In an example laying out a tree of 10,000 nodes, we originally read from `StyleValuePool` 2.4 million times.

This originally resulted in a ~10% regression, but when combined with the changes in the last diff, most style reads become simple bitwise operations on the handle, and we are actually 14% faster than before.

| | Before | After | Δ |
| `sizeof(yoga::Style)` | 208B  | 144B | -64B/-31% |
| `sizeof(yoga::Node)` | 640B  | 576B | -64B/-10% |
| `sizeof(YogaLayoutableShadowNode) ` |  920B | 856B | -64B/-7% |
| `sizeof(YogaLayoutableShadowNode) + sizeof(YogaStylableProps)` | 1296B  | 1168B | -128B/-10% |
| `sizeof(ViewShadowNode)`  |  920B | 856B | -64B/-7% |
| `sizeof(ViewShadowNode) + sizeof(ViewShadowNodeProps)` | 2000B  | 1872B | -128B/-6% |
| "Huge nested layout" microbenchmark (M1 Ultra) | 11.5ms | 9.9ms | -1.6ms/-14% |
| Quest Store C++ heap usage (avg over 10 runs) | 86.2MB | 84.9MB | -1.3MB/-1.5% |

Reviewed By: joevilches

Differential Revision: D52223122

fbshipit-source-id: 990f4b7e991e8e22d198ce20f7da66d9c6ba637b
2024-01-19 18:22:29 -08:00
Nick Gerleman
395c596695 Add some tests for justification under row-reverse (#1560)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1560

I added these when I was trying to debug the Facepile break removing the row-reverse errata caused. Yoga is doing the right thing, and the tests pass. We didn't have this specific coverage before, so add it.

Reviewed By: joevilches

Differential Revision: D52909633

fbshipit-source-id: d1e8f55bb534d76bd7dfdc46a1e1cc6f0a3ca211
2024-01-19 16:21:59 -08:00
Nick Gerleman
8744792f41 Simplify Edge Resolution (#1550)
Summary:
X-link: https://github.com/facebook/react-native/pull/42254

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

This change aims to simplify how we resolve edges. This operation happens many, many times, and has gotten complex and slow when paired with StyleValuePool.

This starts reshaping so that `yoga::Style` can resolve a style prop for a given edge. This is closer to the ideal computed style API to avoid recalcing this so many times, but doesn't address that.

This relies on removing the errata related to row-reverse, and cleans up the removal started in the last change.

This has no measurable perf effect under CompactValue, but has a >10% uplift in perf when using StyleValueHandle, where we can trivially check if a handle points to a defined value without resolving it, but only within `yoga::Style` since we don't expose the handle outside of it.

More quantifiably, we go from 2.35 million StyleValuePool reads to 993k. The rest are checks on the handle.

Reviewed By: joevilches

Differential Revision: D52605596

fbshipit-source-id: 0b366963a899e376f99ce3d75cd5f14a25d60cec
2024-01-19 11:28:06 -08:00
Nick Gerleman
35b9b5223e yoga::Node::getStyle() to yoga::Node::style() (#1555)
Summary:
X-link: https://github.com/facebook/react-native/pull/42314

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

The next diff moves a bunch of methods to `yoga::Style`. This renames the function to be a tad bit shorter, for more readable callsites. It also makes it more consistent with style property getters.

Changelog: [Internal]

Reviewed By: rozele

Differential Revision: D52803393

fbshipit-source-id: 557df34a9f0fb0ee42ad23b1fda99c1e0eb1d4e3
2024-01-19 11:28:06 -08:00
Nick Gerleman
d6a3b71085 Fix missing assignment in Node move constructor (#1554)
Summary:
X-link: https://github.com/facebook/react-native/pull/42275

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

Adds recently added field missing from move constructor

Reviewed By: joevilches

Differential Revision: D52767525

fbshipit-source-id: ec68452b058178967650bbef736562caafbf4a36
2024-01-19 09:46:08 -08:00
Nathaniel Brough
1a8b80a3d5 Add simple fuzz-harness (#1537)
Summary:
> This PR is based on the proposal in https://github.com/facebook/yoga/issues/1538 inlined below, to integrate yoga with `oss-fuzz`

Hey yoga team,

I've recently become interested in yoga. I'd like to suggest and champion an effort to set up some basic fuzz-testing and combine it with google/oss-fuzz for continuous fuzzing. I'm fully aware that you are very busy people and I don't want to overload your review/maintenance capacity. Is this a bad time to discuss potential security/reliability improvements?

If you're not familiar with fuzzing or oss-fuzz I've included a few brief notes below.

#### **Benefits of Fuzz-Testing**

- **Dynamic Code Testing**: Fuzz-testing challenges systems with unexpected data, aiming to identify vulnerabilities or bugs. It’s akin to an exhaustive stress-test for the code.
- **Detecting Hidden Vulnerabilities**: It can uncover potential weaknesses that may not be evident in routine tests.
- **Continuous and Automated Testing**: With tools like Google’s OSS-Fuzz, fuzz-testing can be automated, running continuously on distributed systems, ensuring daily resilience checks.

#### **Google/oss-fuzz for Continuous Fuzzing**

- **Automated Fuzzing**: OSS-Fuzz undertakes comprehensive fuzz-testing daily on a distributed cluster.
- **Detailed Reporting**: OSS-Fuzz offers exhaustive reports in case of detected anomalies, enabling effective action.

I’d be more than happy to lead the effort in integrating fuzz testing with the yoga and assist in any way required.

#### Prior integrations
There have been a number of previous integrations completed with facebook repositories and google/oss-fuzz including;
- facebook/time
- facebook/zstd
- facebookexperimental/starlark-rust (this was me)
- facebook/proxygen
- facebook/hermes
- facebook/rocksdb

As a proof of concept I created a couple of super simple fuzz harnesses in https://github.com/facebook/yoga/issues/1537.

NOTE: Adding fuzz-testing and integrating with google/oss-fuzz was previously suggested here https://github.com/facebook/yoga/pull/1055 and was rejected. I think I've addressed the concerns raised in the first PR. While the original PR contained what was probably a higher performance fuzzer, the new fuzzer should be easier to integrate and doesn't introduce multiple sources of truth.

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

Reviewed By: yungsters

Differential Revision: D52800366

Pulled By: NickGerleman

fbshipit-source-id: 4957282456f3263e600d13ae6f3e983681bebda6
2024-01-19 09:00:35 -08:00
Joe Vilches
1541f9d528 Rename AbsolutePositioning errata (#1558)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1558

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

AbsolutePositioning -> AbsolutePositioningCatchAll

A bit more clear. This errata is for various issues with positioning absolute nodes. There really isn't a clear description as to what specifically this enables/disables, so I just opted to say "catch all" to indicate that this controls various bugs

Reviewed By: NickGerleman

Differential Revision: D52820117

fbshipit-source-id: 80b77832baf65e68e57ca523c418422dd346ef0f
2024-01-18 21:22:05 -08:00
Joe Vilches
06c26d7d46 Remove static-behaves-like-relative errata (#1556)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1556

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

Since we aim to ship static to all users of yoga (not just XPR), we need to remove the errata that is gating most of the features. This should be a non breaking change. To ensure that, I added a new errata which, if on, will use the inner size of the containing node as the containing block. This is how it has been for a while and resolving this is risky and time consuming so for the time being we will stick with that.

Reviewed By: NickGerleman

Differential Revision: D52706161

fbshipit-source-id: 30a93f29cb0d97b20b2947eaa21f36cdc78c4961
2024-01-18 21:22:05 -08:00
Joe Vilches
f69a1a43e5 Hardcode AbsolutePercentageAgainstPaddingEdge experimental feature to false (#1549)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1549

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

This experimental feature is always false, and with the next diff I will be deleting the branch that actually calls into this. Separating this diff out to simplify the review process.

Reviewed By: NickGerleman

Differential Revision: D52705765

fbshipit-source-id: 705f4aa297eae730af9b44753eb01c9dec385dcf
2024-01-18 21:22:05 -08:00
Nick Gerleman
0bbfe4503d Remove YGNodeSetPrintFunc and related (#1553)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1553

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

Separate from `YGConfigSetPrintTreeFlag` we have a public API `YGNodeSetPrintFunc` which sets a function called, if you manually change a constant in source code during debugging.

This is not debug-only, is exposed as part of the public API (without a way to turn it on from the public API), and takes up a pointer per node doing nothing.

I'm not aware of anyone recently using the capability, and the tracing/event related work done since then would be more powerful for this anyway.

Remove the API.

Changelog: [Internal]

Reviewed By: rozele

Differential Revision: D52767445

fbshipit-source-id: f72927b47cffa4fe6fe886b42f07cc1ba55f141e
2024-01-16 10:07:19 -08:00
Nick Gerleman
508df05f0d Android Gradle Plugin 8.2.1 (#1548)
Summary:
We technically didn't need to be on the Beta before for NDK 26, but this bumps to the latest, non-prerelease version.

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

Reviewed By: christophpurrer

Differential Revision: D52749378

Pulled By: NickGerleman

fbshipit-source-id: c1940976e6b240aba2af5a2863f189280701ebd3
2024-01-12 22:49:14 -08:00
Nick Gerleman
8c3e01166b Remove row-reverse errata (#1547)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1547

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

Yoga has an odd behavior, where `start`/`end` edges under row-reverse are relative to flex-direction, instead of writing direction.

While Yoga doesn't actually document what this behavior is supposed to be, it goes against CK documentation, historic RN documentation, and the behavior valid on the web. It is also applied inconsistently (e.g. sometimes only on container, sometimes on child). It really is a bug, instead of an intended behavior.

We changed the default behavior for Yoga, but left the existing one behind an errata (so existing fbsource users got old behavior). We have previously seen this behavior show up in product code, including CK when running on FlexLayout.

`row-reverse` is surprisingly uncommon though:
1. Litho has <40 usages
2. RN has ~40 usages in `RKJSModules`,~30 in `arvr/js`, ~6 in `xplat/archon`
3. CK has ~80 usages
4. NT has ~40 usages

There are few enough, mostly simple components, that we can inspect through each of them, looking for signs they will hit the issue (at the potential chance of missing some).

CK accounts for 10/14 usages that I could tell would trigger the issue, since it only exposes start/end edge, and not left/right. It might make sense to make it preserve behavior instead, to reduce risk a bit.

FlexLayout is now separately powering Bloks, which wasn't surveyed, so I didn't touch CK behavior under Bloks.

There could also be other usages in other frameworks/bespoke usages, and this has implications for OSS users. But based on our own usage, of many, many components, this seems rare.

Changelog:
[General][Breaking] - Make `start/end` in styles always refer to writing direction

Reviewed By: pentiumao, joevilches

Differential Revision: D52698130

fbshipit-source-id: 2a9ac47e177469f30dc988d916b6c0ad95d53461
2024-01-12 13:49:53 -08:00
dependabot[bot]
7e70656e46 Bump follow-redirects from 1.15.3 to 1.15.4 (#1546)
Summary:
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.3 to 1.15.4.
<details>
<summary>Commits</summary>
<ul>
<li><a href="65858205e5"><code>6585820</code></a> Release version 1.15.4 of the npm package.</li>
<li><a href="7a6567e16d"><code>7a6567e</code></a> Disallow bracketed hostnames.</li>
<li><a href="05629af696"><code>05629af</code></a> Prefer native URL instead of deprecated url.parse.</li>
<li><a href="1cba8e85fa"><code>1cba8e8</code></a> Prefer native URL instead of legacy url.resolve.</li>
<li><a href="72bc2a4229"><code>72bc2a4</code></a> Simplify _processResponse error handling.</li>
<li><a href="3d42aecdca"><code>3d42aec</code></a> Add bracket tests.</li>
<li><a href="bcbb096b32"><code>bcbb096</code></a> Do not directly set Error properties.</li>
<li>See full diff in <a href="https://github.com/follow-redirects/follow-redirects/compare/v1.15.3...v1.15.4">compare view</a></li>
</ul>
</details>
<br />

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=follow-redirects&package-manager=npm_and_yarn&previous-version=1.15.3&new-version=1.15.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

 ---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `dependabot rebase` will rebase this PR
- `dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `dependabot merge` will merge this PR after your CI passes on it
- `dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `dependabot cancel merge` will cancel a previously requested merge and block automerging
- `dependabot reopen` will reopen this PR if it is closed
- `dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency
- `dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/facebook/yoga/network/alerts).

</details>

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

Reviewed By: cortinico

Differential Revision: D52689011

Pulled By: NickGerleman

fbshipit-source-id: 3a8b1d0802a03d262660bafd5998bedd8487c5b0
2024-01-11 04:28:37 -08:00
Joe Vilches
93b6c09eeb Fix error from misspelled function name (#1542)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1542

`YGNodeSetAlwaysFormContainingBlock` -> `YGNodeSetAlwaysFormsContainingBlock`

Started getting tasks telling me github CI was broken. Turns out I was just mispelling this.

Its not a big deal but we really should ensure that stuff will not land if it break github CI...not in our wheelhouse but it seems quite silly that this happens.

Also, a lot of the random files do not have auto complete or code checking which is why I didn't notice this to begin with.

Reviewed By: NickGerleman

Differential Revision: D52632257

fbshipit-source-id: 367ae5766ef9baecf55f7c227ff9fc8dece43af6
2024-01-09 11:46:05 -08:00
Joe Vilches
e4ab593686 JS bindings for setAlwaysFormsContainingBlock (#1541)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1541

tsia

Reviewed By: NickGerleman

Differential Revision: D52608426

fbshipit-source-id: 19fa01d87cbae3457adb9cdb9e0cb602b7afa619
2024-01-08 20:28:49 -08:00
Joe Vilches
47e9f33eb4 Java bindings for setAlwaysFormsContainingBlock (#1540)
Summary:
X-link: https://github.com/facebook/react-native/pull/42192

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

tsia

Changelog: [Internal]

Reviewed By: NickGerleman

Differential Revision: D52608259

fbshipit-source-id: 647ec4e2fe180ace8d6b641e17cd610fa53fe845
2024-01-08 20:28:49 -08:00
Joe Vilches
5425107246 Support transforms forming containing blocks (#1539)
Summary:
X-link: https://github.com/facebook/react-native/pull/42191

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

React native supports transforms and if a node has a transform it will [form a containing block for absolute descendants regardless of position type](https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block). So we need to pass that information into Yoga to ensure this happens.

The verbiage for the field "alwaysFormsContainingBlock" is very specific. In a vacuum a node cannot simply "form a containing block". It only forms a containing block in reference to a different node. This can be illustrated in a scenario where we have a static node that is a flex container which has 1 absolute child and 1 relative child. This static node will form a containing block for the relative child but not the absolute one. We could just pass the information on rather something has a transform or not but Yoga is not supposed to know about transforms in general. As a result we have a notion of "always" forming a containing block. Since Yoga is a flexbox spec, non-absolute nodes' containing blocks will ways be their parent. If we add something like a transform to a node then that will also apply to absolute nodes - hence we can say the node will **always** form a CB, no matter who is the descendant.

Changelog: [Internal]

Reviewed By: NickGerleman

Differential Revision: D52521160

fbshipit-source-id: bab9319ffddec617f5281823930f2a00cc2967f2
2024-01-08 20:28:49 -08:00
Nick Gerleman
94e7336394 Move trailing position functions (#1533)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1533

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

I have some reservations about  some of the conditional setting of trailing position in general, and some of the repeated transformations that neccesitates this, but these functions don't belong in `CalculateLayout.h`. For now, just move these to their own header.

Reviewed By: joevilches

Differential Revision: D52292121

fbshipit-source-id: 4a998a4390a8d045af45f5424adaf049ed635e7a
2023-12-21 13:48:11 -08:00
Nick Gerleman
c319c36b0d Remove duplicate declaration of calculateLayoutInternal (#1532)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1532

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

as per title

Reviewed By: joevilches

Differential Revision: D52289613

fbshipit-source-id: 51a810dda32e6fe44be05a42fe21d78aede52d30
2023-12-21 13:48:11 -08:00
Nick Gerleman
3b0545b15d Add tests for cycles with percentage dimensions (#1530)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1530

Yoga has a shortcut where if a min dimension and max dimension are the same, the value acts as a definite length.

I was curious how browsers handled this.

CSS 2.1 said:
> If the containing block's width depends on this element's width, then the resulting layout is undefined

This is superceded in the CSS box sizing spec. https://www.w3.org/TR/css-sizing-3/#sizing-values

> If, in a particular axis, the containing block’s size depends on the box’s size, see the relevant layout module for special rules on how to resolve percentages. Negative values are invalid.

And later:
https://www.w3.org/TR/css-sizing-3/#cyclic-percentage-contribution

> Sometimes the size of a percentage-sized box’s containing block depends on the intrinsic size contribution of the box itself, creating a cyclic dependency. When calculating the intrinsic size contribution of such a box (including any calculations for a content-based automatic minimum size), a percentage value that resolves against a size in the same axis as the intrinsic size contribution (a cyclic percentage size) is resolved specially:

> If the box is non-replaced, then the entire value of any max size property or preferred size property (width/max-width/height/max-height) specified as an expression containing a percentage (such as 10% or calc(10px + 0%)) that is cyclic is treated for the purpose of calculating the box’s intrinsic size contributions only as that property’s initial value. For example, given a box with width: calc(20px + 50%), its max-content contribution is calculated as if its width were auto. (The percentage is honored as usual, however, during the actual sizing of the box itself; see below.)

> Otherwise, the percentage is resolved against the containing block’s size. (The containing block’s size is not re-resolved based on the resulting size of the box; the contents might thus overflow or underflow the containing block).

So, for the purpose of sizing the parent, the child sized using a percentage does not contribute, but we should be sizing children based on that size.

Yoga does not really work like this right now, but gets the answer right answer for half of these tests.

Reviewed By: yungsters

Differential Revision: D52251601

fbshipit-source-id: 4978b90723130283b00e87bbf49795a4d209174c
2023-12-19 13:38:40 -08:00
Nick Gerleman
c5edcb3d3a Reorder members in Node.h (#1529)
Summary:
X-link: https://github.com/facebook/react-native/pull/41994

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

Reorganizes the header according to common C++ convnetions. Public first, then private. Constructors, then functions, then member variables.

Reviewed By: joevilches

Differential Revision: D52106056

fbshipit-source-id: 0095cf7caa58dc79c1803b3b231911e4fc66ddaf
2023-12-19 13:38:40 -08:00
Nick Gerleman
1f391dfc50 Node::styleDefinesDimension() -> Node::hasDefiniteLength() (#1526)
Summary:
X-link: https://github.com/facebook/react-native/pull/41995

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

This function has made quite the journey from something that originally made more sense. This renames, refactors, and adds documentation for what it actually does.

This should eventually make its way into `yoga::Style` once computed style is moved into that structure.

bypass-github-export-checks

Reviewed By: joevilches

Differential Revision: D52105718

fbshipit-source-id: 6492224dd2e10cef3c5fc6a139323ad189a0925c
2023-12-19 13:38:40 -08:00
Nick Gerleman
ca4ecc044d yoga::resolveValue -> Length::resolve (#1520)
Summary:
X-link: https://github.com/facebook/react-native/pull/41939

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

This code originates as `YGValueResolve`, used to compute a YGValue to a length in points, using a reference for 100%.

This moves it to `Style::Length`, so we can encapsulate parts of it (for style value functions), and make the API more cohesive now that we can do C++ style OOP with it.

Changelog: [Internal]

Reviewed By: joevilches

Differential Revision: D51796973

fbshipit-source-id: a7c359c7544f4bd2066a80d976dde67a0d16f1dd
2023-12-19 13:38:40 -08:00
Nick Gerleman
192016a0a8 Make CompactValue internal detail of yoga::Style (#1492)
Summary:
X-link: https://github.com/facebook/react-native/pull/41776
Pull Request resolved: https://github.com/facebook/yoga/pull/1492

# Summary

In preparation to replace `CompactValue`, this fully encapsulates it as an implementation detail of `yoga::Style`.

The internal API now always operates on `Style::Length`, converted to `YGValue` at the public API boundary.

In the next step, we can plug in a new representation within `Style`, which should enable 64 bit values, and lower memory usage.

# Test Plan

1. Existing tests (inc for style, invalidation, CompactValue) pass
2. Check that constexpr `yoga::isinf()` produces same assembly under Clang as `std::isinf()`
3. Fabric Android builds
4. Yoga benchmark does style reads

# Performance

Checking whether a style is defined, then reading after, is a hot path, and we are doubling any space style lengths take in the stack (but not long-term on the node). After a naive move, on one system, the Yoga benchmark creating, laying out, and destroying a tree, ran about 8-10%  slower in the "Huge nested flex" example. We are converting in many more cases instead of doing undefined check, but operating on accessed style values no longer needs to do the conversion multiple times.

I changed the `CompactValue` conversion to YGValue/StyleLength path to check for undefined as the common case (since we always convert, instead of calling `isUndefined` directly on CompactValue. That seemed to get the difference down to ~5-6% when I was playing with it then. We can optimistically make some of this up with ValuePool giving better locality, and fix this more holistically if we reduce edge and value resolution.

On another machine where I tested this, the new revision went the opposite direction, and was about 5% faster, so this isn't really a cut and dry regression, but we see different characteristics than before.

# Changelog
[Internal]

Reviewed By: rozele

Differential Revision: D51775346

fbshipit-source-id: c618af41b4882b4a227c917fcad07375806faf78
2023-12-19 13:38:40 -08:00
Nick Gerleman
2caa8ac8cb Workaround Docusaurus prism highlighting hydration bug (#1519)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1519

See https://github.com/facebook/docusaurus/issues/9629

We use prism to render the code for the inline editor. Prism renders colors to style directly, and the color chosen is dependent on a setting that may not be available at SSR time.

This adds an SSR-specific representation of the code, missing some of the nuances in token colorization (similar to https://github.com/facebook/docusaurus/pull/7373). This adds a little bit of jank compared to perfect SSR, but fixes cases where the mode is incorrect, and is a lot less jank then the more generic solution used by theme-live-codeblock of keeping the rendering of the opposite color until rehydration.

Preview: https://yoga-website-next-git-fork-nickgerleman-exp-2f8171-fbopensource.vercel.app/

Reviewed By: yungsters

Differential Revision: D52163722

fbshipit-source-id: 312dc52134f0084d40f78147190151700ee10ff7
2023-12-19 12:46:26 -08:00
Nick Gerleman
3f6f04cb92 Don't include code in SSR generation of Playground endpoint (#1518)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1518

We allow arbitrary code in the query param, that static site generation doesn't know about. Current experience in production build is confusing, since you can see a flash of one set of code (playground default), quickly change to another. It is less confusing to have it go from blank to code showing.

Reviewed By: yungsters

Differential Revision: D52162928

fbshipit-source-id: fc7b51455682351a0616be8b9ecf557122d3a8db
2023-12-19 12:46:26 -08:00
Nick Gerleman
eeeb2cae49 Make playground links shorter (#1516)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1516

Right now playground links are URL encoded base64 of the code content. This leads to some pretty long links.

Running a service, or needing to auth to some other service, seems like a lot more headache than it is worth, so this change instead tries to make the URLs a bit more reasonable.

One minor saving is that we're URL encoding base64, instead of just representing using the url-safe variant of base64. But we can get more savings, even in small examples, using compression. This adds a popular, small, library to do that.

Reviewed By: yungsters

Differential Revision: D52161884

fbshipit-source-id: 9f5d131f27e25a611501c2e3bf3907e83c2e3da1
2023-12-19 12:46:26 -08:00
Nick Gerleman
7697be57a8 Consistent bracket spacing in main example (#1517)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1517

Accidentally using a combination of prettier default vs with `--no-bracket-spacing`

Reviewed By: yungsters

Differential Revision: D52162274

fbshipit-source-id: a0e629717060c17b63fa6144d775a590258580ac
2023-12-18 09:38:00 -08:00
Nick Gerleman
3f3b909086 Change Style::resolveColumnGap() return from Length to Style::Length (#1525)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1525

Accidentally left this inconsistent with some of the refactoring. Rename the lone usage of `Length` within Style class to `Style::Length` to match the rest of the code.

This is functionally identical as before.

Changelog: [Internal]

bypass-github-export-checks

Reviewed By: yungsters

Differential Revision: D52096820

fbshipit-source-id: d6c569a02fb27a6e7548a9c12ff764afb823a282
2023-12-17 02:58:54 -08:00
Nick Gerleman
a1751127ef Fix align-content of cross-stretched container (#1524)
Summary:
X-link: https://github.com/facebook/react-native/pull/41964

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

D52087013 (#1513) fixed some issues, including where measuring under max-content or fit-content, align-content stretch would consume the entire available cross-dimensions, instead of only sizing to definite dimension, like the spec dicates.

I missed a case, where flexbox considers a container as having a definite cross-size if it is being stretched, even if it doesn't have a definite length.

https://www.w3.org/TR/css-flexbox-1/#definite-sizes

> 3. Once the cross size of a flex line has been determined, items in auto-sized flex containers are also considered definite for the purpose of layout;

> 1. If a single-line flex container has a definite cross size, the outer cross size of any stretched flex items is the flex container’s inner cross size (clamped to the flex item’s min and max cross size) and is considered definite.

We handle `align-items: stretch` of a flex container after cross-size determination by laying out the child under stretch-fit (previously YGMeasureModeExactly) constraint. This checks that case, and sizing the line container to specified cross-dim if we are told to stretch to it.

We could probably afford to merge this a bit with later with what is currently step 9, where we end up redoing some of this same math.

Reviewed By: yungsters

Differential Revision: D52234980

fbshipit-source-id: 475773a352fd01f63a4b21e93a55519726dc0da7
2023-12-17 01:13:36 -08:00
Cheng Zhao
2a8c7a4223 std::terminate belongs to <exception> header (#1511)
Summary:
X-link: https://github.com/facebook/react-native/pull/41917

See also https://en.cppreference.com/w/cpp/error/terminate.

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

Reviewed By: christophpurrer

Differential Revision: D52072882

Pulled By: NickGerleman

fbshipit-source-id: 4d4d442b82d108d1d2ff5d241fbdc8df89045fed
2023-12-17 00:47:44 -08:00
Nick Gerleman
464d1668ba Fix sizing and alignment issues with multi-line containers (#1513)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1513

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

Fixes https://github.com/facebook/yoga/issues/1300
Fixes https://github.com/facebook/yoga/issues/1008

This fixes a smattering of issues related to both sizing and aligment of multi-line-containers:

1. We were previously incorrectly bounding the size of each flex line to the min/max of the entire container.
2. Per-line leads were sometimes incorrectly contributing to alignment within the line
3. The cross dim size used for multi-line alignment is not correct, or correctly clamped. If the available size comes from a max constraint, that was incorrectly used instead of a definite size, or size of content. Leads were entirely skipped for min constraint.

Need to test how breaking this is, to see if it might need to go behind an errata.

See related PRs:
1. https://github.com/facebook/yoga/pull/1491
2. https://github.com/facebook/yoga/pull/1493
3. https://github.com/facebook/yoga/pull/1013

Changelog:
[General][Fixed] - Fix Yoga sizing and alignment issues with multi-line containers

Reviewed By: joevilches

Differential Revision: D52087013

fbshipit-source-id: 8d95ad17e58c1fec1cceab9756413d0b3bd4cd8f
2023-12-16 01:12:30 -08:00
Nick Gerleman
baf95897cb Enable lints for React Components (#1515)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1515

The out-of-the-box docusaurus template doesn't enable linting for React components. This enables those, fixes the errors, and does dome cleanup around the area (e.g. autofocus is a lot more sane).

Reviewed By: vincentriemer

Differential Revision: D52156109

fbshipit-source-id: f32fede3ec4f8a42ecb7f9d77caa2a30581f35ee
2023-12-15 22:46:58 -08:00
Joe Vilches
bac80cafba Add minimist dep to package.json (#1522)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1522

I have the types but not the core

Reviewed By: NickGerleman

Differential Revision: D52216588

fbshipit-source-id: ec348537655213f6d8a3b35402fec03998744c78
2023-12-15 16:26:31 -08:00
Joe Vilches
7aee99567a Change readme yarn link (#1521)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1521

I linked the forked version of yarn when in reality it should be yarn classic

Reviewed By: NickGerleman

Differential Revision: D52215925

fbshipit-source-id: 5d5800d162f2cc250fcf54151de0de87a427abc2
2023-12-15 16:26:31 -08:00
Joe Vilches
43d09a3a94 GitHub workflow to ensure tests are up to date (#1505)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1505

This will ensure that all tests are not modified by hand and that gentest was run if needed (i.e. someone edited those files and forgot to update the tests). Not sure if this works right now, need to export to github and see what happens :)

Reviewed By: NickGerleman

Differential Revision: D52002920

fbshipit-source-id: 1ee033eda04eeba5d01885488bfe8078e7b2f386
2023-12-14 11:48:22 -08:00
Joe Vilches
06c792a407 Create gentest-validate script to validate test signatures (#1504)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1504

I aim to consume this via a github action or workflow. Separating out the CI configuration from the actual script. We could and should maybe change this script to take in arguments for the test dirs so it is more configurable, but getting the barebones down right now.

Reviewed By: NickGerleman

Differential Revision: D51999865

fbshipit-source-id: 5792c6eec5692943518fecefc6226d784c6f0ad8
2023-12-14 11:48:22 -08:00
Joe Vilches
4743040d62 Sign generated tests (#1503)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1503

This diff makes it so that our driver will sign all of the generated files to help ensure that they are not edited by hand. Next I will add CI to actually verify the signature

Reviewed By: NickGerleman

Differential Revision: D51966201

fbshipit-source-id: f7e3f4fde1c98832212a448b2dcc8e21be0560c4
2023-12-14 11:48:22 -08:00
Joe Vilches
e1b59d63a7 Update README with new instructions on how to run the gentest script (#1502)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1502

We should change this if we are moving away from using Ruby

Reviewed By: yungsters, NickGerleman

Differential Revision: D51957351

fbshipit-source-id: fddb0b3348db2b93c661c919a61150c81906a61a
2023-12-14 11:48:22 -08:00
Joe Vilches
e61eb0178c Remove ruby files and regen tests (#1501)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1501

Now that we have `gentest-driver.ts` we can delete the ruby gentest. I also regened all of the tests that have a comment with the wrong file name for where it was generated.

Reviewed By: yungsters, NickGerleman

Differential Revision: D51956567

fbshipit-source-id: d389492e54711cf161dff9e649396cc40f1e5073
2023-12-14 11:48:22 -08:00
Joe Vilches
fba32ebf14 Add command line options to new node-based gentest (#1499)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1499

This uses the minimist library to parse the command line easily for flags and options. I added over the same ones in the ruby script (-f and -s).

Reviewed By: yungsters, NickGerleman

Differential Revision: D51877810

fbshipit-source-id: 643606cad25609ed2567bb63470818b81ebef531
2023-12-14 11:48:22 -08:00
Joe Vilches
98552078b1 Create node version of gentest script (#1498)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1498

The only instance of ruby in this repository is `gentest.rb` used to generate test cases from html fixtures. This is quite annoying as ruby is not the most popular compared to something like Node and it does not integrate into the rest of our stack. I changed this to use Node.js instead. Instead of `watir` we now use `selenium-webdriver`. `watir` is backed by Selenium so I do not expect anything to change.

Next commits will add command line options, clean up gentest.rb and its references, and change the README

allow-large-files

Reviewed By: yungsters, NickGerleman

Differential Revision: D51874433

fbshipit-source-id: ef8588d48aa7f8b720b57df08738bbd01e9e74a3
2023-12-14 11:48:22 -08:00
Nick Gerleman
43cb24fdce Fix playground handling of visible scrollbars (#1514)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1514

On machines with scrollbars, we shouldn't show them unconditionally, and the toolbar should be in the area within them.

This also fixes a couple bugs:
1. Preview not rendering based on correct code when light/dark mode changes
2. Crash on start on mobile safari
3. Incorrect rendering of preview on mobile safari

This also fixes a bug where the playground re-rendering (e.g. on theme change) makes the preview snap back to the initial code passes.

https://yoga-website-next-git-fork-nickgerleman-exp-194d90-fbopensource.vercel.app/

Reviewed By: shwanton

Differential Revision: D52145666

fbshipit-source-id: 50184305987aab4cbcd066f37582997dfdc78c02
2023-12-13 20:05:29 -08:00
Nick Gerleman
738d04fcb0 Fix OSS JS Build (#1512)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1512

Latest revision either never got exported, or didn't block land? Fix the typo.

Reviewed By: joevilches

Differential Revision: D52087122

fbshipit-source-id: 2dfcff4925902bdd1dd210a219a78707186fd28e
2023-12-12 13:11:01 -08:00
Nick Gerleman
c01c4cbb82 Backfil Yoga 2.0 Release notes to blog (#1508)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1508

Backfilling the release notes already on GitHub before the next time we want to do a release, and use the Docusaurus blog.

Reviewed By: yungsters

Differential Revision: D52012362

fbshipit-source-id: 35de017017943ed21263a4a9aeaa0fd1418c2bc7
2023-12-12 09:06:58 -08:00
Nick Gerleman
77742af676 Replace Playground with JSX Editor (#1500)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1500

Inspired by the frequent usage of Expo snacks to run RN, to repro Yoga issues, this replaces the Playground port with a new ground up Playground UI. This UI right now is pretty simple, with a JSX editor which creates a Yoga tree, which is then rendered using the WebAssembly variant of Yoga.

There are a lot of ways we can continue to improve this, but this merges the foundation. Subjectively, I find this more useful as a tool to play with Yoga behavior than the GUI.

This also replaces some of the bits of the homepage, and adds a playground entrypoint (though it's pretty identical to the one I've been testing on the home page).

Reviewed By: yungsters

Differential Revision: D51963201

fbshipit-source-id: 1265cb1784151b685686e189d47ecd42cbacdf8f
2023-12-12 09:06:58 -08:00