Commit Graph

47 Commits

Author SHA1 Message Date
Rubén Norte 0700dd50bd
Implement public instances for text nodes in Fabric (#26516)
## Summary

This adds the ability to create public instances for text nodes in
Fabric. The implementation for the public instances lives in React
Native (as it does for host components after #26437). The logic here
just handles their lazy instantiation when requested via
`getPublicInstanceFromInternalInstanceHandle`, which is called by Fabric
with information coming from the shadow tree.

It's important that the creation of public instances for text nodes is
done lazily to avoid regressing memory usage when unused. Instances for
text nodes are left intact if the public instance is never accessed.

This is necessary to implement access to text nodes in React Native as
explained in
https://github.com/react-native-community/discussions-and-proposals/pull/607

## How did you test this change?

Added unit tests (also fixed a test that was only testing the logic in a
mock :S).
2023-04-04 14:43:35 +01:00
Rubén Norte 9c54b29b44
Remove ReactFabricPublicInstance and used definition from ReactNativePrivateInterface (#26437)
## Summary

Now that React Native owns the definition for public instances in Fabric
and ReactNativePrivateInterface provides the methods to create instances
and access private fields (see
https://github.com/facebook/react-native/pull/36570), we can remove the
definitions from React.

After this PR, React Native public instances will be opaque types for
React and it will only handle their creation but not their definition.
This will make RN similar to DOM in how public instances are handled.

This is a new version of #26418 which was closed without merging.

## How did you test this change?

* Existing tests.
* Manually synced the changes in this PR to React Native and tested it
end to end in Meta's infra.
2023-03-22 17:54:36 +00:00
Rubén Norte f828bad387
Extracted definition and access to public instances to a separate module in Fabric (#26321)
## Summary

The current definition of `Instance` in Fabric has 2 fields:
- `node`: reference to the native node in the shadow tree.
- `canonical`: public instance provided to users via refs + some
internal fields needed by Fabric.

We're currently using `canonical` not only as the public instance, but
also to store internal properties that Fabric needs to access in
different parts of the codebase. Those properties are, in fact,
available through refs as well, which breaks encapsulation.

This PR splits that into 2 separate fields, leaving the definition of
instance as:
- `node`: reference to the native node in the shadow tree.
- `publicInstance`: public instance provided to users via refs.
- Rest of internal fields needed by Fabric at the instance level.

This also migrates all the current usages of `canonical` to use the
right property depending on the use case.

To improve encapsulation (and in preparation for the implementation of
this [proposal to bring some DOM APIs to public instances in React
Native](https://github.com/react-native-community/discussions-and-proposals/pull/607)),
this also **moves the creation of and the access to the public instance
to separate modules** (`ReactFabricPublicInstance` and
`ReactFabricPublicInstanceUtils`). In a following diff, that module will
be moved into the `react-native` repository and we'll access it through
`ReactNativePrivateInterface`.

## How did you test this change?

Existing unit tests.
Manually synced the PR in Meta infra and tested in Catalyst + the
integration with DevTools. Everything is working normally.
2023-03-13 13:25:42 +00:00
Rubén Norte d49e0e0be0
Removed unused imperative events implementation from React Native renderer (#26282)
## Summary

I'm going to start implementing parts of this proposal
https://github.com/react-native-community/discussions-and-proposals/pull/607

As part of that implementation I'm going to refactor a few parts of the
interface between React and React Native. One of the main problems we
have right now is that we have private parts used by React and React
Native in the public instance exported by refs. I want to properly
separate that.

I saw that a few methods to attach event handlers imperatively on refs
were also exposing some things in the public instance (the
`_eventListeners`). I checked and these methods are unused, so we can
just clean them up instead of having to refactor them too. Adding
support for imperative event listeners is in the roadmap after this
proposal, and its implementation might differ after this refactor.

This is essentially a manual revert of #23386.

I'll submit more PRs after this for the rest of the refactor.

## How did you test this change?

Existing jest tests. Will test a React sync internally at Meta.
2023-03-02 15:54:51 +00:00
Rubén Norte 53b1f69ba6
Implement unstable_getBoundingClientRect in RN Fabric refs (#26137)
We're fixing the timing of layout and passive effects in React Native,
and adding support for some Web APIs so common use cases for those
effects can be implemented with the same code on React and React Native.

Let's take this example:

```javascript
function MyComponent(props) {
  const viewRef = useRef();

  useLayoutEffect(() => {
    const rect = viewRef.current?.getBoundingClientRect();
    console.log('My view is located at', rect?.toJSON());
  }, []);

  return <View ref={viewRef}>{props.children}</View>;
}
```

This could would work as expected on Web (ignoring the use of `View` and
assuming something like `div`) but not on React Native because:
1. Layout is done asynchronously in a background thread in parallel with
the execution of layout and passive effects. This is incorrect and it's
being fixed in React Native (see
afec07aca2).
2. We don't have an API to access layout information synchronously. The
existing `ref.current.measureInWindow` uses callbacks to pass the
result. That is asynchronous at the moment in Paper (the legacy renderer
in React Native), but it's actually synchronous in Fabric (the new React
Native renderer).

This fixes point 2) by adding a Web-compatible method to access layout
information (on Fabric only).

This has 2 dependencies in React Native:
1. Access to `getBoundingClientRect` in Fabric, which was added in
https://github.com/facebook/react-native/blob/main/ReactCommon/react/renderer/uimanager/UIManagerBinding.cpp#L644-
L676
2. Access to `DOMRect`, which was added in
673c7617bc
.

As next step, I'll modify the implementation of this and other methods
in Fabric to warn when they're accessed during render. We can't do this
on Web because we can't (shouldn't) modify built-in DOM APIs, but we can
do it in React Native because the refs objects are built by the
framework.
2023-02-09 18:51:47 +00:00
Samuel Susla b14d7fa4b8
Add support for setNativeProps to Fabric (#25737)
Add support for `setNativeProps` in Fabric to make migration to the new
architecture easier. The React Native part of this has already landed in
the core and iOS in
1d3fa40c59.

It is still recommended to move away from `setNativeProps` because the
API will not work with future features.
2022-12-09 14:43:52 +00:00
Andrew Clark 9cdf8a99ed
[Codemod] Update copyright header to Meta (#25315)
* Facebook -> Meta in copyright

rg --files | xargs sed -i 's#Copyright (c) Facebook, Inc. and its affiliates.#Copyright (c) Meta Platforms, Inc. and affiliates.#g'

* Manual tweaks
2022-10-18 11:19:24 -04:00
Jan Kassens d3c6c16a03 Flow upgrade to 0.145
Fixed a RN library definition that defined `CustomEvent` as a reference to itself.

ghstack-source-id: 90da2e316f
Pull Request resolved: https://github.com/facebook/react/pull/25409
2022-10-04 11:01:50 -04:00
Jan Kassens 9328988c02
Flow: fix Fiber typed as any (#25241) 2022-09-12 13:44:58 -04:00
Jan Kassens 8003ab9cf5
Flow: remove explicit object syntax (#25223) 2022-09-09 16:03:48 -04:00
Jan Kassens 8a9e7b6cef
Flow: implicit-inexact-object=error (#25210)
* implicit-inexact-object=error
* default everything ambiguous to exact object
* inexact where exact causes errors
2022-09-09 10:13:58 -04:00
Joshua Gross 05c283c3c3
Fabric HostComponent as EventEmitter: support add/removeEventListener (unstable only) (#23386)
* Implement addEventListener and removeEventListener on Fabric HostComponent

* add files

* re-add CustomEvent

* fix flow

* Need to get CustomEvent from an import since it won't exist on the global scope by default

* yarn prettier-all

* use a mangled name consistently to refer to imperatively registered event handlers

* yarn prettier-all

* fuzzy null check

* fix capture phase event listener logic

* early exit from getEventListeners more often

* make some optimizations to getEventListeners and the bridge plugin

* fix accumulateInto logic

* fix accumulateInto

* Simplifying getListeners at the expense of perf for the non-hot path

* feedback

* fix impl of getListeners to correctly remove function

* pass all args in to event listeners
2022-03-02 12:00:08 -08:00
Joshua Gross 9d4e8e84f7
React Native raw event EventEmitter - intended for app-specific perf listeners and debugging (#23232)
* RawEventEmitter: new event perf profiling mechanism outside of Pressability to capture all touch events, and other event types

* sync

* concise notation

* Move event telemetry event emitter call from Plugin to ReactFabricEventEmitter, to reduce reliance on the plugin system and move the emit call further into the core

* Backout changes to ReactNativeEventPluginOrder

* Properly flow typing event emitter, and emit event to two channels: named and catchall

* fix typing for event name string

* fix typing for event name string

* fix flow

* Add more comments about how the event telemetry system works

* Add more comments about how the event telemetry system works

* rename to RawEventTelemetryEventEmitterOffByDefault

* yarn prettier-all

* rename event

* comments

* improve flow types

* renamed file
2022-02-07 18:34:01 -08:00
Samuel Susla 1a3f1afbd3
[React Native] Fabric get current event priority (#21553)
* Call into Fabric to get current event priority

Fix flow errors

* Prettier

* Better handle null and undefined cases

* Remove optional chaining and use ?? operator

* prettier-all

* Use conditional ternary operator

* prettier
2021-06-08 12:26:21 -04:00
Joshua Gross bd070eb2c4
Enable setJSResponder/setIsJSResponder for React Native Fabric (#21439)
* Enable setJSResponder/setIsJSResponder for React Native

* yarn prettier

* add types to react-native-host-hooks

* yarn prettier

* mock setIsJSResponder
2021-05-05 21:09:04 -07:00
Joshua Gross f8979e0e28
Revert 'Fabric-compatible implementation of feature' and have Fabric noop when setJSResponder is called for now (#21009) 2021-03-15 12:22:26 -07:00
Valentin Shergin 78d2f2d301
Fabric-compatible implementation of `JSReponder` feature (#20768)
With this change, if a node is a Fabric node, we route the setJSResponder call to FabricUIManager. Native counterpart is already landed. Tested internally as D26241364.
2021-02-22 16:50:03 -05:00
Joshua Gross e316f78552
RN: Implement `sendAccessibilityEvent` in RN Renderer that proxies between Fabric/non-Fabric (#20554)
* RN: Implement `sendAccessibilityEvent` on HostComponent

Implement `sendAccessibilityEvent` on HostComponent for Fabric and non-Fabric RN.

Currently the Fabric version is a noop and non-Fabric uses
AccessibilityInfo directly. The Fabric version will be updated once
native Fabric Android/iOS support this method in the native UIManager.

* Move methods out of HostComponent

* Properly type dispatchCommand and sendAccessibilityEvent handle arg

* Implement Fabric side of sendAccessibilityEvent

* Add tests: 1. Fabric->Fabric, 2. Paper->Fabric, 3. Fabric->Paper, 4. Paper->Paper

* Fix typo: ReactFaricEventTouch -> ReactFabricEventTouch

* fix flow types

* prettier
2021-01-26 20:02:40 -08:00
Dan Abramov e3f4eb7272
Fork legacy-events folder into react-dom and react-native (#19228) 2020-07-01 16:37:13 +01:00
Andrew Clark 376d5c1b5a Split cross-package types from implementation
Some of our internal reconciler types have leaked into other packages.
Usually, these types are treated as opaque; we don't read and write
to its fields. This is good.

However, the type is often passed back to a reconciler method. For
example, React DOM creates a FiberRoot with `createContainer`, then
passes that root to `updateContainer`. It doesn't do anything with the
root except pass it through, but because `updateContainer` expects a
full FiberRoot, React DOM is still coupled to all its fields.

I don't know if there's an idiomatic way to handle this in Flow. Opaque
types are simlar, but those only work within a single file. AFAIK,
there's no way to use a package as the boundary for opaqueness.

The immediate problem this presents is that the reconciler refactor will
involve changes to our internal data structures. I don't want to have to
fork every single package that happens to pass through a Fiber or
FiberRoot, or access any one of its fields. So my current plan is to
share the same Flow type across both forks. The shared type will be a
superset of each implementation's type, e.g. Fiber will have both an
`expirationTime` field and a `lanes` field. The implementations will
diverge, but not the types.

To do this, I lifted the type definitions into a separate module.
2020-04-08 23:49:23 -07:00
Andrew Clark d686f3f16a Add `.old` prefix to reconciler modules 2020-04-08 23:49:19 -07:00
Ricky dd7e5e4f5a
Add getInspectorDataForViewAtPoint (take two) (#18388)
* Add getInspectorDataForViewAtPoint (take two)

* Updates from review

* Add DEV to dev-only variable

* Missed this rename
2020-03-30 15:42:41 -04:00
Sebastian Markbage a463fef31b Revert "[React Native] Add getInspectorDataForViewAtPoint (#18233)"
This reverts commit bf351089a0.
2020-03-11 10:05:26 -07:00
Ricky bf351089a0
[React Native] Add getInspectorDataForViewAtPoint (#18233) 2020-03-11 16:12:41 +00:00
Eli White 26aa1987ce
[Native] Enable and remove targetAsInstance feature flag. (#18182) 2020-02-28 13:45:42 -08:00
Dan Abramov e706721490
Update Flow to 0.84 (#17805)
* Update Flow to 0.84

* Fix violations

* Use inexact object syntax in files from fbsource

* Fix warning extraction to use a modern parser

* Codemod inexact objects to new syntax

* Tighten types that can be exact

* Revert unintentional formatting changes from codemod
2020-01-09 14:50:44 +00:00
Eli White 2c6ea0b3ff
[Native] Add FeatureFlag to dispatch events with instance targets (#17323)
* [Native] Add FeatureFlag to dispatch events with instance targets

* Prettier
2019-11-11 11:35:29 -08:00
Moti Zilberman 61d3dd0e08
Update deepDiffer usage in React Native renderer (#17282)
* Add RN prop diffing test with function values

* Update RN deepDiffer mock

* Explicitly ignore functions in RN prop differ
2019-11-07 04:00:20 -08:00
Brian Vaughn b1a03dfdc8
Rename legacy "events" package to "legacy-events" (#16388)
* Renamed 'events' package to 'legacy-events'
* Updated 'events' references to point to 'legacy-events'
2019-08-14 07:32:42 -07:00
Moti Zilberman c45c2c3a26 Move ReactFiberErrorDialog RN fork into RN itself (#16141) 2019-07-16 09:38:14 +01:00
Eli White 8533c0a168
[Fabric] Add dispatchCommand to React Native renderers (#16085)
* Add dispatchCommand to the public export of the React Native renderers

* Fixup invalid check

* Prettier

* Prettier
2019-07-08 13:03:57 -07:00
James Ide 07da821bfd [react-native] Rewrite Haste imports in RN shims and add .fb.js extension (#15786)
This commit is a follow-up to https://github.com/facebook/react/pull/15604, which explains more of the rationale behind moving React Native to path-based imports and the work needed in the React repository. In that linked PR, the generated renderers were updated but not the shims; this commit updates the shims.

The problem is that FB needs a different copy of the built renderers than the OSS versions so we need a way for FB code to import different modules than in OSS. This was previously done with Haste, but with the removal of Haste from RN, we need another mechanism. Talking with cpojer, we are using a `.fb.js` extension that Metro can be configured to prioritize over `.js`.

This commit generates FB's renderers with the `.fb.js` extension and OSS renderers with just `.js`. This way, FB can internally configure Metro to use the `.fb.js` implementations and OSS will use the `.js` ones, letting us swap out which implementation gets bundled.

Test Plan: Generated the renderers and shims with `yarn build` and then verified that the generated shims don't contain any Haste-style imports. Copied the renderers and shims into RN manually and launched the RNTester app to verify it loads end-to-end. Added `.fb.js` to the extensions in `metro.config.js` and verified that the FB-specific bundles loaded.
2019-06-03 15:58:31 +01:00
James Ide 61f62246c8 [react-native] Use path-based imports instead of Haste for the RN renderer (#15604)
* [react-native] Use path-based imports instead of Haste for the RN renderer

To move React Native to standard path-based imports instead of Haste, the RN renderer that is generated from the code in this repo needs to use path-based imports as well since the generated code is vendored by RN. This commit makes it so the interface between the generated renderers and RN does not rely on Haste and instead uses a private interface explicitly defined by RN. This inverts control of the abstraction so that RN decides the internals to export rather than React deciding what to import.

On RN's side, a new module named `react-native/Libraries/ReactPrivate/ReactNativePrivateInterface` explicitly exports the modules used by the renderers in this repo. (There is also a private module for InitializeCore so that we can import it just for the side effects.) On React's side, the various renderer modules access RN internals through the explicit private interface.

The Rollup configuration becomes slimmer since the only external package is now `react-native`, and the individual modules are instead listed out in `ReactNativePrivateInterface`.

Task description: https://github.com/facebook/react-native/issues/24770
Sister RN PR (needs to land before this one): https://github.com/facebook/react-native/pull/24782

Test Plan: Ran unit tests and Flow in this repo. Generated the renderers and manually copied them over to the RN repo. Ran the RN tests and launched the RNTester app.

* Access natively defined "nativeFabricUIManager" instead of importing it

Some places in the Fabric renderers access `nativeFabricUIManager` (a natively defined global) instead of importing UIManager. While this is coupling across repos that depends on the timing of events, it is necessary until we have a way to defer top-level imports to run after `nativeFabricUIManager` is defined. So for consistency we use `nativeFabricUIManager` everywhere (see the comment in https://github.com/facebook/react/pull/15604#pullrequestreview-236842223 for more context).
2019-05-23 08:23:54 +01:00
Eli White 12e5a13cf2
[React Native] Inline calls to FabricUIManager in shared code (#15490)
* [React Native] Inline calls to FabricUIManager in shared code

* Call global.nativeFabricUIManager directly as short term fix

* Add flow types

* Add nativeFabricUIManager global to eslint config

* Adding eslint global to bundle validation script
2019-04-29 14:31:16 -07:00
Eli White 1b2159acc3
[React Native] measure calls will now call FabricUIManager (#15324)
* [React Native] Add tests to paper renderer for measure, measureLayout

* [React Native] measure calls will now call FabricUIManager

The Fabric renderer was previously calling the paper UIManager's measure calls and passing the react tag. This PR changes the renderer to now call FabricUIManager passing the node instead.

One of the parts of this that feels more controversial is making NativeMethodsMixin and ReactNative.NativeComponent warn when calling measureLayout in Fabric. As Seb and I decided in https://github.com/facebook/react/pull/15126, it doesn't make sense for a component created with one of these methods to require a native ref but not work the other way around. For example: a.measureLayout(b) might work but b.measureLayout(a) wouldn't. We figure we should keep these consistent and continue migrating things off of NativeMethodsMixin and NativeComponent.

If this becomes problematic for the Fabric rollout then we should revisit this.

* Fixing Flow

* Add FabricUIManager to externals for paper renderer

* import * as FabricUIManager from 'FabricUIManager';

* Update tests

* Shouldn't have removed UIManager import

* Update with the new tests
2019-04-09 15:10:15 -07:00
Héctor Ramos b87aabdfe1
Drop the year from Facebook copyright headers and the LICENSE file. (#13593) 2018-09-07 15:11:23 -07:00
Sebastian Markbåge 4fa20b53b7
Don't pass instanceHandle to clones (#13125)
We will instead just reuse the first one.
2018-08-16 09:54:12 -07:00
Sebastian Markbåge 64e1921aab
Fix Flow type that event target can be null (#13124)
We pass null sometimes when the event target has disappeared. E.g. when
touches fires on a deleted node.
2018-06-29 12:51:48 -07:00
Sebastian Markbåge c5a8dae025
[Fabric] Wire up event emitters (#12847)
I'm exposing a new native method to wire up the event emitter. This will
use a straight fiber pointer instead of react tags to do the dispatching.
2018-05-17 12:38:50 -07:00
Sebastian Markbåge f792275972
Pass instance handle to all Fabric clone methods (#12824)
We might need this in the future if we want to ensure event handler
consistency when an event handler target has been removed before it is
called.
2018-05-15 14:35:13 -07:00
Sebastian Markbåge b99d0b1416
[RN] Move view config registry to shims (#12569)
* Move view config registry to shims

This ensures that both Fabric and RN renderers share the same view config
registry since it is stateful.

I had to duplicate in the mocks for testing.

* Move createReactNativeComponentClass to shims and delete internal usage

Since createReactNativeComponentClass is just an alias for the register
there's no need to bundle it. This file should probably just move back
to RN too.
2018-04-09 20:05:57 -07:00
Sebastian Markbåge 6031bea239
Add Experimental Fabric Renderer (#12069) 2018-01-22 09:58:35 -08:00
Sam Goldman d906de7f60 Use `declare module.exports` syntax for flow libdefs (#11861)
We added this to Flow in v0.25 (about 2 years ago), but never actually
deprecated the legacy `declare var exports` syntax. Hoping to do that
soon, so clearing up uses that I can find.

Test Plan: flow
2017-12-15 12:17:46 +00:00
Jack Hou e8e62ebb59 use different eslint config for es6 and es5 (#11794)
* use different eslint config for es6 and es5

* remove confusing eslint/baseConfig.js & add more eslint setting for es5, es6

* more clear way to run eslint on es5 & es6 file

* seperate ESNext, ES6, ES6 path, and use different lint config

* rename eslint config file & update eslint rules

* Undo yarn.lock changes

* Rename a file

* Remove unnecessary exceptions

* Refactor a little bit

* Refactor and tweak the logic

* Minor issues
2017-12-11 15:52:46 +00:00
Dan Abramov 21d0c11523
Convert the Source to ES Modules (#11389)
* Update transforms to handle ES modules

* Update Jest to handle ES modules

* Convert react package to ES modules

* Convert react-art package to ES Modules

* Convert react-call-return package to ES Modules

* Convert react-test-renderer package to ES Modules

* Convert react-cs-renderer package to ES Modules

* Convert react-rt-renderer package to ES Modules

* Convert react-noop-renderer package to ES Modules

* Convert react-dom/server to ES modules

* Convert react-dom/{client,events,test-utils} to ES modules

* Convert react-dom/shared to ES modules

* Convert react-native-renderer to ES modules

* Convert react-reconciler to ES modules

* Convert events to ES modules

* Convert shared to ES modules

* Remove CommonJS support from transforms

* Move ReactDOMFB entry point code into react-dom/src

This is clearer because we can use ES imports in it.

* Fix Rollup shim configuration to work with ESM

* Fix incorrect comment

* Exclude external imports without side effects

* Fix ReactDOM FB build

* Remove TODOs I don’t intend to fix yet
2017-11-02 19:50:03 +00:00
Sebastian Markbåge 696908f496
[CS] Implement Some Stuff (#11390)
* Implement CS first take

This is using a pure JS API. This should probably switch to native hooks
at some later point but I'll start ironing out issues at this level first.

* Use async scheduling by default

The scheduled callback gets called immediately in render with infinite
time for now. Later this will be per root and abortable.

* Fix up the type signature of the ReactNativeCSType export

* Add escape hatch for special cased children

Working around the fact that we can't map arbitrary children slots. Just
the "children" prop.

* Readd providesModule for ReactNativeCSTypes

* Fix lint

* Fix ReactNativeTypes providesModule and CI check

* Special case a parent instance that doesn't have a props object

CSCustom can be anything here. Ugly but whatevs.

* Don't forget to store stateUpdater so that we can trigger updates

* Fix test
2017-10-27 20:05:34 -07:00
Dan Abramov 1ef250d881 Move Flow environment into scripts/flow (#11249)
* Move flow environment into scripts/flow

* Run Prettier
2017-10-17 14:20:00 +01:00