Commit Graph

49 Commits

Author SHA1 Message Date
Laura buns b43eec7eaa Replace `wrap-warning-with-env-check` with an eslint plugin (#17540)
* Replace Babel plugin with an ESLint plugin

* Fix ESLint rule violations

* Move shared conditions higher

* Test formatting nits

* Tweak ESLint rule

* Bugfix: inside else branch, 'if' tests are not satisfactory

* Use a stricter check for exactly if (__DEV__)

This makes it easier to see what's going on and matches dominant style in the codebase.

* Fix remaining files after stricter check
2019-12-06 18:25:54 +00:00
Dominic Gannaway a61886b16b
[react-interactions] Refine custom active element blur logic (#17354) 2019-11-13 20:46:00 +00:00
Dominic Gannaway b71ab61c8f
[react-interactions] Adds more experimental Scope API methods (#17042) 2019-10-08 19:32:53 +02:00
Eli White db8afe4f63
Add HostComponent type to ReactNative (#16898)
* Add HostComponent type to ReactNative

* Use type alias imports instead of wildcard

* Fix forgotten Object in measureLayout type
2019-09-26 14:42:18 -07:00
Dominic Gannaway fc80772078
[react-events] Ensure updateEventListeners updates in commit phase (#16540) 2019-08-22 23:58:16 +01:00
Dominic Gannaway 5098891193
[Flare] Redesign core event system (#16163) 2019-07-23 23:46:44 +01:00
Dominic Gannaway 2c4d61e102
Adds experimental fundamental interface (#16049) 2019-07-19 22:20:28 +01:00
Dominic Gannaway 67e3f3fb6e
[Flare] Revise responder event types (#16081) 2019-07-08 14:35:59 +01:00
Dominic Gannaway c64f40d718
[Flare] Remove dead event target code (#16063) 2019-07-04 13:10:55 +01:00
Sunil Pai a457e02ae3
allow nested `act()`s from different renderers (#16039)
* allow nested `act()`s from different renderers

There are usecases where multiple renderers need to oprate inside an act() scope
- ReactDOM.render being used inside another component tree. The parent component will be rendered using ReactTestRenderer.create for a snapshot test or something.
- a ReactDOM instance interacting with a ReactTestRenderer instance (like for the new devtools)

This PR changes the way the acting sigils operate to allow for this. It keeps 2 booleans, one attached to React, one attached to the renderer. act() changes these values, and the workloop reads them to decide what warning to trigger.

I also renamed shouldWarnUnactedUpdates to warnsIfNotActing

* s/ReactIsActing/IsSomeRendererActing and s/ReactRendererIsActing/IsThisRendererActing
2019-07-02 22:20:17 +01:00
Dominic Gannaway eb2ace1281
[Flare] Bring Flare support to React Native Fabric (#15887) 2019-06-28 01:22:32 +01:00
Dominic Gannaway 8b88ac2592
[Flare] Remove event targets including TouchHitTarget (#16011) 2019-06-27 23:58:48 +01:00
Sunil Pai fce15f14d3
don't fire missing act() warnings for react-art (#15975)
* use toWarnDev for dom fixture tests

forks toWarnDev from root into fixture/dom, updates tes tests to use it

* disable act() warnings for react-art()

- For 'secondary' renderers like react-act, we don't want to fire missing act() warnings; the wrapping renderer will fire warnings anyway, and when it flushes, it flushes effects *across* renderers.

- I could have used isPrimaryRenderer as the flag, but this is marked as false for react-test-renderer, and we *do* want the warning to fire for it. Hence a new flag.

* add missing dependency `art` to fixtures/dom
2019-06-24 19:18:26 +01:00
Dominic Gannaway 34ce57ae75
[Flare] Refine flow type annotations (#15950) 2019-06-21 12:32:43 +01:00
Dominic Gannaway 4a7a39b594
[Flare] Add RN build step for ReactTypes (#15926) 2019-06-19 13:27:10 +01:00
Dominic Gannaway 689beef6f5
[Flare] Move unstable_createEventComponent to ReactDOM (#15890) 2019-06-18 23:41:00 +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
Adam Comella a187e9b5e4 React Native: Allow Views to be nested inside of Text (#15464)
This feature is now supported on both iOS and Android. The Android feature was merged a couple of weeks ago: https://github.com/facebook/react-native/pull/23195.
2019-04-25 12:06:39 +01: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
Dominic Gannaway aece8119cf
Refactor EventComponent logic + add onOwnershipChange callback (#15354) 2019-04-09 12:47:32 +01:00
Dominic Gannaway 4064ea9fa6
Experimental event API: Support EventComponent onUnmount responder callback (#15335) 2019-04-06 08:16:57 +01:00
Dominic Gannaway 4fbbae8afa
Add full TouchHitTarget hit slop (experimental event API) to ReactDOM (#15308) 2019-04-06 07:51:21 +01:00
Dominic Gannaway 6a1e6b2f78
Experimental event API: loosen EventTarget constraints and warnings (#15292)
* Remove warning for event targets being direct children of event component

* Addressed feedback and added more test coverage + warnings
2019-04-02 19:49:28 +01:00
Eli White 2e02469fa2
ReactNative's ref.measureLayout now takes a ref (#15126)
* ReactNative's ref.measureLayout now takes a ref

* Use Object as the additional param type

* Remove unnecessary whitespace

* Not supporting ref in mixin or subclass
2019-03-29 15:57:06 -07:00
Eli White 1b94fd215d Make setNativeProps a no-op with Fabric renderer (#15094)
* Make setNativeProps a no-op with Fabric renderer

* Remove unnecessary __DEV__ check
2019-03-29 15:44:15 -07:00
Dominic Gannaway b83e01cade
Adds more scaffolding for experimental event API (#15112)
* Adds more scaffolding for experimental event API
2019-03-20 11:20:17 +00:00
Dominic Gannaway 0c03a47436
Adds experimental event API scaffolding (#15108)
* Adds experimental event API scaffolding
2019-03-14 17:02:42 +00:00
Andrew Clark bc8bd24c14
Run persistent mode tests in CI (#15029)
* Add command to run tests in persistent mode

* Convert Suspense fuzz tester to use noop renderer

So we can run it in persistent mode, too.

* Don't mutate stateNode in appendAllChildren

We can't mutate the stateNode in appendAllChildren because the children
could be current.

This is a bit weird because now the child that we append is different
from the one on the fiber stateNode. I think this makes conceptual
sense, but I suspect this likely breaks an assumption in Fabric.

With this approach, we no longer need to clone to unhide the children,
so I removed those host config methods.

Fixes bug surfaced by fuzz tester. (The test case that failed was the
one that's already hard coded.)

* In persistent mode, disable test that reads a ref

Refs behave differently in persistent mode. I added a TODO to write
a persistent mode version of this test.

* Run persistent mode tests in CI

* test-persistent should skip files without noop

If a file doesn't reference react-noop-renderer, we shouldn't bother
running it in persistent mode, since the results will be identical to
the normal test run.

* Remove module constructor from placeholder tests

We don't need this now that we have the ability to run any test file in
either mutation or persistent mode.

* Revert "test-persistent should skip files without noop"

Seb objected to adding shelljs as a dep and I'm too lazy to worry about
Windows support so whatever I'll just revert this.

* Delete duplicate file
2019-03-11 10:56:34 -07:00
Andrew Clark 3f4852fa5f
Run Placeholder tests in persistent mode, too (#15013)
* Convert ReactSuspensePlaceholder tests to use noop

Instead of the test renderer, since test renderer does not support
running in persistent mode.

* Run Placeholder tests in persistent mode, too

* Fix Flow and lint

* Hidden text instances should have correct host context

Adds a test for a subtle edge case that only occurs in persistent mode.

* createHiddenTextInstance -> cloneHiddenTextInstance

This sidesteps the problem where createHiddenTextInstance needs access
to the host context.
2019-03-08 18:53:14 -08:00
Andrew Clark 1e3b6192b5
Import Scheduler directly, not via host config (#14984)
* Import Scheduler directly, not via host config

We currently schedule asynchronous tasks via the host config. (The host
config is a static/build-time dependency injection system that varies
across different renderers — DOM, native, test, and so on.) Instead of
calling platform APIs like `requestIdleCallback` directly, each renderer
implements a method called `scheduleDeferredCallback`.

We've since discovered that when scheduling tasks, it's crucial that
React work is placed in the same queue as other, non-React work on the
main thread. Otherwise, you easily end up in a starvation scenario where
rendering is constantly interrupted by less important tasks. You need a
centralized coordinator that is used both by React and by other
frameworks and application code. This coordinator must also have a
consistent API across all the different host environments, for
convention's sake and so product code is portable — e.g. so the same
component can work in both React Native and React Native Web.

This turned into the Scheduler package. We will have different builds of
Scheduler for each of our target platforms. With this approach, we treat
Scheduler like a built-in platform primitive that exists wherever React
is supported.

Now that we have this consistent interface, the indirection of the host
config no longer makes sense for the purpose of scheduling tasks. In
fact, we explicitly do not want renderers to scheduled task via any
system except the Scheduler package.

So, this PR removes `scheduleDeferredCallback` and its associated
methods from the host config in favor of directly importing Scheduler.

* Missed an extraneous export
2019-03-06 14:41:45 -08:00
Eli White 870214f37a
Deprecate ref.setNativeProps in favor of ReactNative.setNativeProps (#14912)
* Deprecate ref.setNativeProps in favor of ReactNative.setNativeProps

* Using a feature flag for the setNativeProps warning

* Removing extra line breaks

* Set the FB native feature flag to true

* Prettier
2019-02-25 15:00:39 -08:00
Andrew Clark fb3f7bfde9
Avoid importing Scheduler directly (#14757)
* Avoid importing Scheduler directly

The reconciler should not depend directly on Scheduler. This adds it to
the host config for the renderer instead.

(Except for `scheduler/tracing` imports, which are used only by the
profiling build. I've left those imports as-is, though I'm open to
directing those through the host config, too.)

* Make throwaway root id longer to appease Brian
2019-02-05 03:21:25 -08:00
Sebastian Markbåge c954efa70f
Remove `import * as` pattern from the codebase (#14282)
Whenever we do this, Rollup needs to materialize this as an object.
This causes it to also add the Babel compatibility property which is
unnecessary bloat. However, since when we use these, we leak the object
this often also deopts any compiler optimizations.

If we really need an object we should export default an object.

Currently there is an exception for DOMTopLevelEventTypes since
listing out the imports is a PITA and it doesn't escape so it should
get properly inlined. We should probably move to a different pattern
to avoid this for consistency though.
2018-11-19 15:32:54 -08:00
Sophie Alpert 9d47143e85
Implement {,un}hideInstance on RN renderer (#14115)
This is required to use lazy.

Test Plan:
* Verified lazy works on a real world use case (shows spinner, shows real content).
* Verified that if I change the primary content's styles to have `display: 'none'` then it never appears (i.e., the code in `unhide` reads the styles successfully)
2018-11-05 15:33:25 -08:00
Andrew Clark 8c67bbf183
[scheduler] Deadline object -> shouldYield (#14025)
* [scheduler] Deadline object -> shouldYield

Instead of using a requestIdleCallback-style deadline object, expose a
method Scheduler.shouldYield that returns true if there's a higher
priority event in the queue.

* Nits
2018-10-30 13:47:51 -07:00
Andrew Clark dac9202a9c
Hide timed-out children instead of deleting them so their state is preserved (#13823)
* Store the start time on `updateQueue` instead of `stateNode`

Originally I did this to free the `stateNode` field to store a second
set of children. I don't we'll need this anymore, since we use fragment
fibers instead. But I still think using `updateQueue` makes more sense
so I'll leave this in.

* Use fragment fibers to keep the primary and fallback children separate

If the children timeout, we switch to showing the fallback children in
place of the "primary" children. However, we don't want to delete the
primary children because then their state will be lost (both the React
state and the host state, e.g. uncontrolled form inputs). Instead we
keep them mounted and hide them. Both the fallback children AND the
primary children are rendered at the same time. Once the primary
children are un-suspended, we can delete the fallback children — don't
need to preserve their state.

The two sets of children are siblings in the host environment, but
semantically, for purposes of reconciliation, they are two separate
sets. So we store them using two fragment fibers.

However, we want to avoid allocating extra fibers for every placeholder.
They're only necessary when the children time out, because that's the
only time when both sets are mounted.

So, the extra fragment fibers are only used if the children time out.
Otherwise, we render the primary children directly. This requires some
custom reconciliation logic to preserve the state of the primary
children. It's essentially a very basic form of re-parenting.

* Use `memoizedState` to store various pieces of SuspenseComponent's state

SuspenseComponent has three pieces of state:

- alreadyCaptured: Whether a component in the child subtree already
suspended. If true, subsequent suspends should bubble up to the
next boundary.
- didTimeout: Whether the boundary renders the primary or fallback
children. This is separate from `alreadyCaptured` because outside of
strict mode, when a boundary times out, the first commit renders the
primary children in an incomplete state, then performs a second commit
to switch the fallback. In that first commit, `alreadyCaptured` is
false and `didTimeout` is true.
- timedOutAt: The time at which the boundary timed out. This is separate
from `didTimeout` because it's not set unless the boundary
actually commits.


These were previously spread across several fields.

This happens to make the non-strict case a bit less hacky; the logic for
that special case is now mostly localized to the UnwindWork module.

* Hide timed-out Suspense children

When a subtree takes too long to load, we swap its contents out for
a fallback to unblock the rest of the tree. Because we don't want
to lose the state of the timed out view, we shouldn't actually delete
the nodes from the tree. Instead, we'll keep them mounted and hide
them visually. When the subtree is unblocked, we un-hide it, having
preserved the existing state.

Adds additional host config methods. For mutation mode:

- hideInstance
- hideTextInstance
- unhideInstance
- unhideTextInstance

For persistent mode:

- cloneHiddenInstance
- cloneUnhiddenInstance
- createHiddenTextInstance

I've only implemented the new methods in the noop and test renderers.
I'll implement them in the other renderers in subsequent commits.

* Include `hidden` prop in noop renderer's output

This will be used in subsequent commits to test that timed-out children
are properly hidden.

Also adds getChildrenAsJSX() method as an alternative to using
getChildren(). (Ideally all our tests would use test renderer #oneday.)

* Implement hide/unhide host config methods for DOM renderer

For DOM nodes, we hide using `el.style.display = 'none'`.

Text nodes don't have style, so we hide using `text.textContent = ''`.

* Implement hide/unhide host config methods for Art renderer

* Create DOM fixture that tests state preservation of timed out content

* Account for class components that suspend outside concurrent mode

Need to distinguish mount from update. An unfortunate edge case :(

* Fork appendAllChildren between persistent and mutation mode

* Remove redundant check for existence of el.style

* Schedule placement effect on indeterminate components

In non-concurrent mode, indeterminate fibers may commit in an
inconsistent state. But when they update, we should throw out the
old fiber and start fresh. Which means the new fiber needs a
placement effect.

* Pass null instead of current everywhere in mountIndeterminateComponent
2018-10-18 15:37:16 -07:00
Brian Ng 970a34baed Bump babel-eslint and remove flow supressions (#13727) 2018-09-25 22:48:31 +01:00
Dan Abramov 144328fe81
Enable no-use-before-define rule (#13606) 2018-09-10 16:15:18 +01: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
Dan Abramov b3d8c5376f
[RN] Remove isMounted() false positive warning (#13511) 2018-08-30 18:42:09 +01:00
Timothy Yung d2123d6569
Sync React Native Flow Changes (#13513) 2018-08-29 13:54:58 -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
Andrew Clark aa8266c4f7
Prepare placeholders before timing out (#13092)
* Prepare placeholders before timing out

While a tree is suspended, prepare for the timeout by pre-rendering the
placeholder state.

This simplifies the implementation a bit because every render now
results in a completed tree.

* Suspend inside an already timed out Placeholder

A component should be able to suspend inside an already timed out
placeholder. The time at which the placeholder committed is used as 
the start time for a subsequent suspend.

So, if a placeholder times out after 3 seconds, and an inner
placeholder has a threshold of 2 seconds, the inner placeholder will
not time out until 5 seconds total have elapsed.
2018-07-03 19:22:41 -07:00
Dan Abramov aeda7b745d
Remove fbjs dependency (#13069)
* Inline fbjs/lib/invariant

* Inline fbjs/lib/warning

* Remove remaining usage of fbjs in packages/*.js

* Fix lint

* Remove fbjs from dependencies

* Protect against accidental fbjs imports

* Fix broken test mocks

* Allow transitive deps on fbjs/ for UMD bundles

* Remove fbjs from release script
2018-06-19 16:03:45 +01:00
Sebastian Markbåge 051637da61
Extract Fabric event handlers from canonical props (#13024)
We need a different "component tree" thingy for Fabric.

A lot of this doesn't really make much sense in a persistent world but
currently we can't dispatch events to memoizedProps on a Fiber since
they're pooled. Also, it's unclear what the semantics should be when we
dispatch an event that happened when the old props were in effect but now
we have new props already.

This implementation tries to use the last committed props but also fails
at that because we don't have a commit hook in the persistent mode.

However, at least it doesn't crash when dispatching. :)
2018-06-13 16:20:48 -07:00
Dan Abramov 47b003a828
Resolve host configs at build time (#12792)
* Extract base Jest config

This makes it easier to change the source config without affecting the build test config.

* Statically import the host config

This changes react-reconciler to import HostConfig instead of getting it through a function argument.

Rather than start with packages like ReactDOM that want to inline it, I started with React Noop and ensured that *custom* renderers using react-reconciler package still work. To do this, I'm making HostConfig module in the reconciler look at a global variable by default (which, in case of the react-reconciler npm package, ends up being the host config argument in the top-level scope).

This is still very broken.

* Add scaffolding for importing an inlined renderer

* Fix the build

* ES exports for renderer methods

* ES modules for host configs

* Remove closures from the reconciler

* Check each renderer's config with Flow

* Fix uncovered Flow issue

We know nextHydratableInstance doesn't get mutated inside this function, but Flow doesn't so it thinks it may be null.
Help Flow.

* Prettier

* Get rid of enable*Reconciler flags

They are not as useful anymore because for almost all cases (except third party renderers) we *know* whether it supports mutation or persistence.

This refactoring means react-reconciler and react-reconciler/persistent third-party packages now ship the same thing.
Not ideal, but this seems worth how simpler the code becomes. We can later look into addressing it by having a single toggle instead.

* Prettier again

* Fix Flow config creation issue

* Fix imprecise Flow typing

* Revert accidental changes
2018-05-19 11:29:11 +01: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
Dan Abramov 45b90d4866
Move renderer host configs into separate modules (#12791)
* Separate test renderer host config

* Separate ART renderer host config

* Separate ReactDOM host config

* Extract RN Fabric host config

* Extract RN host config
2018-05-15 01:12:28 +01:00