Summary:
Changelog: [Internal]
ScrollView didn't support centerContent prop. The implementation is copied over from Paper.
I added an example of this prop in RNTester.
Reviewed By: JoshuaGross
Differential Revision: D21548270
fbshipit-source-id: 28f6c8d769c5a6bc1d111b33970a06b95c259132
Summary:
This diff implements iOS-specific `PlatformRunLoopObserver` (and `MainRunLoopObserver`) that then being glued together with `SynchronousEventBeat` replaces `MainRunLoopEventBeat`, and then same thing glued with `AsynchronousEventBeat` replaces `RuntimeEventBeat`.
So, instead of two platform-specific classes we had on iOS (for that needs), now we have only one (that can be reused for a more broad variety of applications).
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D21341998
fbshipit-source-id: fafde4e678770f7fcf9c1ff87acc02812a37e708
Summary:
Changelog: [internal]
As part of recycle, we should delete state. This is a common pattern used in other components as well.
Reviewed By: shergin
Differential Revision: D21348782
fbshipit-source-id: a5dee2f4ccee9b19498db31dab1983d8879dca71
Summary:
In D20836890 we no longer set `_contentView.frame` inside `layoutSubviews`.
This doesn't work well with component views that set their `contentView` after `updateLayoutMetrics` is called. For Example legacy interop which sets its contentView in the `finalizeUpdates` method. Other component views that set their contentView during initialisation are fine.
Changelog: [Internal]
Reviewed By: shergin
Differential Revision: D21302108
fbshipit-source-id: 5adcf489e4e650ac04b84c836a8f8d6f55a77267
Summary:
Changelog: [Internal]
When there is a change coming from javascript, avoid triggering `onChange ` and `onSelectionChange` events since JavaScript already has these changes. This is only necessary for multiline text.
For changes coming through view commands, do not increment `_mostRecentEventCount`.
Reviewed By: shergin
Differential Revision: D21255228
fbshipit-source-id: e972dab0eb3dd21f611ee5c71d755bab593ae9cc
Summary:
Changelog: [Internal]
In `onKeyPress` event, we were not returning `key` property. This diff adds `key` property to `onKeyPress` event and removes other, redundant properties from `onKeyPress` event.
The implementation has been translated from Paper.
Reviewed By: shergin
Differential Revision: D21250411
fbshipit-source-id: f1e31381667acb9dec02d0b33883df8f8f5b2a4b
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/28730
Moving RuntimeExecutor out of react/utils and into its own subdir of ReactCommon. I'm doing this because I'm going to be pulling this into CatalystInstance on Android, and I don't want to pull in all the files we don't need there; also, this should hopefully make the OSS NDK stuff easier (this uses the react/utils prefix to export, and I'm not sure if you can include a '/' in a gradle module name?)
Changelog: [Internal]
Reviewed By: shergin, mdvacca
Differential Revision: D21098528
fbshipit-source-id: 9fbd72901ece522b1caec3ec34fafb8f9b327275
Summary:
Before the change, an incorrect (NaN or Inf) values in LayoutMetrics might force an early return in the `updateLayoutMetrics:oldMetrics:` method implementation. This was not correct because the rest of the method also didn't run in this case, so it might force some value to stale.
E.g., imagine we have an instruction that contains NaN size and `display: none`. Previously, the function might just return right before applying sizes and progress the stored "already applied" value of LayoutMetrics which will cause the view being visible even if it should not.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: JoshuaGross
Differential Revision: D21110644
fbshipit-source-id: 501319d7b1dcd5c18f27e0ceca3c8d207485c49b
Summary:
We need to break up the `uimanager` module in order to solve circular dependencies problem (which future diff would have otherwise).
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: JoshuaGross
Differential Revision: D20885645
fbshipit-source-id: 8148bd934879802b076261ed86fa78acf0a07ed3
Summary:
We need to break up the `uimanager` module in order to solve circular dependencies problem (which future diff would have otherwise).
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: JoshuaGross
Differential Revision: D20885163
fbshipit-source-id: 08eb1ba1d408fc0948e8d0da62380786a40973af
Summary:
Changelog: [Internal]
We don't use view command `setMostRecentEventCount`, let's get rid of it.
Reviewed By: JoshuaGross
Differential Revision: D21016600
fbshipit-source-id: 6491c063e9d6a89252300cb47c010b248e473f4b
Summary:
Now we can control the differentiator mode via MC.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: fkgozali
Differential Revision: D20978857
fbshipit-source-id: 13264948762f02f874d8d051c873d378062d6db4
Summary:
Changelog: [Internal]
Calling `_backedTextInputView.attributedText = attributedString` causes cursor to be moved to the end of text input.
This applies to both, `UITextField` and `UITextView`.
This is not desired as when JS sets a new text, we don't want the cursor to be moved to the end of text input.
JS has the option to use view commands if it wishes to move cursor somewhere.
Reviewed By: JoshuaGross
Differential Revision: D20836201
fbshipit-source-id: 9234e54cfbc5fc206f723626988e505275788aae
Summary:
Changelog: [Internal]
UIKit uses either `UITextField` or `UITextView` as its UIKit element for `<TextInput>`. `UITextField` is for single line entry, `UITextView` is for multiline entry.
There is a problem with order of events when user types a character.
In `UITextField` (single line text entry), typing a character first triggers `onChange` event and then `onSelectionChange`. JavaScript depends on this order of events because it uses `mostRecentEventCount` from this even to communicate to native that it is in sync with changes in native.
In `UITextView` (multi line text entry), typing a character first triggers `onSelectionChange` and then `onChange`. As JS depends on the correct order of events, this can cause issues. An example would be a TextInput which changes contents based as a result of `onSelectionChange`. Those changes would be ignored as native will throw them away because JavaScript doesn't have the newest version.
Reviewed By: JoshuaGross
Differential Revision: D20836195
fbshipit-source-id: fbae3b6c0d388fc059ca2541ae980073b8e5f6c7
Summary:
Changelog: [Internal]
Setting `_borderLayer.frame` inside `-[RCTViewComponentView layoutSubviews]` causes unwanted animation because it is not wrapped in `CATransaction`.
Moving it to `-[RCTViewComponentView updateLayoutMetrics]` which is called inside `CATransaction`.
Reviewed By: shergin
Differential Revision: D20836890
fbshipit-source-id: 2048a25fd2edb8109f6275c1186c0adae4b9f504
Summary:
We are replacing inline-ed implementation with practically the same one implemented as the helper method.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D20551409
fbshipit-source-id: fcc6f497cd240af65fba534051c217fe5746ce82
Summary:
An evolution of D20633188 but more performant.
There are three optimized paths before the slow path.
The first optimized path tries to pair identical nodes from old/new tree, and generate Update mutations, until we hit nodes that are different (indicating either a remove or an insert). This already existed.
The next two optimizations, introduced by Tim in his JS pseudocode, were inspired by ReactJS's diffing algorithm. They work in cases where the rest of the nodes are (1) all removals/deletes or (2) all creates+inserts.
Finally, if those final two optimized paths can't run, it's because there is a mix of delete+remove, create+insert, and "move" operations, mixed at the beginning, middle, and/or end of the list.
This has slightly better average/best-case complexity as the previous implementation.
In particularly pathological cases where all nodes are arbitrarily reordered, or reversed, for instance (ABCDE->EDCBA) the algorithm has the same complexity as the previous algorithm (quadratic).
For now iOS is pinned to the older differ
Changelog: [Internal] Experiment to optimize diffing algorithm in Fabric
Reviewed By: shergin
Differential Revision: D20684094
fbshipit-source-id: d29fba95a0328156c023e1c87804f23770ee1d91
Summary:
This is another attempt to fix an issue very similar to T59424871. The previous attempt was in D19249490. I don't know why we don't see production crashes (stalls) but it happened to me (and not to me) in the debugger. The previous attempt didn't work because we still could have a deadlock because we tried to acquired shared mutex already owned exclusively by the `suspend` method.
Here is another approach: Instead of using one shared mutex, now we use two. One is similar to what we had and another that protects `suspend` and `resume`. Besides that, now we pass a Scheduler to functions that use that explicitly. This way we can be more explicit about acquiring mutexes and the overall flow of execution. The idea is: Now an arbitrary code that can be reentrant does not cover with mutexes, so the deadlock is not possible.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D20639228
fbshipit-source-id: 98515742f00f2ae94b50b585c9f1f0611e169ebe
Summary:
Changelog: [Internal]
# There are three changes in this diff
## _stateRevision is replaced with a BOOL
`_stateRevision` was protecting against setting attributed string that is already visible to the user. Previously this was ok because the change was only coming from native, any changes from JS were ignored.
Imagine following scenario:
1. User taps key.
2. Update state is called on component initiated by native.
3. New state is created with incremented revision by one.
4. `_stateRevision` gets set to new state's revision + 1.
5. Now JS wants to change something because it just learnt that user tapped the key.
6. New state is created again with incremented revision by one.
7. Update state is called on the component, but the change isn't applied to the text view because `_state->getRevision()` will equal `_stateRevision`.
By having a BOOL instead of number, we very explicitly mark the region in which we don't want state changes to be applied to text view.
## Calling [_backedTextInputView setAttributedText] move cursor to the end of text input
This is prevented by storing what the current selection is and applying it after `[_backedTextInputView setAttributedText]` is called.
This was previously invisible because JS wasn't changing contents of `_backedTextInputView`.
## Storing of previously applied JS attributed string in state
This is the mechanism used to detect when value of text input changes come from JavaScript. JavaScript sends text input value changes through props and as children of TextInput.
We compare what previously was set from JavaScript to what is currently being send from JavaScript and if they differ, this change is communicated to the component.
Previously only first attributed string send from JavaScript was send to the component.
# Problem
If children are used to set text input's value, then there is a case in which we can't tell what source of truth should be.
Let's take following example
We have a text field that allows only 4 characters, again this is only a problem if those 4 characters come as children, not as value.
This is a controller text input.
1. User types 1234.
2. User types 5th character.
3. JavaScript updates TextInput, saying that the content should stay 1234.
4. In `TextInputShadowNode` `hasJSUpdatedAttributedString` will be set to false, because previous JS value is the same as current JS value.
Reviewed By: shergin
Differential Revision: D20587681
fbshipit-source-id: 1b8a2efabbfa0fc87cba210570142d162efe61e6
Summary:
Changelog: [Internal]
# Fabric
1. If `start` and `end` parameters in `setTextAndSelection` are -1, we don't move the cursor. Previously the cursor would be moved to beginning of text input.
2. In view commands, do not validate `eventCount`. It is passed in as undefined from JS because Fabric's text input doesn't use `eventCount`.
# Paper
1. If `start` and `end` parameters in `setTextAndSelection` are -1, we don't move the cursor. Previously the cursor would be moved to beginning of text input.
Reviewed By: shergin
Differential Revision: D20538290
fbshipit-source-id: c7aeddc25f58697254474058ce901df958321f7c
Summary:
The new prop on RCTParagraphComponentView is meant to be used only by external introspection tools, not the RN core.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: nscoding
Differential Revision: D20523078
fbshipit-source-id: 4c457d070fd2c172d681c5aa7f731d2d52bba291
Summary:
Changelog: [internal]
layoutDirectionPass down layoutDirection from `RCTSurfacePresenter` down to `YogaLayutableShadowNode`.
In `ParagraphShadowNode`, we propagate layoutDirection from yoga node to `TextAttributes.layoutDirection`.
Reviewed By: shergin
Differential Revision: D20420041
fbshipit-source-id: 86e01d31ea9415acb8579c44c470cac870ec1b8f
Summary:
Changelog: [Internal]
# Problem
SafeAreaView is getting reused, its previous `safeAreaInsets` is top: 44, bottom: 34 so `safeAreaInsetsDidChange` doesn't get called because it doesn't change. Therefore state gets never updates because `safeAreaInsetsDidChange` is never called.
# Solution
Update state whenever a new state is assigned.
Reviewed By: shergin
Differential Revision: D20444198
fbshipit-source-id: 75d1458450c70d74647df4962ddad88d5f6a38d2
Summary:
Changelog: [internal]
# Problem
Assigning `CALayer.contents` implicitly animates the difference. As we keep `UIView` in recycle pool between usages, they keep their previous state. This was causing animation of border when the views were being reused.
# Solution
Wrapping application of mutations in `CATTransaction`.
Reviewed By: shergin
Differential Revision: D20442045
fbshipit-source-id: 214d6c422f23f399dec46b5bf1a38a7b64758160
Summary:
Now we have `zIndex` feature implemented in the Core, we don't need to take `view.layer.zIndex` into account when we do hit-testing, so now we don't need to sort *all subviews* on *all levels of hierarchy* every time we process touch down event.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D20425987
fbshipit-source-id: 025bd968ae948b9b0a4188845efc0de950fb5cdf
Summary:
Now we have `zIndex` feature implemented in the Core, we don't need to have it implemented on the mounting layer.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D20432156
fbshipit-source-id: f77b96919bab21b6628472b9fe58c5f4e3233318
Summary:
Before this change, fields of EmptyLayoutMetrics have some "invalid" values to allow us to compare equal them individually and get `false`. Turned out that having invalid values there might break some serialization layers, which is no good.
This change fixes that and adds explicit check for EmptyLayoutMetrics before running a comparison of individual fields.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: mdvacca
Differential Revision: D20324881
fbshipit-source-id: ab8e2a402f6bdfb393fc9b6789decb526fa94dfa
Summary:
Changelog: [Internal]
# Problem
`scrollView.state.contentOffset` was not in sync with actual `contentOffset` in case `contentOffset` is changed programatically.
# Solution
Add a flag `_isUserTriggeredScrolling` that indicates whether the current scroll is triggered by user or not. In case it isn't, update state.
Reviewed By: shergin
Differential Revision: D20098161
fbshipit-source-id: 021d916e7a45a24095a47bb8f84d1102226b672a
Summary:
Investigating a crash, I spend half of an hour staring at `__bridge`, `__bridge_retained`, `CFRelease` and etc trying to understand is there a bug or not. Even if I think there was no bug there, it should not be this way. We have a nice abstraction around that madness we should use to make the code obvious.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D20260917
fbshipit-source-id: 2b511ebf46a78950c4720e749099134aed1dd890
Summary:
We don't know why exactly it happens but (seemingly) sometime Paragraph component receives an empty State object. This causes a crash because of unchecked access to an instance variable.
This diff introduces an assert in DEBUG mode and the check for prod.
Why is this happens? Hard to say, probably `layout()` method (which updates `State`) is not being called on ShadowNode. Why? One explanation can be that Yoga skips some subtree during layout because it starts from "visibility: hidden" component. We need to investigate it more and figure out what exactly going on and what should we need to improve besides the check. That's why we have an assertion.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: sammy-SC
Differential Revision: D20260512
fbshipit-source-id: 4772855f41c6694be2ed6c0a19da40332d2bb8db
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:
We are moving towards 100%-prettified files. That's another step when we apply Clang Format for `React/Fabric`.
Changelog: [Internal]
Reviewed By: mdvacca
Differential Revision: D20112417
fbshipit-source-id: 020d818e5cb8e2f509c5276738c8f252f6817a56
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:
Changelog: [Internal]
If `layer.mask` was set and the view got reused without having a different `layer.mask`, this value would persist between reuses.
I also added a call to `super finalizeUpdates` as it is best practice to call super, the parent class right now doesn't do anything but in the future we might add there some default logic.
Reviewed By: shergin
Differential Revision: D20030174
fbshipit-source-id: c90be3f4e9a8f3814000f177a3d50061f5aa120c
Summary:
Changelog: [Internal]
Switching queue here is not necessary if we are already on the main queue.
This is important for Fabric SSTs, otherwise images are missing.
Reviewed By: shergin
Differential Revision: D19907908
fbshipit-source-id: 52e82484afc8e2f591d0c5cc126952990d992e96
Summary:
Changelog: [Internal]
When I was originally implementing this view command (D19471025), I misunderstood the desired behaviour.
The text parameter isn't meant to change text in the specified `select` but it is supposed to override text of entire text input.
Reviewed By: shergin
Differential Revision: D19793484
fbshipit-source-id: 64ba36ddfa27ac5a0adf48495cb4e985a429e005