Commit Graph

10966 Commits

Author SHA1 Message Date
Sunil Pai
381d292d8d Merge branch 'master' into renderer-specific-act-warning 2019-05-17 15:07:09 +01:00
Dominic Gannaway
1160b37691
Event API: Add responder allowMultipleHostChildren flag (#15646) 2019-05-16 19:03:38 +01:00
Dominic Gannaway
95e06ac3d0
Event API: isTargetWithinEventResponderScope on unmounted event components (#15672) 2019-05-16 18:59:59 +01:00
Sunil Pai
d278a3ff8b
act() - s / flushPassiveEffects / Scheduler.unstable_flushWithoutYielding (#15591)
* s/flushPassiveEffects/unstable_flushWithoutYielding

a first crack at flushing the scheduler manually from inside act(). uses unstable_flushWithoutYielding(). The tests that changed, mostly replaced toFlushAndYield(...) with toHaveYielded(). For some tests that tested the state of the tree before flushing effects (but still after updates), I replaced act() with bacthedUpdates().

* ugh lint

* pass build, flushPassiveEffects returns nothing now

* pass test-fire

* flush all work (not just effects), add a compatibility mode

of note, unstable_flushWithoutYielding now returns a boolean much like flushPassiveEffects

* umd build for scheduler/unstable_mock, pass the fixture with it

* add a comment to Shcduler.umd.js for why we're exporting unstable_flushWithoutYielding

* run testsutilsact tests in both sync/concurrent modes

* augh lint

* use a feature flag for the missing mock scheduler warning

I also tried writing a test for it, but couldn't get the scheduler to unmock. included the failing test.

* Update ReactTestUtilsAct-test.js

- pass the mock scheduler warning test,
- rewrite some tests to use Scheduler.yieldValue
- structure concurrent/legacy suites neatly

* pass failing tests in batchedmode-test

* fix pretty/lint/import errors

* pass test-build

* nit: pull .create(null) out of the act() call
2019-05-16 17:12:36 +01:00
Dominic Gannaway
aad5a264d2
Event API: ensure calculateResponderRegion accounts for page offset (#15671) 2019-05-16 17:09:41 +01:00
Dan Abramov
bb89b4eacc
Bail out of updates in offscreen trees (#15666)
* Bail out of updates in offscreen trees

* Address review
2019-05-16 11:12:05 +01:00
Andrew Cherniavskii
4bf88ddeca Fix <embed> not triggering onLoad (#15614) 2019-05-16 11:05:20 +02:00
Andrew Clark
f961050a37 Always flushPassiveEffects before rendering
I  mistakenly wrapped this in the revertPassiveEffectsChange feature
flag. It should flush regardless of the flag.
2019-05-15 18:13:05 -07:00
Andrew Clark
b899819e77
Use dynamic flag in test renderer in www (#15662)
Uses a dynamic flag in www's test renderer build so we can condtionally
disable the passive effects bugfix. Matches the dynamic flag used in
the www React DOM build.
2019-05-15 14:55:50 -07:00
Andrew Clark
d34b457ce2
Feature flag to revert #15650 (#15659)
PR #15650 is a bugfix but it's technically a semantic change that could
cause regressions. I don't think it will be an issue, since the
previous behavior was both broken and incoherent, but out of an
abundance of caution, let's wrap it in a flag so we can easily revert
it if necessary.
2019-05-15 13:38:06 -07:00
Andrew Clark
668fbd651b
Fix serial passive effects (#15650)
* Failing test for false positive warning

* Flush passive effects before discrete events

Currently, we check for pending passive effects inside the `setState`
method before we add additional updates to the queue, in case those
pending effects also add things to the queue.

However, the `setState` method is too late, because the event that
caused the update might not have ever fired had the passive effects
flushed before we got there.

This is the same as the discrete/serial events problem. When a serial
update comes in, and there's already a pending serial update, we have to
do it before we call the user-provided event handlers. Because the event
handlers themselves might change as a result of the pending update.

This commit moves the `flushPassiveEffects` call to before the discrete
event handlers are called, and removes it from the `setState` method.
Non-discrete events will not cause passive effects to flush, which is
fine, since by definition they are not order dependent.
2019-05-14 18:08:10 -07:00
Dominic Gannaway
b0657fde6a
Event API: ensure getFocusableElementsInScope handles suspended trees (#15651) 2019-05-15 01:08:30 +01:00
Sebastian Markbåge
8af90c8972
Add test for nested avoided boundaries (#15636)
* Add test for nested avoided boundaries

* Add test for top level avoided boundaries
2019-05-14 14:41:45 -07:00
Dominic Gannaway
af19e2eb2f
Event API: adds pointerType to Focus events (#15645) 2019-05-14 15:59:36 +01:00
Andrew Clark
cc24d0ea56
Invariant that throws when committing wrong tree (#15517)
If React finishes rendering a tree, delays committing it (e.g.
Suspense), then subsequently starts over or renders a new tree, the
pending tree is no longer valid. That's because rendering a new work-in
progress mutates the old one in place.

The current structure of the work loop makes this hard to reason about
because, although `renderRoot` and `commitRoot` are separate functions,
they can't be interleaved. If they are interleaved by accident, it
either results in inconsistent render output or invariant violations
that are hard to debug.

This commit adds an invariant that throws if the new tree is the same as
the old one. This won't prevent all bugs of this class, but it should
catch the most common kind.

To implement the invariant, I store the finished tree on a field on the
root. We already had a field for this, but it was only being used for
the unstable `createBatch` feature.

A more rigorous way to address this type of problem could be to unify
`renderRoot` and `commitRoot` into a single function, so that it's
harder to accidentally interleave the two phases. I plan to do something
like this in a follow-up.
2019-05-13 16:15:50 -07:00
Andrew Clark
83fc258f29
Remove <ConcurrentMode /> (#15532)
Use createSyncRoot instead.
2019-05-13 16:10:00 -07:00
Andrew Clark
283ce53204
Add ReactDOM.unstable_createSyncRoot (#15504)
* Add ReactDOM.unstable_createSyncRoot

- `ReactDOM.unstable_createRoot` creates a Concurrent Mode root.
- `ReactDOM.unstable_createSyncRoot` creates a Batched Mode root. It
does not support `createBatch`.
- `ReactDOM.render` creates a Legacy Mode root. It will eventually be
deprecated and possibly moved to a separate entry point, like
`react-dom/legacy`.

* Rename internal ReactRoot types
2019-05-13 15:30:03 -07:00
Andrew Clark
862f499fac
Add Batched Mode (#15502)
* Add Batched Mode

React has an unfortunate quirk where updates are sometimes synchronous
-- where React starts rendering immediately within the call stack of
`setState` — and sometimes batched, where updates are flushed at the
end of the current event. Any update that originates within the call
stack of the React event system is batched. This encompasses most
updates, since most updates originate from an event handler like
`onClick` or `onChange`. It also includes updates triggered by lifecycle
methods or effects. But there are also updates that originate outside
React's event system, like timer events, network events, and microtasks
(promise resolution handlers). These are not batched, which results in
both worse performance (multiple render passes instead of single one)
and confusing semantics.

Ideally all updates would be batched by default. Unfortunately, it's
easy for components to accidentally rely on this behavior, so changing
it could break existing apps in subtle ways.

One way to move to a batched-by-default model is to opt into Concurrent
Mode (still experimental). But Concurrent Mode introduces additional
semantic changes that apps may not be ready to adopt.

This commit introduces an additional mode called Batched Mode. Batched
Mode enables a batched-by-default model that defers all updates to the
next React event. Once it begins rendering, React will not yield to
the browser until the entire render is finished.

Batched Mode is superset of Strict Mode. It fires all the same warnings.
It also drops the forked Suspense behavior used by Legacy Mode, in favor
of the proper semantics used by Concurrent Mode.

I have not added any public APIs that expose the new mode yet. I'll do
that in subsequent commits.

* Suspense in Batched Mode

Should have same semantics as Concurrent Mode.

* Use RootTag field to configure type of root

There are three types of roots: Legacy, Batched, and Concurrent.

* flushSync should not flush batched work

Treat Sync and Batched expiration times separately. Only Sync updates
are pushed to our internal queue of synchronous callbacks.

Renamed `flushImmediateQueue` to `flushSyncCallbackQueue` for clarity.
2019-05-13 14:30:39 -07:00
Dominic Gannaway
fec74f99da
Event API: ensure preventDefault works for nested targets (#15633) 2019-05-13 13:45:48 +01:00
Andrew Clark
edfedf3ae9
Fork ReactSharedInternals for UMD builds (#15617) 2019-05-10 13:51:39 -07:00
Andrew Clark
39ef609e7c Update test to fix CI 2019-05-10 11:12:24 -07:00
Andrew Clark
5b6eb55e1c
Remove scheduler from React package dependencies (#15616)
Scheduler is used by the renderers, but not the isomorphic package.
2019-05-10 11:01:04 -07:00
Sebastian Markbåge
0803d22479 Don't consider "Never" expiration as part of most recent event time (#15606)
* Don't consider "Never" expiration as part of most recent event time

This doesn't happen with deprioritization since those are not "updates"
by themselves so they don't go into this accounting.

However, they are real updates if they were scheduled as Idle pri using
the scheduler explicitly. It's unclear what suspense should do for these
updates. For offscreen work, we probably want them to commit immediately.
No point in delay them since they're offscreen anyway. However if this is
an explicit but very low priority update that might not make sense.
So maybe this means that these should have different expiration times?

In this PR I just set the suspense to the lowest JND.

However, we don't want is for these things to commit earlier in case
they got batched in with other work so I also ensured that they're not
accounted for in in the workInProgressRootMostRecentEventTime calculation
at all. This makes them commit immediately if they're by themselves, or
after the JND of whatever they were batched in with.

Ultimately, I think that we should probably never schedule anything at
Never that isn't truly offscreen so this should never happen.

However, that begs the question what happens with very low pri work that
suspends. Do we always work at that level first?

* Adjust test to account for the new shorter suspense time
2019-05-10 10:53:20 -07:00
Dominic Gannaway
90f54d77f3
Event API: add follow up event unwind test (#15612) 2019-05-10 13:36:54 +01:00
Dominic Gannaway
91a044e31f
Event API: add key modifiers to Press events (#15611) 2019-05-10 13:32:11 +01:00
Dominic Gannaway
3d8b836e22
Event API: ensure we pop context for event system fibers (#15599) 2019-05-09 17:01:18 +01:00
Dominic Gannaway
e33e32db04
Event API: normalize event timeStamp property to be in event system (#15598) 2019-05-09 16:05:25 +01:00
Dominic Gannaway
3669b90101
Event API: add more warnings for responder based events (#15597) 2019-05-09 15:31:18 +01:00
Dominic Gannaway
05d08500b2
Experimental Event API: Press event properties (#15586) 2019-05-08 20:29:03 +01:00
Dominic Gannaway
51e66cf9fa
Experimental Event API: reduce code size of event modules (#15590) 2019-05-08 19:09:32 +01:00
Dominic Gannaway
8abf243b86
Ensure touch events are properly handled for pageX and pageY (#15587) 2019-05-08 19:08:15 +01:00
Sebastian Markbåge
c7398f3396
Add Suspense Boundary Context (and unstable_avoidThisFallback) (#15578)
* Avoidable suspense boundaries

* Move the context out of SuspenseComponent

* Use setDefaultShallowSuspenseContext instead of passing 0
2019-05-07 18:08:05 -07:00
Andrew Clark
f9e60c8a19
Warn when suspending at wrong priority (#15492)
* Warn when suspending at wrong priority

Adds a warning when a user-blocking update is suspended.

Ideally, all we would need to do is check the current priority level.
But we currently have no rigorous way to distinguish work that was
scheduled at user- blocking priority from work that expired a bit and
was "upgraded" to a higher priority. That's because we don't schedule
separate callbacks for every level, only the highest priority level per
root. The priority of subsequent levels is inferred from the expiration
time, but this is an imprecise heuristic.

However, we do store the last discrete pending update per root. So we
can reliably compare to that one. (If we broaden this warning to include
high pri updates that aren't discrete, then this won't be sufficient.)

My rationale is that it's better for this warning to have false
negatives than false positives.

Potential follow-ups:
- Bikeshed more on the message. I don't like what I landed on that much
but I think it's good enough to start.
- Include the names of the components that updated. (The ideal place to
fire the warning is during the setState call but we don't know if
something will suspend until the next update. Maybe we could be clever
and warn during a subsequent update to the same component?)

* Move Suspense priority check to throwException
2019-05-07 16:50:04 -07:00
Nicolas Gallagher
89d8d1435f
Add React.unstable_createEventComponent (#15580)
API for creating event components from event responders.
2019-05-07 12:36:42 -07:00
Brian Vaughn
6da04b5d88
Fix interaction tracing for batched update mounts (#15567)
* Added failing test for act+interaction tracing
* Mark pending interactions on root for legacy unbatched phase
2019-05-06 12:59:48 -07:00
Dominic Gannaway
d38cfd452f
Ensure TouchHitTarget element is server side rendered with hit slop (#15385)
* Follow up to 15381

* Add back in hit slop properties

* Prettier

* Fix lint

* move hydration update out of DEV block

* Remove pointer-events:auto
2019-05-06 20:13:23 +01:00
Nicolas Gallagher
2e5d1a8b9e
React Events: fix cancel events for Press (#15563)
* Fixes a bug in the cancellation logic. The cancel events are now correctly listened to on the root.
* Fixes cancellation in Safari by using the dragstart event as a proxy for cancellation (i.e., the event dispatched when move-during-press occurs on an anchor tag)
2019-05-03 15:33:21 -07:00
Nicolas Gallagher
307e0a7d7d
React Events: cancel onLongPress for large enough moves (#15562)
Implements the behaviour from React Native's Pressability.
2019-05-03 12:59:55 -07:00
Dominic Gannaway
339366c461
Event API: Support press reentry for pointer events (#15560) 2019-05-03 18:32:50 +01:00
Dominic Gannaway
ec6691a687
Event API: remove isTargetDirectlyWithinEventComponent (#15546) 2019-04-30 17:38:48 +01:00
Dominic Gannaway
a6e30001fb
Delete duplicate Focus.js (#15540)
This file was renamed to the lower case version, but as Mac filesystems are typically case insensitive, it was never removed.
2019-04-30 12:20:44 +01:00
Dominic Gannaway
f7993d5477
Delete duplicate Hover.js (#15539)
This file was renamed to the lower case version, but as Mac filesystems are typically case insensitive, it was never removed.
2019-04-30 12:13:07 +01:00
Dominic Gannaway
c8ee10037a
Delete duplicate Swipe.js (#15541)
This file was renamed to the lower case version, but as Mac filesystems are typically case insensitive, it was never removed.
2019-04-30 12:11:26 +01:00
Dominic Gannaway
494716c9b4
Delete duplicate Drag.js (#15537)
This file was renamed to the lower case version, but as Mac filesystems are typically case insensitive, it was never removed.
2019-04-30 12:07:24 +01:00
Dominic Gannaway
377846fef8
Delete duplicate Press.js (#15538)
This file was renamed to the lower case version, but as Mac filesystems are typically case insensitive, it was never removed.
2019-04-30 12:06:44 +01:00
Dominic Gannaway
379515e83e
Follow up to 15535 (#15536) 2019-04-30 12:04:19 +01:00
Dominic Gannaway
bd88982fbf
Event API: use capture for all event listeners using experimental responder system (#15526) 2019-04-30 11:40:45 +01:00
Andrew Clark
72ca3c60e7
Bump scheduler version to 0.14.0 (#15395) 2019-04-29 18:10:11 -07:00
Andrew Clark
7882c41f60
Use lowercase entry points for event modules (#15535)
Matches npm convention
2019-04-29 16:25:56 -07:00
Nathan Schloss
43c4e5f348 Add method for forcing a lower framerate 2019-04-29 15:51:58 -07:00