Summary: Now, following the previous diff, we remove `LayoutableShadowNode::isLayoutOnly()` and change the view flattening algorithm to rely on two new traits. See the previous diff to learn more about how it works.
Reviewed By: sammy-SC
Differential Revision: D20212252
fbshipit-source-id: 87a07e8bb17b2e66e5703f107dc35ca7a8e49634
Summary:
This diff introduces two new `ShadowNodeTrait`s that we will use in the future in the new (slightly tweaked) view-flattening algorithm. (Note: this diff does not enable the new flattening, it's just preparation.)
The idea is that we split the notion of `isLayoutOnlyView` into two traits:
* `FormsView`: `ShadowNode`s with this trait must be represented as `ShadowView`s. Normal "visible" ShadowNodes will have this trait, but "layout only views" in old nomenclature will not.
* `FormsStackingContext`: `ShadowNode`s with this thread not only must be represented as `ShadowView`s but also have to form a "stacking context" which means that their children must be mounted as `ShadowView`'s children.
Our implementation does not exactly follow W3C spec in terms of sets of props that create the stacking context (because of historical reasons and mobile specifics) but ideologically it's the same. We start from the very conservative implementation where only views with background-color and borders do not form stacking context and then we probably extend that to more props.
Most importantly for us now, we will enforce the absence of ``FormsStackingContext` for `ParagraphShadowNode` and the presence of `FormsView` for `TextShadowNode` on Android where it's essential for mounting layer.
Read more about stacking context here: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D20212253
fbshipit-source-id: 0fbaee214ce2c5886cb0232843a2a3c7bb20655d
Summary:
Passing `layoutContext` to yoga crashes fb4a-64. Until I have a solution let's back this out.
Original commit changeset: 9df7da4bef8c
Changelog: [Internal]
Reviewed By: makovkastar
Differential Revision: D20246917
fbshipit-source-id: 220744fde9f74e8157fc0714c63639b01152e4ab
Summary:
Now we tweak more props in order to prepare for new flattening algorithm.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: JoshuaGross
Differential Revision: D20212254
fbshipit-source-id: 7391155072f93046e78fbecf4bb4b42cb1caacdc
Summary:
This is a part of migration staterted in D19390813.
There is no need to have those as const. The whole *Props object is usually const (and when it's not, props should not be too).
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D20212255
fbshipit-source-id: 87f3d8e7a94c6626bd9b0fc304f75e915dd73d4c
Summary:
Changelog: [Internal]
Use LayoutContext to pass `fontSizeMultiplier` down to ParagrapShadowNode.
Reviewed By: shergin
Differential Revision: D20184596
fbshipit-source-id: 3965a127069a21328ed19cb3f9732f0a2d1c4d58
Summary:
In order to build dynamic text sizing, `LayoutableShadowNode::measure` needs to accept `LayoutContext`
Changelog: [Internal]
Reviewed By: shergin
Differential Revision: D20184598
fbshipit-source-id: 8928b59d51948caf3654f40049212a89a91dceb6
Summary:
In order to build dynamic text sizing, we need to pass layoutContext to `yogaNodeMeasureCallbackConnector`
Changelog: [Internal]
Reviewed By: shergin
Differential Revision: D20184597
fbshipit-source-id: 9df7da4bef8cbad3bc87d63ed0c5aa5f420dbc11
Summary:
What's changed:
* `end()` now returns the pointer to the imaginary element after the very last one (which is aligned with STL);
* `erase()` now swaps the removing and the last elements and shrinks the size of an array.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D19965405
fbshipit-source-id: 92eedf38d55be35a0d9ab6120634b51c8d6e4674
Summary:
Clearing `props` and `state` (which we don't use) allows avoiding retain cycles.
The memory leak was caused by a retain cycle:
AttributedString -> Fragment -> ShadowView -> PharagraphState -> TextLayoutManager -> Cache -> AttributedString.
We don't use `props` and `state` parts of `ShadowView` inside `AttributedString`.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: mdvacca
Differential Revision: D20182791
fbshipit-source-id: 2ddc5d53a1cb594e3d1cc39933e8958eb6425389
Summary:
This diff implements serialization and deserialization of text attachments as part of the calculation of layout of text components
changelog: [internal]
Reviewed By: JoshuaGross
Differential Revision: D20087251
fbshipit-source-id: dbcbd22f856aadace14343205548154ea80c8464
Summary:
Changelog: [internal]
# Problem
We have node A with N children.
Calling cloning constructor on `YogaLayoutableShadowNode` causes new `yogaNode_` to be created.
However if `fragment.children` is nil in cloning constructor, which basically says children were not changed, then the existing children's `owner` becomes invalid.
# Solution
In the clone constructor, always call `updateYogaChildren`. This updates yoga children with the new `owner`.
Reviewed By: JoshuaGross
Differential Revision: D20139582
fbshipit-source-id: 3932694d4381b601df07dd8a57887ce7c09f1582
Summary:
The sizes of attachments are legit parts of `AttributedString`s identity, so we need to incorporate it into the equality test.
We need that to make measurement cache work correctly with inline views.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: mdvacca
Differential Revision: D20151505
fbshipit-source-id: ae47c24a753eab1e497fcfaa93de557ffb30d874
Summary:
Run clang-format and add .clang-tidy with `clang-diagnostic-*` to several more directories in order to catch any problems.
Changelog:
[Internal]
Reviewed By: shergin
Differential Revision: D19860169
fbshipit-source-id: 7785aab010c8e6945cc6b5c9b68cb8ee0cdbb7fa
Summary:
The PlatformConstants native module exposes the ability to query the React
Native version used to build native code. This is managed on iOS and Android by
a version bumping script, which replaces module code based on a template.
It is currently difficult to accurately determine this version for out-of-tree C++
platforms (I.e. React Native Windows). The version of upstream react-native we resolve to is ultimately
dependent on the version of react-native chosen a peer dependency, which is not
neccesarily constant given a build of react-native-windows.
We could try to hack around this, and make our native build try to reason about
the resolved pacakge for react-native using a lockfile, but a much cleaner
solution is to embed version into C++ code, similar to what is done for Android
and iOS. This change does that, adding a header with React Native version and
updating the build stamping script to write to it.
Usage sample:
```c++
constants["reactNativeVersion"] = folly::dynamic::object();
constants["reactNativeVersion"]["major"] = ReactNativeVersion.Major;
constants["reactNativeVersion"]["minor"] = ReactNativeVersion.Minor;
constants["reactNativeVersion"]["patch"] = ReactNativeVersion.Patch;
```
## Changelog
[General] [Added] - Stamp React Native Version Into C++ Code
Pull Request resolved: https://github.com/facebook/react-native/pull/28036
Test Plan: Validated that the bumping script will accurately update the header, can compile under both MSVC and Clang.
Differential Revision: D19865992
Pulled By: hramos
fbshipit-source-id: 9e0b8e9519015bb62c60b9935a234cd367a1926a
Summary:
Cloning subtrees is not something specific to a RootNode, so it makes sense to have it in ShadowNode. Soon we will use that to clone subtrees inside Paragraph component to implement Inline Views.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: mdvacca
Differential Revision: D20090666
fbshipit-source-id: 0a64ef9bda438cd55d5fd21d3ad83b36221fa89e
Summary:
All logic that is performed on the root node only was moved from `layout` to a separate methods `layoutTree`. That makes the code simpler and allows reusing `layoutTree` in InlineViews feature.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: mdvacca
Differential Revision: D20052025
fbshipit-source-id: 3070a1cca4e322c6d077ede751ea80359c96a600
Summary:
Similar to a previous diff but for `setChildren`.
`YogaLayoutableShadowNode::setChildren()` was renamed to `YogaLayoutableShadowNode::updateYogaChildren()`. Now we don't need to pass an argument to this function because the object is already initialized. The new name also disambiguates this method with `getChildren()` from `ShadowNode` (which does something completely different). The rest of the changes is just type adjustments.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: mdvacca
Differential Revision: D20052031
fbshipit-source-id: 6157cad9b55d4cdd97ce04e1278ac1369bfb96bc
Summary:
`YogaLayoutableShadowNode::setProps()` was renamed to `YogaLayoutableShadowNode::updateYogaProps()`. Now we don't need to pass an argument to this function because the object is already initialized. The new name also disambiguates this method with `getProp()` from `ShadowNode` (which does something completely different).
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D20052018
fbshipit-source-id: 4d9651bb4452408708fa1b36bb5c5c8639f7d1bb
Summary:
How we can finally make `ViewProps` inherit `YogaStylableProps` and remove `dynamic_cast`. This overall change is aligned with D19963353.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D20052026
fbshipit-source-id: 1066f9a259b50d4672111c9c03a71c2590d59aca
Summary:
Here we delete several constructors that were needed only because `YogaLayoutableShadowNode::yogaStyle` was private (which is not true anymore).
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC, mdvacca
Differential Revision: D20052033
fbshipit-source-id: c2afcaf2fdebb65cdcde6c214c8b78aa35d45e91
Summary:
Here we refine the `ShadowNode::BaseTraits` static method. Before this change, ConcreteViewShadowNode<> enforces Layoutable and YogaLayoutable traits. This change moves that responsibility to LayoutableShadowNode and YogaLayoutableShadowNode which makes overall logic more coherent.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D20052027
fbshipit-source-id: fd25264204b0232b1dbbff6f9dfefd9fbcb146c4
Summary:
Now we can move custom to `YogaLayoutableShadowNode` code from `ConcreteViewShadowNode<>` template to `YogaLayoutableShadowNode` itself reducing the amount of templated code and reduce overall complexity.
Note, here we have to do `dynamic_cast` for now, we will address that in coming diffs.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: mdvacca
Differential Revision: D20052021
fbshipit-source-id: dac5969a97b75e54c7728a1ca8161922bd2245ca
Summary:
The fact that `LayoutableShadowNode` now inherits `ShadowNode` allows us to de-virtualize `getLayoutableChildNodes` and move that to `LayoutableShadowNode`. Less code, less virtual dispatch, less complexity.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D20052032
fbshipit-source-id: 580e86b5a746028e470788e00027f247bf77126c
Summary:
D19963353 mentioned the infrastructure that re-routes methods calls related to adding and cloning children between YogaLayoutableShadowNode and ShadowNode. `cloneAndReplaceChild` is exactly this. It was implemented as a virtual method that is called from `ConcreteViewShadowNode`. The whole process requires building a list of children of some class and passing that as a list of pointers. Now we don't need it all that because we can call directly and statically. That change will allow us to simplify that infra even more in the future diffs.
With all previous changes, now we can implement `getYogaLayoutableChildren` inside `YogaLayoutableShadowNode` and call that statically. Eventually, that will allow us to remove templated `getChildrenSlice`. Previously the call for that method must be in `ConcreteViewShadowNode`, now it's not true anymore which we will use later to even better goodness.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: mdvacca
Differential Revision: D20052020
fbshipit-source-id: e5c819a4d21b2dbcd08f3439e1783e3a9cba5ef4
Summary:
D19963353 mentioned the infrastructure that re-routes methods calls related to adding and cloning children between YogaLayoutableShadowNode and ShadowNode. `cloneAndReplaceChild` is exactly this. It was implemented as a virtual method that is called from `ConcreteViewShadowNode`. The whole process requires building a list of children of some class and passing that as a list of pointers. Now we don't need it all that because we can call directly and statically. That change will allow us to simplify that infra even more in the future diffs.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D20052022
fbshipit-source-id: ddf341c112edd8a2f79eaf74465a9a360a168541
Summary:
This is another perf-critical place where using traitCast should help with perf.
After this change we practically will not have any `dynamic_cast`s (except those which will be delited (with methods where they are used) in the future diffs).
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D20052029
fbshipit-source-id: 63b589d3c3322f0afd72f18b4701fe31d0e05c2f
Summary:
We use this function in Diffing, and Diffing is one of the hottest pieces of Fabric. Removing `dynamic_cast` here should improve perf. See the previous diff for more details.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D20052023
fbshipit-source-id: d6427ebf076d7f8244f0aeaf16407efa2368957e
Summary:
The Diffing is one of the hottest pieces of Fabric. Removing dynamic_cast here should improve perf. See the previous diff for more details.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D20052030
fbshipit-source-id: 27fd9f34f2a1f9d22b9da6b1e3c1a2982045c07a
Summary:
`traitCast` is a special form of static_cast that checks additional requirements (similar to `dynamic_cast`) before performing the cast. We will use that in many places in the coming diffs.
Restructuring the class hierarchy in the previous diff finally allows us to do static casts among ShadowNode and LayoutableShadowNode and other classes (previously it wasn't allowed because of lack of common base class).
Why we don't want to use `dynamic_cast`:
* It's expensive (and we need to do the cast on the hottest fragments of the framework). (See: (1) http://www.stroustrup.com/fast_dynamic_casting.pdf and (2) https://www.youtube.com/watch?v=ARYP83yNAWk Herb Sutter & proposal of `down_cast`).
* It's code-size inefficient, whereas `static_cast` has zero runtime and code-size overhead.
* Removing `dynamic_cast` will allow us finally to opt-out `RTTI` (additional code size and perm wins).
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D20052024
fbshipit-source-id: d293c1cf80deb7817d333d5306d6b32bf3abdb27
Summary:
This is a very crucial change, everything else in this stack depends on it.
Here is the set of constraints that we have for ShadowNode-based class hierarchy:
* `ShadowNode` is a base class that defines basic operations on the nodes. It does not have virtual methods by design (virtual dispatch hurts performance; we want to limit and centralize that in `ComponentDescriptor`s).
* `ConcreteShadowNode<>` template *statically* wires particular `ShadowNode` and particular `Props` establishing a type-safe relationship between them ensured on compile time.
* Not all `ShadowNode`s are "layoutable", not all "layoutable" `ShadowNode`s use Yoga to do layout.
* Layotability (and YogaLayotability) feature is implemented as two classes `LayoutableShadowNode` and `YogaLayoutableShadowNode`. These classes essentially need to know something about the ShadowNode nature of the object (get the list of children or replace some children).
Before the change, `LayoutableShadowNode` and `YogaLayoutableShadowNode`classes did not inherit `ShadowNode` because we don't want to use *virtual inheritance* for `ShadowNode`: `ConcreteShadowNode<>` already inherits `ShadowNode`, so if we make `LayoutableShadowNode` inherits `ShadowNode`, we will have to somehow flatten this inheritance hierarchy (and the virtual inheritance is an answer to that). (Yes, C++ supports multiple inheritance and virtual inheritance.)
Before this change, we solved this dilemma this way: We have a subclass-template `ConcreteViewShadowNode<>` that inherits `ConcreteShadowNode<>` and `YogaLayoutableShadowNode`. Then, we had a bunch of methods that implement the rerouting of some functionality from `YogaLayoutableShadowNode` to `ShadowNode` and vise-versa. (See the diagram "Before".)
That worked fine, except the caveats:
* That wiring is nasty, complex, hard to reason about and overall limiting.
* There is no way to statically cast `LayoutableShadowNode` to `ShadowNode` (because there is no common base class). That forces us to use dynamic_cast on some perf critical paths (including layout, diffing and so on).
* Adding features that rely on interop between `LayoutableShadowNode` and `ShadowNode` is a nightmare.
It should be a better way to deal with this dilemma, and this diff implements a different approach: We can have a base class of `ConcreteShadowNode<>` as a template parameter. With this approach, we can make `LayoutableShadowNode` inherit `ShadowNode` and when we need to instantiate a `ConcreteShadowNode<>` that needs to be layoutable, we can just specify `YogaLayoutableShadowNode` as a base class. (See the diagram "After".)
This simple change will allow us to simplify a lot of things. The rest of the stack is about getting rid of unnecessary moving parts. Which will finally allow us to build "Inline Views" feature.
```
╭──────────────────────╮
│ ◎ ○ ○ ░░░░░░░░░░░░░░░│
├──────────────────────┤
│ │
│ │
│ Before │
│ │ ┌────────────────────────────┐ ┌────────────────────────────┐
│ │ │ │ │ │
│ │ │ ShadowNode │ │ LayoutableShadowNode │
└──────────────────────┘ │ │ │ │
└────────────────────────────┘ └────────────────────────────┘
▲ ▲
│ │
╔════════════════════════════╗ ┌────────────────────────────┐
║ ║ │ │
┌────────�║ ConcreteShadowNode<> ║ │ YogaLayoutableShadowNode │
│ ║ ║ │ │
│ ╚════════════════════════════╝ └────────────────────────────┘
│ ▲ ▲
│ │ │
│ │ │
│ │ │
│ │ ╔════════════════════════════╗ │
│ │ ║ ║ │
│ └─────║ ConcreteViewShadowNode<> ║─┘
│ ║ ║
│ ╚════════════════════════════╝
│ ▲
│ │
│ ┌──────────────┴───────────────┐
│ │ │
│ │ │
│ │ │
┌────────────────────────────┐ ┌────────────────────────────┐ ┌────────────────────────────┐
│ │ │ │ │ │
│ TextShadowNode │ │ ViewShadowNode │ │ ParagraphShadowNode │
│ │ │ │ │ │
└────────────────────────────┘ └────────────────────────────┘ └────────────────────────────┘
╭──────────────────────╮
│ ◎ ○ ○ ░░░░░░░░░░░░░░░│
├──────────────────────┤
│ │ ┌────────────────────────────┐
│ │ │ │
│ After │ │ ShadowNode │
│ │ │ │
│ │ └────────────────────────────┘
│ │ ▲
└──────────────────────┘ ┌────────────────────────────────────┤
│ │
│ ╔════════════════════════════╗
┌────────────────────────────┐ ║ ConcreteShadowNode ║
│ │ ║ <Base: ShadowNode> ║
│ LayoutableShadowNode │ ║ ║
│ │ ╚════════════════════════════╝
└────────────────────────────┘ ▲
▲ │
│ ┌────────────────────────────┐
┌────────────────────────────┐ │ │
│ │ │ TextShadowNode │
│ YogaLayoutableShadowNode │ │ │
│ │ └────────────────────────────┘
└────────────────────────────┘
▲
│
╔════════════════════════════╗
║ ConcreteShadowNode ║
║ <Base: ║
║ YogaLayoutableShadowNode> ║
╚════════════════════════════╝
▲
│
╔════════════════════════════╗
║ ║
║ ConcreteViewShadowNode<> ║
║ ║
╚════════════════════════════╝
▲
├─────────────────────────────────────┐
│ │
┌────────────────────────────┐ ┌────────────────────────────┐
│ │ │ │
│ ParagraphShadowNode │ │ ViewShadowNode │
│ │ │ │
└────────────────────────────┘ └────────────────────────────┘
```
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D19963353
fbshipit-source-id: b65c8a5064bdb54ab64f08a8e546aa9e2b5a486b
Summary:
For backwards-compatibility with Paper, we're implementing a feature in Fabric that will allow TextInputs to use the default padding from the theme in Android.
Note that this uses some pretty ugly hacks that probably shouldn't be used inside of components at all: looking directly at rawProps, overriding props/Yoga styles in the component descriptor, etc. I would (personally) really like to kill this feature entirely unless and until we can find a more elegant solution.
Changelog: [Internal]
TextInputs are still not pixel-perfect with Paper, but they're much closer, and the underline visual glitchiness is no longer an issue.
Reviewed By: mdvacca
Differential Revision: D20109605
fbshipit-source-id: 543282843e0a9f03a504d72d7a014431099bd64c
Summary:
Changelog: [Internal]
As agreed in https://fb.quip.com/Oh2mAaTAbBj6, `findNodeAtPoint` now calls callback with `shadowNode` instead of `instanceHandle`.
Reviewed By: shergin
Differential Revision: D20097269
fbshipit-source-id: bd2a1bcd26ab2510f16c3e73f628be4b1f7dacfc
Summary:
Changelog: [Internal]
# Problem
Calling `UIManager::updateState` does not increment state revision because it calls `ConcreteComponentDescriptor::createState` which creates new state with state revision 1.
# How did this propagate?
This error propagated itself in TextInput when trying to input a value, you would be only allowed to type in 1 character.
Reviewed By: JoshuaGross
Differential Revision: D20072844
fbshipit-source-id: 37b8173307e1d91d6e9c41b5ff2e185dde31cc38
Summary:
We are moving towards 100%-prettified files. That's the first step when we apply Clang Format for `ReactCommon`.
Changelog: [Internal]
Reviewed By: mdvacca
Differential Revision: D20110895
fbshipit-source-id: 0a0ce4997cf1c3721b0b07ef78c1a57ce87d20f9
Summary: The `Function::call` method says it leaves the JS `this` object undefined. According to my tests, that's not completely true: if the function is defined to use strict mode via `"use strict"` either inside itself or in the file it was defined in, it does leave it `undefined`, but if the function is defined in non-strict mode, it sets `this` to the global object instead. This diff updates the documentation to reflect this.
Reviewed By: mhorowitz
Differential Revision: D19613483
fbshipit-source-id: 4b9ecf81c6318592be05a216748dcb22e32989f8
Summary:
Until now, there were two measure functions that differ in only one parameter (rootTag). The rootTag is used to use the context associated to the tag as part of the calculation of layout, otherwise it just uses the ReactApplicationContext.
This diff unifies both method into an unique method that
changelog: [internal]
Reviewed By: JoshuaGross
Differential Revision: D20081281
fbshipit-source-id: b1f6a6cedbf78f36f36fd0f93407c23c6996d76b