Compare commits

..

1406 Commits

Author SHA1 Message Date
Laura González
cbc344e8e7 Update ReactShallowRenderer.js 2019-12-06 16:18:09 +00:00
Laura González
e3b59c14ba comments 2019-12-06 15:46:43 +00:00
Laura González
341faaf4e3 fire away 2019-12-06 15:25:07 +00:00
Laura González
48b03f3774 also wrap lowPriorityWarning 2019-12-06 14:15:26 +00:00
Laura González
416e258b3c rename wrap-warning-with-env-check 2019-12-06 13:33:59 +00:00
Laura González
1a9b639c2f Update wrap-warning-with-env-check.js 2019-12-05 18:00:06 +00:00
Laura González
a20f13e3cd Update wrap-warning-with-env-check-test.js 2019-12-05 17:58:48 +00:00
Laura González
b73cdc72df Update wrap-warning-with-env-check.js 2019-12-05 17:57:45 +00:00
Laura González
5ddb7a01c6 restore plugin 2019-12-05 17:56:30 +00:00
Laura González
fb0a374117 Nicer messages 2019-12-05 17:17:01 +00:00
Laura González
d84332c4f7 Revert "test this"
This reverts commit fafc2e1889.
2019-12-05 17:11:44 +00:00
Laura González
fafc2e1889 test this 2019-12-05 17:02:10 +00:00
Laura González
c791455637 support && 2019-12-05 16:38:40 +00:00
Laura González
38f5068684 tidy tests 2019-12-05 16:25:42 +00:00
Laura González
46e17a9700 Update no-production-logging.js 2019-12-05 14:51:43 +00:00
Laura González
3db8a02d28 try fixer 2019-12-05 14:05:02 +00:00
Laura González
07c28b59a8 prettier it all 2019-12-05 13:52:53 +00:00
Laura González
a2d7a0ca7a test for invariant 2019-12-05 13:45:26 +00:00
Laura González
d363805462 remobe babel plugin 2019-12-05 13:37:44 +00:00
Laura González
b1fc0040a9 plug plugin in 2019-12-05 13:34:21 +00:00
Laura González
d94f6972eb add rule over 2019-12-05 13:31:01 +00:00
Dominic Gannaway
acfe4b21b2 [react-interactions] Upgrade passive event listeners to active listeners (#17513) 2019-12-04 19:30:50 +00:00
Farhad Yasir
5235d193d7 fix: make serializable data in react-devtools (#17233)
* fix: make serializable data for bridge in react-devtools

* fix: add bigint data type in hydration

* refactor: remove console.log

* test: update unit tests for bigint in react-devtools
2019-12-04 15:53:00 +00:00
Sebastian Markbåge
5064c7f6aa Revert Rerender Error Check (#17519)
* Add failing test

* Revert "Move rerender error check to avoid global state"

This reverts commit 3e77742d8c4e64b89f816c0b1ce0bc156f8c5f61.
2019-12-03 23:10:36 -08:00
Dominic Gannaway
6d105ad3f6 [react-interactions] Move Flare event registration to commit phase (#17518) 2019-12-04 02:08:20 +00:00
Sebastian Markbåge
dc18b8b8d2 Don't group Idle/Offscreen work with other work (#17456)
When we suspend we always try a lower level but we shouldn't try offscreen.
2019-12-03 13:38:02 -08:00
Sebastian Markbåge
f523b2e0d3 Use fewer global variables in Hooks (#17480)
* We don't need the global state for this

* Move componentUpdateQueue and sideEffectTag out of global state

* Move firstWorkInProgressHook off global state

* Move remainingExpirationTime off global state

* Reset fiber to its current state if it throws

* Move rerender error check to avoid global state

This means that it's harder to find it since it's not in the dispatch
function's stack but we can add a DEV only one for that if we really
need it. Alternatively, we can check it in against the renderUpdates queue.

* Move next___Hook out of global state

* Assert that currentlyRenderingFiber is always set

When accessed, this should always be set. This could enforced by storing
this on the dispatcher for example.

* Add another test just to be safe
2019-12-03 12:51:36 -08:00
Sebastian Markbåge
d75323f65d Remove case that only exists for createBatch (#17506)
The comment says this is only needed for createBatch().commit() which
doesn't exist anymore.
2019-12-03 10:35:17 -08:00
Sebastian Markbåge
79572e34d1 Adjust SuspenseList CPU bound heuristic (#17455)
* Adjust SuspenseList CPU bound heuristic

In SuspenseList we switch to rendering fallbacks (or stop rendering further
rows in the case of tail="collapsed/hidden") if it takes more than 500ms
to render the list. The limit of 500ms is similar to the train model and
designed to be short enough to be in the not noticeable range.

This works well if each row is small because we time the 500ms range well.
However, if we have a few large rows then we're likely to exceed the limit
by a lot. E.g. two 480ms rows hits almost a second instead of 500ms.

This PR adjusts the heuristic to instead compute whether something has
expired based on the render time of the last row. I.e. if we think rendering
one more row would exceed the timeout, then we don't attempt.

This still works well for small rows and bails earlier for large rows.

The expiration is still based on the start of the list rather than the
start of the render. It should probably be based on the start of the render
but that's a bigger change and needs some thought.

* Comment
2019-12-02 17:53:08 -08:00
Sung M. Kim
b64938e123 Fixed changelog formatting #17481 (#17487) 2019-11-29 13:57:38 +00:00
Dan Abramov
969f4b5bb8 Change DevTools hook warning message (#17478) 2019-11-28 00:47:13 +00:00
Brian Vaughn
3816ae7c38 DevTools version bump 4.2.0 -> 4.2.1 2019-11-27 07:49:49 -08:00
Brian Vaughn
5fc97420b9 Remove dependency on local git checkout from build process (#17475)
* Remove dependency on local git checkout from build process

* Updated Webpack dependencies to account for recent changes to deps for Flight
2019-11-27 07:48:09 -08:00
Dan Abramov
6470e0f169 [Fresh] Make all errors recoverable (#17438)
* [Fresh] Detect root updates more reliably

* [Fresh] Use WeakMap for root elements

* [Fresh] Make initial failures recoverable too

* Fix DevTools check

* Fix wrong flow type
2019-11-25 17:25:34 +00:00
Andrew Clark
54f66731c8 Update release script URL (#17428)
CircleCI API endpoint changed
2019-11-21 13:19:03 -08:00
Dan Abramov
237a966da0 [Fresh] Fix an infinite loop in an edge case (#17414)
* [Fresh] Fix an infinite loop in an edge case

* Make it work in IE11
2019-11-21 14:10:26 +00:00
Dominic Gannaway
007a276b65 [react-interactions] Fix memory leak in event responder system (#17421) 2019-11-21 13:15:37 +00:00
Dominic Gannaway
3fdfa231ad [react-interactions] Refine virtual click detection for FF+JAWS/NVDA (#17422) 2019-11-21 13:09:30 +00:00
Dominic Gannaway
a7d07ff24d [react-interactions] Rename Flare listeners prop to DEPRECATED_flareListeners (#17394) 2019-11-18 13:32:50 +00:00
Sebastian Markbåge
3ad076472c Update Fixtures to use new APIs (#17380)
Also renamed unstable-async to concurrent
2019-11-17 14:42:47 -08:00
Andrew Clark
1f2da0babd Forgot to mark test as experimental (#17391) 2019-11-17 13:59:25 -08:00
David Garner
a807c307c4 [eslint] Check forwardRef callbacks (#17255)
* [eslint] Check forwardRef callbacks (#17220)

* [eslint] Make tests more realistic (#17220)

* [eslint] Check anonymous callback of React.memo for rules-of-hooks (#17220)

* [eslint] Add tests for callbacks not known to be components (#17220)

* [eslint] Correct comments and add another test (#17220)
2019-11-17 13:39:08 +00:00
Andrew Clark
2586303662 [Bugfix] Pending state is always user-blocking (#17382)
Fixes a bug where `isPending` is only set to `true` if `startTransition`
is called from inside an input event. That's usually the case, but
not always.

Now it works regardless of where you call it.
2019-11-15 15:46:09 -08:00
Sebastian Markbåge
8e74a31b2d Add Webpack as devDependency (#17379)
This is now used by the Flight package so it needs to be installed as a
peer.
2019-11-15 14:02:59 -08:00
Sebastian Markbåge
39dbb14da3 [Flight] Move Flight DOM to a Webpack Specific Package (#17372)
* Move Flight DOM to Webpack Specific Packagee

We'll have Webpack specific coupling so we need to ensure that it can be
versioned separately from various Webpack versions. We'll also have builds
for other bundlers in the future.

* Move to peerDep

* Move DOM Flight Tests

* Merge ReactFlightIntegration into ReactFlightDOM

This was an integration test. We can add to it.

* Fix fixture paths
2019-11-15 11:46:07 -08:00
Dominic Gannaway
532810a370 [react-interactions] FocusWithin beforeblur propagation fix (#17375) 2019-11-15 12:05:00 +00:00
Dominic Gannaway
f30ccb9ed9 [react-interactions] Fix unatached fiber bug (#17371) 2019-11-15 00:47:33 +00:00
Luna Ruan
1832f832c5 Changelog for 16.12 2019-11-14 16:06:10 -08:00
Luna Ruan
9a5f28dbed update version numbers for 16.12 2019-11-14 16:02:18 -08:00
Ricky
769dd522a2 [Fast Refresh] Fix for intentional unmounts after an error (#17368) 2019-11-14 18:40:25 +00:00
Dominic Gannaway
df8db4e005 [react-interactions] Enable event system before dispatching blur (#17365) 2019-11-14 13:47:39 +00:00
Dominic Gannaway
fc43644eba [react-interactions] Follow up active element blur logic (#17364) 2019-11-14 11:55:50 +00:00
Dominic Gannaway
a61886b16b [react-interactions] Refine custom active element blur logic (#17354) 2019-11-13 20:46:00 +00:00
Andrew Clark
b53ea6ca05 [Bugfix] Passive effects triggered by synchronous renders in a multi-root app (#17347)
* Regression test: Effects dropped across roots

See #17066

* [Bugfix] Passive effects loop

The bug
-------

In a multi-root app, certain passive effects (`useEffect`) are never
fired. See #17066.

The underlying problem
----------------------

The implicit contract of `flushPassiveEffects` is that, right after
calling it, there should be no pending passive effects. In the normal
case, in concurrent mode, this is true. But the current implementation
fails to account for the case where a passive effect schedules
synchronous work, which in turn schedules additional passive effects.

This led to `rootWithPendingPassiveEffects` being overwritten in the
commit phase, because an assignment that assumed it was replacing null
was actually replacing a reference to another root, which has the
consequence of dropping passive effects on that root.

The fix
-------

The fix I've chosen here is, at the beginning of the commit phase, keep
flushing passive effects in a loop until there are no more.

This doesn't not change the "public" implementation of
`flushPassiveEffects`, though it arguably should work this way, too. I
say "public" because it's only used by implementation layers on top of
React which we control: mainly, the legacy version of `act` that does
not use the mock Scheduler build. So there's probably still a bug
in that `act` implementation.

I will address `act` in a follow-up. The ideal solution is to replace
the legacy `act` with one implemented directly in the renderer, using a
special testing-only build of React DOM. Since that requires a breaking
change, we'll need an interim solution. We could make the "public" `act`
recursively flush effects in a loop, as I've done for the commit phase.
However, I think a better solution is to stop automatically flushing the
synchronous update queue at the end of `flushPassiveEffects`, and
instead require the caller to explicitly call `flushSyncUpdateQueue` (or
the equivalent) if needed. This follows the same pattern we use
internally in the work loop, which is designed to avoid factoring
hazards like the one that resulted in this bug.
2019-11-12 10:41:07 -08:00
Vasilii Cuhar
f4cc45ce96 [Fresh] Add options to configure RefreshSig and RefreshReg identifiers (#17340) 2019-11-12 14:16:23 +00:00
Eli White
ade764157f [Native] If statement cleanup for null targets (#17346) 2019-11-11 12:58:30 -08:00
Eli White
3dcec3a925 [Native] Add FeatureFlag to dispatch events with instance currentTarget (#17345)
* [Native] Add FeatureFlag to dispatch events with instance targets

* Prettier

* [Native] Change currentTarget to be an instance behind a flag 2/2
2019-11-11 12:42:06 -08: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
Eli White
01bce8c248 Change legacy-events plugin nativeEventTarget to allow null (#17344) 2019-11-11 11:22:41 -08:00
Dominic Gannaway
6cff70a740 [react-interactions] Expost host instance to Scope Query function (#17341) 2019-11-11 13:51:46 +00:00
Dan Abramov
b8f8258775 Split ReactDOM entry point (#17331)
* Split ReactDOM entry point

* BatchedRoot -> BlockingRoot
2019-11-10 13:43:29 +00:00
Dan Abramov
a7b4d51a20 Warn when doing createRoot twice on the same node (another approach) (#17329)
* Unify fields used for createRoot warning and event system

* Warn when doing createRoot twice on the same node

* Stricter check for modern roots

* Unmark asynchronously

* Fix Flow
2019-11-10 00:54:13 +00:00
Dan Abramov
be3bfa6fab [Flight] Basic Integration Test (#17307)
* [Flight] Basic Integration Test

* Just act()

* Lint

* Remove unnecessary acts

* Use Concurrent Mode

* it.experimental

* Fix prod test by advancing time

* Don't observe initial state
2019-11-09 02:56:03 +00:00
Dan Abramov
182f64f938 [Flight] End-to-End Fixture (#17319) 2019-11-09 02:44:27 +00:00
Dan Abramov
6cb6b1d668 Add yarn build --unsafe-partial (#17316)
* Add yarn build --partial

* unsafe-partial
2019-11-08 19:41:40 +00:00
Moti Zilberman
38dd17ab98 [RN] Hoist static deepDiffer options object (#17303) 2019-11-07 16:03:55 +00: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
Dominic Gannaway
e701632ad4 [react-interactions] Change unmount blur logic to a dedicated event (#17291) 2019-11-07 10:27:02 +00:00
Dominic Gannaway
ce4b3e9981 [react-interactions] Add optional searchNodes to Scope.queryAllNodes (#17293) 2019-11-06 22:52:59 +00:00
Sebastian Markbåge
dee03049f5 [Flight] Basic Streaming Suspense Support (#17285)
* Return whether to keep flowing in Host config

* Emit basic chunk based streaming in the Flight server

When something suspends a new chunk is created.

* Add reentrancy check

The WHATWG API is designed to be pulled recursively.

We should refactor to favor that approach.

* Basic streaming Suspense support on the client

* Add basic suspense in example

* Add comment describing the protocol that the server generates
2019-11-06 09:48:34 -08:00
Dan Abramov
f50f39b55f [Flight] Better compat with http.createServer (#17289) 2019-11-06 17:10:26 +00:00
Brian Vaughn
3452706308 DevTools cleanup (#17283)
1. Add a Store test for memo, lazy, and forwardRef components
2. Remove dead code for React.lazy
3. Update DT tests to include HOC badge names in the serialized store
2019-11-05 22:19:10 -08:00
Dominic Gannaway
cd1bdcd067 [react-interactions] Prevent duplicate onPress firing for keyboard Enter (#17266)
* [react-interactions] Prevent duplicate onPress firing for keyboard Enter

* address feedback
2019-11-05 23:28:26 +00:00
Waseem Dahman
4f02c93c7c Fix devtools displaying Anonymous for memo of ref-forwarding components (#17274)
* [react-is] return correct typeOf value of forwardRef

* [react-devtools-shared] use correct displayName of memo(forwardRef(Component))

* [react-devtools-shared] add resolveFiberType and resolve fiber type of memo recursively

Resolving the fiber type of memo recursively before passing it to getDisplayName
will prevent it from displaying "Anonymous" as displayName for components
wrapped with both memo and forwardRef: memo(forwardRef(Component))

* rework resolveFiberType
2019-11-05 14:08:01 -08:00
Brian Vaughn
053cf0fedc Fix react-is memo and lazy type checks (#17278) 2019-11-05 10:37:12 -08:00
Andrew Clark
0f3838a01b Remove debugRenderPhaseSideEffects flag (#17270)
There are two similar flags, `debugRenderPhaseSideEffects` and
`debugRenderPhaseSideEffectsForStrictMode`. The strict mode one is the
only one that is actually used. I think originally the theory is that
we would one day turn it on for all components, even outside strict
mode. But what we'll do instead is migrate everyone to strict mode.

The only place `debugRenderPhaseSideEffects` was being used was in
an internal test file. I rewrote those tests to use public APIs.
2019-11-04 14:07:05 -08:00
Dominic Gannaway
cb09dbe0ab [react-interactions] Add handleSimulateChildBlur upon DOM node removal (#17225)
* [react-interactions] Add handleSimulateChildBlur upon DOM node removal
2019-11-04 20:02:45 +00:00
Eli White
6095993d46 Types: findHostInstance_DEPRECATED returns React.ElementRef<HostComponent<mixed>> (#17265)
* Types: findHostInstance_DEPRECATED returns React.ElementRef<HostComponent<mixed>>

* Prettier
2019-11-04 10:14:01 -08:00
Mateusz Burzyński
62ef25077e Avoid bundling in ponyfill for Object.assign in use-subscription package (#17259) 2019-11-04 07:33:10 -08:00
Sebastian Markbåge
f4148b2561 [Flight] Move around the Server side a bit (#17251)
* Rename ReactFlightStreamer -> ReactFlightServer

* Unify Browser/Node stream tests into one file and use the client reader

* Defer to the actual ReactDOM for HTML rendering for now

This will need to use a variant of Fizz to do inline SSR in Flight.
However, I don't want to build the whole impl right now but also don't
want to exclude the use case yet. So I outsource it to the existing
renderer. Ofc, this doesn't work with Suspense atm.
2019-11-01 17:39:24 -07:00
Sebastian Markbåge
fadc97167f [Flight] Add Client Infrastructure (#17234)
* Change demo to server

* Expose client in package.json

* Reorganize tests

We don't want unit tests but instead test how both server and clients work
together. So this merges server/client test files.

* Fill in the client implementation a bit

* Use new client in fixture

* Add Promise/Uint8Array to lint rule

I'll probably end up deleting these deps later but they're here for now.
2019-11-01 16:05:07 -07:00
Brian Vaughn
36fd29f09f Don't show empty (no work) commits in Profiler (#17253) 2019-11-01 15:51:39 -07:00
Andrew Clark
a2e05b6c14 [Scheduler] Delete old rAF implementation (#17252)
We've been using the message loop version for a while. Time to delete.
2019-11-01 13:32:22 -07:00
Andrew Clark
6dc2734b41 Codemod tests to it.experimental (#17243)
`it.experimental` marks that a test only works in Experimental builds.

It also asserts that a test does *not* work in the stable builds. The
main benefit is that we're less likely to accidentally expose an
experimental API before we intend. It also forces us to un- mark an
experimental test once it become stable.
2019-11-01 10:20:08 -07:00
Ives van Hoorne
a1ff9fd7bb Add CodeSandbox CI Config (#17175)
* Add CodeSandbox CI Config

* Add default sandbox to build

* Make build more efficient and add scheduler

* Force build

* Add scheduler image

* Add scheduler/tracing to the build

* Force another build
2019-10-31 10:44:48 -07:00
Brian Vaughn
273679a78c DevTools standalone shell changes: (#17213)
* DevTools standalone shell changes:

1. Update React Native connection wording
2. Tweak styles slightly

* Tweaked standalone DevTools error warning text
2019-10-31 09:22:08 -07:00
Eli White
d0fc0ba0a6 Revert "Dispatch commands to both UIManagers from both renderers (#17211)" (#17232)
This reverts commit 8eee0eb01c.
2019-10-30 18:03:37 -07:00
Eli White
bdcdb69a24 Rename findHostInstance_deprecated to findHostInstance_DEPRECATED (#17228) 2019-10-30 13:10:16 -07:00
Eli White
515746c217 Add findHostInstance_deprecated to the React Native Renderer (#17224) 2019-10-30 11:42:37 -07:00
Brian Vaughn
9a35adc96d Only call Profiler onRender when a descendant had work (#17223) 2019-10-30 11:08:42 -07:00
Eli White
8eee0eb01c Dispatch commands to both UIManagers from both renderers (#17211)
* Dispatch commands to both UIManagers from both renderers

* Merge test files
2019-10-29 18:16:23 -07:00
Sebastian Markbåge
f4e974d26e Add Experimental Flight Infrastructure (#16398)
* Add Flight Build and Unify HostFormat Config between Flight and Fizz

* Add basic resolution of models

* Add basic Flight fixture

Demonstrates the streaming protocol.

* Rename to flight-server to distinguish from the client parts

* Add Flight Client package and entry point

* Fix fixture
2019-10-29 14:45:47 -07:00
Sebastian Markbåge
6cd365cac6 Don't treat the last row in hidden as deleted if already mounted (#17206)
Already mounted rows that resuspend may be considered as part of a tail
if they're at the end. However, for purposes of the tail="..." option
they don't get deleted. We deal with that in cutOffTailIfNeeded.

However, if they're also the first to suspend in the "hidden" case, we have
a special case that deletes the actual rendered row. This needs to consider
if that row was already mounted or things go wrong.
2019-10-29 13:38:25 -07:00
Dominic Gannaway
048879edad [react-interactions] Ensure props on scope query function is always object (#17212) 2019-10-29 13:26:46 -07:00
Brian Vaughn
3497ccc149 Add guard to handle modified React elements with non-string keys (#17164) 2019-10-29 08:41:48 -07:00
Lea Rosema
0f64703edf Update .mailmap (#17177) 2019-10-28 16:48:54 +00:00
Deniz Susman
3f9c036758 Typo fix in comment (#17111) 2019-10-26 08:33:05 -07:00
Dan Abramov
f6b8d31a76 Rename createSyncRoot to createBlockingRoot (#17165)
* Rename createSyncRoot to createBlockingRoot

* Fix up
2019-10-23 15:04:39 -07:00
Wilco Fiers
9c02d26549 docs: Fixed a typo in readme.md (#17119) 2019-10-23 18:52:14 +01:00
Andrew Clark
57b2fbb741 Changelog for 16.11.0 2019-10-22 14:30:12 -07:00
Andrew Clark
8075c8505b Update local package versions for 16.10 release 2019-10-22 14:30:06 -07:00
Brian Vaughn
5faf377df5 Fixed a style bug in props editor (#17162) 2019-10-21 15:08:55 -07:00
Dominic Gannaway
f7ec65eeba [react-interactions] Make events non-passive to allow preventDefault (#17136) 2019-10-21 22:37:27 +02:00
Andrew Clark
1022ee0ec1 Read current time without marking event start time (#17160)
* Failing test: DevTools hook freezes timeline

The DevTools hook calls `requestCurrentTime` after the commit phase has
ended, which has the accidnental consequence of freezing the start
time for subsequent updates. If enough time goes by, the next update
will instantly expire.

I'll push a fix in the next commit.

* Read current time without marking event start time

`requestCurrentTime` is only meant to be used for updates, because
subsequent calls within the same event will receive the same time.
Messing this up has bad consequences.

I renamed it to `requestCurrentTimeForUpdate` and created a new
function that returns the current time without the batching heuristic,
called `getCurrentTime`.

Swapping `requestCurrentTime` for `getCurrentTime` in the DevTools
hook fixes the regression test added in the previous commit.
2019-10-21 13:15:37 -07:00
Andrew Clark
349cf5acc3 Experimental test helper: it.experimental (#17149)
Special version of Jest's `it` for experimental tests. Tests marked as
experimental will run **both** stable and experimental modes. In
experimental mode, they work the same as the normal Jest methods. In
stable mode, they are **expected to fail**. This means we can detect
when a test previously marked as experimental can be un-marked when the
feature becomes stable. It also reduces the chances that we accidentally
add experimental APIs to the stable builds before we intend.

I added corresponding methods for the focus and skip APIs:

- `fit` -> `fit.experimental`
- `it.only` -> `it.only.experimental` or `it.experimental.only`
- `xit` -> `xit.experimental`
- `it.skip` -> `it.skip.experimental` or `it.experimental.skip`

Since `it` is an alias of `test`, `test.experimental` works, too.
2019-10-19 16:08:08 -07:00
Andrew Clark
edc234c730 Build script should default to experimental (#17144)
`yarn build` defaults to building in experimental mode. To opt-out, set
the `RELEASE_CHANNEL` environment variable to `stable`. This is the same
as what we do when running tests via `yarn test`, to make local
development easier.
2019-10-18 19:35:33 -07:00
Sebastian Markbåge
3cc564547c SuspenseList support in DevTools (#17145)
* SuspenseList support in DevTools

This adds SuspenseList tags to DevTools so that the name properly shows
up.

It also switches to use the tag instead of Symbol type for Suspense
components. We shouldn't rely on the type for any built-ins since that
field will disappear from the fibers. How the Fibers get created is an
implementation detail that can change e.g. with a compiler or if we
use instanceof checks that are faster than symbol comparisons.

* Add SuspenseList test to shell app
2019-10-18 17:18:36 -07:00
Sebastian Markbåge
68fb58029d Remove unstable_ prefix in various internal uses (#17146)
* Rename unstable_createRoot in DevTools

* Rename createSyncRoot in warning
2019-10-18 17:18:10 -07:00
Andrew Clark
3059ab3523 Add experimental instructions to release README (#17143) 2019-10-18 16:26:06 -07:00
Andrew Clark
093de5fb43 Lint experimental build artifacts (#17141)
Adds `lint_build` job to the experimental workflow
2019-10-18 16:03:08 -07:00
Andrew Clark
7082d5a2db Don't build non-experimental www bundles (#17139)
Reduces the likelihood we'll accidentally sync the wrong ones.
2019-10-18 14:36:59 -07:00
Andrew Clark
c47f59331e Move SuspenseList to experimental package (#17130)
Also moves `withSuspenseConfig`
2019-10-18 14:24:13 -07:00
Luna Ruan
685ed561f2 Migrate useDeferredValue and useTransition (#17058)
Migrated useDeferredValue and useTransition from Facebook's www repo into ReactFiberHooks.
2019-10-18 12:48:43 -07:00
Dan Abramov
0b61e26983 Update RN typings for a shim (#17138) 2019-10-18 18:05:09 +01:00
Sebastian Markbåge
4eeee358e1 [SuspenseList] Store lastEffect before rendering (#17131)
* Add a failing test for SuspenseList bug

* Store lastEffect before rendering

We can't reset the effect list to null because we don't rereconcile the
children so we drop deletion effects if we do that.

Instead we store the last effect as it was before we started rendering
so we can go back to where it was when we reset it.

We actually already do something like this when we delete the last row
for the tail="hidden" mode so we had a field available for it already.
2019-10-17 15:57:07 -07:00
Nicolas Gallagher
4fb5bf61dd [react-interactions] Fix focus-visible heuristic (#17124)
Respond to all keys not just `Tab`
2019-10-17 09:24:31 -07:00
Dominic Gannaway
8facc05373 [react-interactions] Allow event.preventDefault on LegacyPress responder (#17113)
[react-interactions] Allow event.preventDefault on LegacyPress responder
2019-10-17 10:21:02 +02:00
Andrew Clark
7cec15155a Remove prefixed concurrent APIs from www build (#17108)
The downstream callers have been updated, so we can remove these.
2019-10-16 18:58:33 -07:00
Sebastian Markbåge
ed5f010ae5 Client render Suspense content if there's no boundary match (#16945)
Without the enableSuspenseServerRenderer flag there will never be a boundary match. Also when it is enabled, there might not be a boundary match if something was conditionally rendered by mistake.

With this PR it will now client render the content of a Suspense boundary in that case and issue a DEV only hydration warning. This is the only sound semantics for this case.

Unfortunately, landing this will once again break #16938. It will be less bad though because at least it'll just work by client rendering the content instead of hydrating and issue a DEV only warning.

However, we must land this before enabling the enableSuspenseServerRenderer flag since it does this anyway.

I did notice that we special case fallback={undefined} due to our unfortunate semantics for that. So technically a workaround that works is actually setting the fallback to undefined on the server and during hydration. Then flip it on only after hydration. That could be a workaround if you want to be able to have a Suspense boundary work only after hydration for some reason.

It's kind of unfortunate but at least those semantics are internally consistent. So I added a test for that.
2019-10-16 16:23:12 -07:00
Dominic Gannaway
916937563b [react-interactions] Add onFocusWithin event to FocusWithin responder (#17115) 2019-10-16 22:57:08 +02:00
Andrew Clark
d7feeb25ac unstable_createRoot -> createRoot in test (#17107)
Fixes test added in #17105, which was based on an earler commit than the
one that removed the `unstable_` prefix from `createRoot`.
2019-10-15 21:37:54 -07:00
Sebastian Markbåge
6ff23f2a5d Change retry priority to "Never" for dehydrated boundaries (#17105)
This changes the "default" retryTime to NoWork which schedules at Normal
pri.

Dehydrated bouundaries normally hydrate at Never priority except when they
retry where we accidentally increased them to Normal because Never was used
as the default value. This changes it so NoWork is the default.

Dehydrated boundaries however get initialized to Never as the default.

Therefore they now hydrate as Never pri unless their priority gets
increased by a forced rerender or selective hydration.

This revealed that erroring at this Never priority can cause an infinite
rerender. So I fixed that too.
2019-10-15 19:53:20 -07:00
Andrew Clark
2c832b4dcf Separate sizebot for experimental builds (#17100)
Configures the sizebot to leave a second comment that tracks the
experimental build artifacts.
2019-10-15 18:43:06 -07:00
Luna Ruan
3ac0eb075d Modify Babel React JSX Duplicate Children Fix (#17101)
If a JSX element has both a children prop and children (ie. <div children={childOne}>{childTwo}</div>), IE throws an Multiple definitions of a property not allowed in strict mode. This modifies the previous fix (which used an Object.assign) by making the duplicate children a sequence expression on the next prop/child instead so that ordering is preserved. For example:

```
<Component children={useA()} foo={useB()} children={useC()}>{useD()}</Component>
```
should compile to
```
React.jsx(Component, {foo: (useA(), useB()), children: (useC(), useD)})
```
2019-10-15 17:13:21 -07:00
Andrew Clark
43562455c9 Temporary patch www fork with prefixed APIs (#17103)
I'm doing this here instead of in the downstream repo so that if the
sync diff gets reverted, it doesn't revert this, too.

Once the sync has landed, and the callers are updated in www, I will
remove this.
2019-10-15 16:44:33 -07:00
Andrew Clark
9123c479f4 Enable concurrent APIs in all experimental forks (#17102)
Forgot to update the flags in the forked modules.
2019-10-15 16:19:45 -07:00
Andrew Clark
30c5daf943 Remove concurrent apis from stable (#17088)
* Tests run in experimental mode by default

For local development, you usually want experiments enabled. Unless
the release channel is set with an environment variable, tests will
run with __EXPERIMENTAL__ set to `true`.

* Remove concurrent APIs from stable builds

Those who want to try concurrent mode should use the experimental
builds instead.

I've left the `unstable_` prefixed APIs in the Facebook build so we
can continue experimenting with them internally without blessing them
for widespread use.

* Turn on SSR flags in experimental build

* Remove prefixed concurrent APIs from www build

Instead we'll use the experimental builds when syncing to www.

* Remove "canary" from internal React version string
2019-10-15 15:09:19 -07:00
Dominic Gannaway
4cb399a433 [react-interactions] Modify Scope query mechanism (#17095) 2019-10-15 15:57:02 +02:00
Dominic Gannaway
e7704e22a1 [babel-plugin-react-jsx] Avoid duplicate "children" key in props object (#17094)
* [babel-plugin-react-jsx] Avoid duplicate "children" key in props object

* Use Object.assign approach
2019-10-15 15:41:09 +02:00
Krzysztof Kotowicz
fdba0e5ce7 Fixed a bug with illegal invocation for Trusted Types (#17083)
* Fixed a bug with illegal invocation.

* Fixed the test.
2019-10-15 11:41:42 +01:00
Andrew Clark
a8c6a1b34e Update release scripts to support experimental releases (#17086)
* Download correct artifacts for release channel

Experimental builds should pull artifacts from the
`process_artifacts_experimental` job.

I think instead of two separate CI workflows, a better approach might
be to build stable artifacts to the `build` directory and the
experimental artifacts to a `build_experimental` directory, and
generate both within the same workflow. This would take some work since
lots of things assume the output directory is `build`, but something
to consider in the future.

* Prevent experimental promotion to stable

Adds a check to the `prepare-stable` script to prevent experimental
builds from being published using stable semver versions.
2019-10-14 14:15:23 -07:00
Andrew Clark
d364d8555f Set up experimental builds (#17071)
* Don't bother including `unstable_` in error

The method names don't get stripped out of the production bundles
because they are passed as arguments to the error decoder.

Let's just always use the unprefixed APIs in the messages.

* Set up experimental builds

The experimental builds are packaged exactly like builds in the stable
release channel: same file structure, entry points, and npm package
names. The goal is to match what will eventually be released in stable
as closely as possible, but with additional features turned on.

Versioning and Releasing
------------------------

The experimental builds will be published to the same registry and
package names as the stable ones. However, they will be versioned using
a separate scheme. Instead of semver versions, experimental releases
will receive arbitrary version strings based on their content hashes.
The motivation is to thwart attempts to use a version range to match
against future experimental releases. The only way to install or depend
on an experimental release is to refer to the specific version number.

Building
--------

I did not use the existing feature flag infra to configure the
experimental builds. The reason is because feature flags are designed
to configure a single package. They're not designed to generate multiple
forks of the same package; for each set of feature flags, you must
create a separate package configuration.

Instead, I've added a new build dimension called the **release
channel**. By default, builds use the **stable** channel. There's
also an **experimental** release channel. We have the option to add more
in the future.

There are now two dimensions per artifact: build type (production,
development, or profiling), and release channel (stable or
experimental). These are separate dimensions because they are
combinatorial: there are stable and experimental production builds,
stable and experimental developmenet builds, and so on.

You can add something to an experimental build by gating on
`__EXPERIMENTAL__`, similar to how we use `__DEV__`. Anything inside
these branches will be excluded from the stable builds.
This gives us a low effort way to add experimental behavior in any
package without setting up feature flags or configuring a new package.
2019-10-14 10:46:42 -07:00
Sebastian Markbåge
d5b54d0c35 [SuspenseList] Fix bugs with dropped Promises (#17082)
* Transfer any pending promises from inner boundary to list

For non-hidden modes, this boundary should commit so this shouldn't be
needed but the nested boundary can make a second pass which forces these
to be recreated without resuspending. In this case, the outer list assumes
that it can collect the inner promises to still rerender if needed.

* Propagate suspense "context" change to nested SuspenseLists

This means that we always rerender any nested SuspenseLists together.

This bug looks similar to the previous one but is not based on the lack of
retry but that the retry only happens on the outer boundary but the inner
doesn't get a retry ping since it didn't know about its own promise after
the second pass.
2019-10-14 09:42:10 -07:00
Andrew Clark
75955bf1d7 Pass prod error messages directly to constructor (#17063)
* Remove "Invariant Violation" from dev errors

When I made the change to compile `invariant` to throw expressions, I
left a small runtime to set the error's `name` property to "Invariant
Violation" to maintain the existing behavior.

I think we can remove it. The argument for keeping it is to preserve
continuity in error logs, but this only affects development errors,
anyway: production error messages are replaced with error codes.

* Pass prod error messages directly to constructor

Updates the `invariant` transform to pass an error message string
directly to the Error constructor, instead of mutating the
message property.

Turns this code:

```js
invariant(condition, 'A %s message that contains %s', adj, noun);
```

into this:

```js
if (!condition) {
  throw Error(
    __DEV__
      ? `A ${adj} message that contains ${noun}`
      : formatProdErrorMessage(ERR_CODE, adj, noun)
  );
}
```
2019-10-11 09:10:40 -07:00
Dominic Gannaway
0ac8e563d0 [react-interactions] Add getInstanceFromNode support to TestHostRenderer (#17065)
Fix bad WeakMap key case

Fix bad WeakMap key case
2019-10-11 16:58:27 +02:00
Brian Vaughn
22b2642a56 DevTools test shell tweaks (#17054)
* Updated DevTools shell ignore warning message to account for recent changes in warning text

* Update DevTools console patching to patch the parent window's console rather than the iframe, to more accurately simulate real usage environment
2019-10-09 12:37:25 -07:00
Eli White
4be45be5ff Stop warning about setNativeProps being deprecated (#17045)
* Stop warning about setNativeProps being deprecated

* Remove ReactNative.setNativeProps

* Remove more Fabric tests
2019-10-08 11:21:20 -07:00
Dominic Gannaway
b71ab61c8f [react-interactions] Adds more experimental Scope API methods (#17042) 2019-10-08 19:32:53 +02:00
Andrew Clark
5a71cbe7a9 Remove unused export
Meant to do this in e4b21be but neglected to `git add` the changes.
2019-10-07 15:32:34 -07:00
Andrew Clark
71d012ecd0 Remove dormant createBatch experiment (#17035)
* Remove dormant createBatch experiment

In a hybrid React app with multiple roots, `createBatch` is used to
coordinate an update to a root with its imperative container.

We've pivoted away from multi-root, hybrid React apps for now to focus
on single root apps.

This PR removes the API from the codebase. It's possible we'll add back
some version of this feature in the future.

* Remove unused export
2019-10-07 14:15:15 -07:00
Andrew Clark
cd1b167ad4 [Scheduler Profiler] Use microsecond precision (#17010)
The `performance.now` returns a timestamp in milliseconds as a float.
The browser has the option to adjust the precision of the float, but
it's usually more precise than a millisecond. However, this precision
is lost when the timestamp is logged by the Scheduler profiler, because
we store the numbers in an Int32Array.

This change multiplies the millisecond float value by 1000, giving us
three more degrees of precision.
2019-10-07 09:16:18 -07:00
Dominic Gannaway
55731fd8ce [react-interactions] Refine a11y component flow types (#17032) 2019-10-07 16:36:16 +02:00
Dominic Gannaway
a011aacafa [react-interactions] Remove FB builds of a11y components (#17030) 2019-10-07 12:45:49 +02:00
Dominic Gannaway
fff5b1ca77 [react-interactions] Add FocusTable colSpan support (#17019) 2019-10-07 12:04:41 +02:00
Luna Ruan
4bc52ef0df Revert "update hideOrUnhideAllChildren to hide portals that aren't wrapped in a host component (#16992)" (#17011)
This reverts commit de2edc268d.
2019-10-03 17:22:22 -07:00
Sebastian Markbåge
3a2b5f148d [Selective Hydration] ReactDOM.unstable_scheduleHydration(domNode) (#17004)
Adds an API to explicitly prioritize hydrating the path to a particular DOM node without relying on events to do it.

The API uses the current scheduler priority to schedule it. For the same priority, the last one wins. This allows a similar effect as continuous events. This is useful for example to hydrate based on scroll position, or prioritize components that will upgrade to client-rendered-only content.

I considered having an API that explicitly overrides the current target(s). However that makes it difficult to coordinate across components in an app.

This just hydrates one target at a time but if it is blocked on I/O we could consider increasing priority of later targets too.
2019-10-03 14:48:28 -07:00
Dominic Gannaway
26ba38ae4b [EnterLeaveEventPlugin] Fix bug when dealing with unhandled DOM nodes (#17006) 2019-10-03 23:35:09 +02:00
Andrew Clark
abedf17597 Changelog for v16.10.2 2019-10-03 14:16:13 -07:00
Andrew Clark
d256f88ac6 Update local version numbers for 16.10.2 release 2019-10-03 14:14:10 -07:00
Brian Vaughn
a8b8ffb894 DevTools v4.1.3 -> v4.2.0 2019-10-03 12:34:35 -07:00
Brian Vaughn
0545f366d4 Added trace updates feature (DOM only) (#16989)
* Added trace updates feature (DOM only)
* Updated DevTools CHANGELOG
2019-10-03 11:07:18 -07:00
Simen Bekkhus
e09097a75d chore: upgrade to jest 24 (#15778)
* chore: upgrade to jest 24

* download react-is from npm manually
2019-10-03 22:44:18 +05:30
Rane Wallin
5943b1da6c Fixing grammatical errors in error message (#16973)
* Fixing grammatical errors in error message

* Fixing grammar error in test file
2019-10-03 18:14:48 +05:30
Dominic Gannaway
4c5698400f [react-interactions] Remove context.setTimeout & context.clearTimeout (#17000) 2019-10-03 13:37:37 +02:00
Dominic Gannaway
b33633d932 [react-interactions] Repurpose React a11y modules (#16997) 2019-10-03 11:19:24 +02:00
Luna Ruan
de2edc268d update hideOrUnhideAllChildren to hide portals that aren't wrapped in a host component (#16992)
Currently, when a node suspends, if its subtree contains a portal, the portal is not hidden. This hides portals in the subtree when it's not wrapped in a host component .
2019-10-02 15:30:55 -07:00
Sebastian Markbåge
bb680a0905 [Selective Hydration] Prioritize the last continuous target (#16937)
* Prioritize the last continuous target

This ensures that the current focus target is always hydrated first.

Slightly higher than the usual Never expiration time used for hydration.
The priority increases with each new queued item so that the last always
wins.

* Don't export the moving target

It's not useful for comparison purposes anyway.
2019-10-02 14:52:23 -07:00
Eli White
10277cc5ba Remove unused canonical check in fiber host component (#16914) 2019-10-02 11:07:20 -07:00
Nicolas Gallagher
ab1a4f249e Move eventSystemFlags to last argument in event plugin extractors (#16978)
Fix for necolas/react-native-web#1443
2019-10-02 10:31:15 -07:00
Nicolas Gallagher
f6efb224b0 [react-interactions] Tap cancels on second pointerdown (#16936)
This patch causes onTapCancel to be called whenever a second pointer interacts
with the responder target.
2019-10-01 15:13:31 -07:00
Dominic Gannaway
34457729a6 [react-interactions] Add allowModifiers flag to FocusList + FocusTable (#16971) 2019-10-01 17:59:52 +02:00
Rango Yuan
b34f042e5b Fix mouseenter handlers fired twice (#16928) 2019-10-01 14:03:14 +02:00
Andrew Clark
05dc814cf0 Remove IIFE wrappers from dev invariant checks (#16963)
The error transform works by replacing calls to `invariant` with
an `if` statement.

Since we're replacing a call expression with a statement, Babel wraps
the new statement in an immediately-invoked function expression (IIFE).
This wrapper is unnecessary in practice because our `invariant` calls
are always part of their own expression statement.

In the production bundle, the function wrappers are removed by Closure.
But they remain in the development bundles.

This commit updates the transform to confirm that an `invariant` call
expression's parent node is an expression statement. (If not, it throws
a transform error.)

Then, it replaces the expression statement instead of the expression
itself, effectively removing the extraneous IIFE wrapper.
2019-09-30 11:14:51 -07:00
Brian Vaughn
2c8832075b React DevTools v4.1.2 -> v.4.1.3 2019-09-30 09:33:23 -07:00
Brian Vaughn
6c73a1e776 Updated DevTools CHANGELOG 2019-09-30 08:31:47 -07:00
David Huang
6a3de7a414 [DevTools] postMessage target origin needs to be '*' for local files (#16953) 2019-09-30 08:29:18 -07:00
Dominic Gannaway
ac8e8b3278 [react-interactions] Add tab handling to FocusList (#16958) 2019-09-30 17:13:35 +02:00
Dominic Gannaway
10c7dfe3b4 [react-interactins] FocusTable tabScope handling+tabIndex control (#16922) 2019-09-30 11:41:20 +02:00
Kirankumar Ambati
d3622d0f97 chore: updated comment message (#16949) 2019-09-29 15:00:49 -07:00
Andrew Clark
2a264a9dbe Update local version numbers for 16.10.1 release 2019-09-28 21:41:42 -07:00
Andrew Clark
22019ef5a2 Changelog for v16.10.1 2019-09-28 11:24:19 -07:00
Sebastian Markbåge
d8a76ad580 Allow Suspense Mismatch on the Client to Silently Proceed (#16943)
* Regression test: Suspense + hydration + legacy

* Allow Suspense Mismatch on the Client to Silently Proceed

This fixes but isn't actually the semantics that we want this case to have.
2019-09-28 10:43:53 -07:00
Sebastian Markbåge
9d637844e9 Remove enableUserBlockingEvents flag (#16882)
Seems like this worked out. We can clean up the flag now.
2019-09-27 19:46:56 -07:00
Sebastian Markbåge
fe31cc710e [Selective Hydration] Increase priority for non-synchronous discrete events and retries (#16935)
* Increase retryTime for increased priority dehydrated boundaries

* Increaese the priority to user blocking for every next discrete boundary
2019-09-27 17:27:17 -07:00
Brian Vaughn
b550679617 Fixed typo in DevTools CHANGELOG 2019-09-27 17:10:27 -07:00
Brian Vaughn
5184346daf DevTools v4.1.1 -> v4.1.2 2019-09-27 17:03:17 -07:00
Brian Vaughn
d4278663c6 Replaced === check with Object.is() to support values like NaN (#16934) 2019-09-27 16:54:53 -07:00
Nicolas Gallagher
d1121c0174 [react-interactions] Fix virtual click heuristic (#16915) 2019-09-27 15:38:47 -07:00
Andrew Clark
f553515d1e Fix heading level in changelog 2019-09-27 13:37:36 -07:00
Andrew Clark
7dc83a6100 Changelog for 16.10 2019-09-27 13:31:47 -07:00
Andrew Clark
93f5f11b79 Update local version numbers for 16.10 release 2019-09-27 13:31:35 -07:00
Luna Ruan
c8dc7a926e expose isHydrating (#16909)
expose isHydrating for FB
2019-09-26 14:47:01 -07: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
Andrew Clark
fad5102101 [bugfix] Fix false positive render phase update (#16907)
Need to reset the current "debug phase" inside the catch block.
Otherwise React thinks we're still in the render phase during the
subsequent event.
2019-09-26 12:47:48 -07:00
Brian Vaughn
a9cd9a765b DevTools v4.1.0 -> v4.1.1 2019-09-26 10:22:59 -07:00
Brian Vaughn
b6606ecba8 DevTools shows unsupported renderer version dialog (#16897)
* DevTools shows unsupported renderer version dialog

* Optimistic CHANGELOG udpate
2019-09-26 08:41:46 -07:00
Brian Vaughn
84e83db1ee Updated DevTools CHANGELOG 2019-09-26 08:26:18 -07:00
Dominic Gannaway
b9811ed5bc [react-interactions] Add wrapping support to FocusList/FocusTable (#16903) 2019-09-26 15:15:48 +02:00
David Huang
49b0cb6db8 Moving backend injection to the content script (#16900) 2019-09-26 14:03:07 +01:00
Sebastian Markbåge
3694a3b5e9 Selective Hydration (#16880)
* Add Feature Flag for Selective Hydration

* Enable Synchronous Hydration of Discrete Events

* Resolve cyclic dependency
2019-09-25 15:26:27 -07:00
Dominic Gannaway
4bb0e96b4b [react-interactions] FocusTable key press bound propgataion (#16895) 2019-09-25 21:12:39 +02:00
Brian Vaughn
fa1a326227 Update useEditableValue hook to sync external value changes (#16878)
* Update useEditableValue to mirror value cahnges

Previously, the hook initialized local state (in useState) to mirror the prop/state value. Updates to the value were ignored though. (Once the state was initialized, it was never updated.) The new hook updates the local/editable state to mirror the external value unless there are already pending, local edits being made.

* Optimistic CHANGELOG update

* Added additional useEditableValue() unit test cases
2019-09-25 10:46:27 -07:00
Dominic Gannaway
57bf275fbd [devtools] Add support for React Scope symbol/number (#16893) 2019-09-25 19:03:37 +02:00
Dominic Gannaway
7c3bd08b37 [react-interactions] Add more documentation for a11y components (#16894) 2019-09-25 19:01:15 +02:00
Sebastian Markbåge
a06d181af0 Include tag in begin/complete invariant (#16881) 2019-09-25 08:10:35 -07:00
Sebastian Markbåge
0d8c0cd096 These flags are hard coded in our internal config (#16883)
By hard coding them here they can get properly DCE and don't have to be
sent to users. The internal config should only have dynamic flags.
2019-09-25 08:00:29 -07:00
Dominic Gannaway
d6d83d7060 [react-interactions] Add Portal propagation configuration (#16889) 2019-09-25 16:56:51 +02:00
Dominic Gannaway
d0ebde77f6 [react-interactions] Add initial docs explaining React Scopes (#16892) 2019-09-25 14:57:47 +02:00
Joshua Gross
32e5c97d11 [React Native] Improve errors for invalid ViewConfig getter functions (#16879)
* [React Native] Improve logging for missing view configs and invalid view config getter functions

* [React Native] Improve logging for missing view configs and invalid view config getter functions
2019-09-24 17:46:21 -07:00
Dominic Gannaway
ebc299fc2f [react-interactions] TabFocus -> FocusManager (#16874) 2019-09-24 23:26:20 +02:00
Dominic Gannaway
793f176dad [react-interactions] Make FocusList bundle (#16876) 2019-09-24 18:02:13 +02:00
Dominic Gannaway
68a87eee54 [react-interactions] Add FocusList component (#16875) 2019-09-24 17:14:29 +02:00
Jessica Franco
18d2e0c03e Warning system refactoring (part 1) (#16799)
* Rename lowPriorityWarning to lowPriorityWarningWithoutStack

This maintains parity with the other warning-like functions.

* Duplicate the toWarnDev tests to test toLowPriorityWarnDev

* Make a lowPriorityWarning version of warning.js

* Extract both variants in print-warning

Avoids parsing lowPriorityWarning.js itself as the way it forwards the
call to lowPriorityWarningWithoutStack is not analyzable.
2019-09-24 13:45:38 +01:00
Andrew Clark
8b580a89d6 Idle updates should not be blocked by hidden work (#16871)
* Idle updates should not be blocked by hidden work

Use the special `Idle` expiration time for updates that are triggered at
Scheduler's `IdlePriority`, instead of `Never`.

The key difference between Idle and Never¹ is that Never work can be
committed in an inconsistent state without tearing the UI. The main
example is offscreen content, like a hidden subtree.

¹ "Never" isn't the best name. I originally called it that because it
"never" expires, but neither does Idle. Since it's mostly used for
offscreen subtrees, we could call it "Offscreen." However, it's also
used for dehydrated Suspense boundaries, which are inconsistent in the
sense that they haven't finished yet, but aren't visibly inconsistent
because the server rendered HTML matches what the hydrated tree would
look like.

* Reset as early as possible using local variable

* Updates in a hidden effect should be Idle

I had made them Never to avoid an extra render when a hidden effect
updates the hidden component -- if they are Idle, we have to render once
at Idle, which bails out on the hidden subtree, then again at Never to
actually process the update -- but the problem of needing an extra
render pass to bail out hidden updates already exists and we should fix
that properly instead of adding yet another special case.
2019-09-23 20:52:48 -07:00
Nicolas Gallagher
c5e7190ed4 [react-interactions] Press with useRef instead of useState (#16870)
We only need to read and modify the value for the lifetime of the hook
2019-09-23 16:25:13 -07:00
Brian Vaughn
911104a129 DevTools CHANGELOG update 2019-09-23 12:58:58 -07:00
Brian Vaughn
bce2ac63a9 Revert change to backend injection method from PR #16752 (#16864)
PR #16752 changed how we were injecting the backend script to be done by the content script in order to work around Trusted Type limitations with our previous approach. This may have caused a regression (see #16840) so I'm backing it out to verify.
2019-09-23 12:56:36 -07:00
Brian Vaughn
9b3cde9b62 Fix DevTools v4.1 editable hook regression (#16867)
* Fixed a regression in hooks editor from a recent EditableValue change

* Fixed a reset/state bug in useEditableValue() hook and removed unnecessary useMemo()
2019-09-23 12:56:01 -07:00
Dominic Gannaway
1a6294d3e2 [react-interaction] Refactor a11y components more (#16866) 2019-09-23 21:30:49 +02:00
Dominic Gannaway
1758b3f7ba [react-interactions] Add no-op stopPropagation + preventDefault to Press (#16868)
Fix
2019-09-23 21:18:40 +02:00
Andrew Clark
013b7ad117 [suspense][error handling] Inline renderRoot and fix error handling bug (#16801)
* Outline push/pop logic in `renderRoot`

I want to get rid of the the `isSync` argument to `renderRoot`, and
instead use separate functions for concurrent and synchronous render.

As a first step, this extracts the push/pop logic that happens before
and after the render phase into helper functions.

* Extract `catch` block into helper function

Similar to previous commit. Extract error handling logic into
a separate function so it can be reused.

* Fork `renderRoot` for sync and concurrent

Removes `isSync` argument in favor of separate functions.

* Extra "root completion" logic to separate function

Moving this out to avoid an accidental early return, which would
bypass the call to `ensureRootIsScheduled` and freeze the UI.

* Inline `renderRoot`

Inlines `renderRoot` into `performConcurrentWorkOnRoot` and
`performSyncWorkOnRoot`. This lets me remove the `isSync` argument
and also get rid of a redundant try-catch wrapper.

* [suspense][error handling] Add failing unit test

Covers an edge case where an error is thrown inside the complete phase
of a component that is in the return path of a component that suspends.
The second error should also be handled (i.e. able to be captured by
an error boundary.

The test is currently failing because there's a call to
`completeUnitOfWork` inside the main render phase `catch` block. That
call is not itself wrapped in try-catch, so anything that throws is
treated as a fatal/unhandled error.

I believe this bug is only observable if something in the host config
throws; and, only in legacy mode, because in concurrent/batched mode,
`completeUnitOfWork` on fiber that throws follows the "unwind" path
only, not the "complete" path, and the "unwind" path does not call
any host config methods.

* [scheduler][profiler] Start time of delayed tasks

Fixes a bug in the Scheduler profiler where the start time of a delayed
tasks is always 0.

* Remove ad hoc `throw`

Fatal errors (errors that are not captured by an error boundary) are
currently rethrown from directly inside the render phase's `catch`
block. This is a refactor hazard because the code in this branch has
to mirror the code that happens at the end of the function, when exiting
the render phase in the normal case.

This commit moves the throw to the end, using a new root exit status.

* Handle errors that occur on unwind
2019-09-23 11:23:28 -07:00
Sebastian Markbåge
0a527707cd Event Replaying (#16725)
* Add Event Replaying Infra

* Wire up Roots and Suspense boundaries, to retry events, after they commit

* Replay discrete events in order in a separate scheduler callback

* Add continuous events

These events only replay their last target if the target is not yet
hydrated. That way we don't have to wait for a previously hovered
boundary before invoking the current target.

* Enable tests from before

These tests were written with replaying in mind and now we can properly
enable them.

* Unify replaying and dispatching

* Mark system flags as a replay and pass to legacy events

That way we can check if this is a replay and therefore needs a special
case. One such special case is "mouseover" where we check the
relatedTarget.

* Eagerly listen to all replayable events

To minimize breakages in a minor, I only do this for the new root APIs
since replaying only matters there anyway. Only if hydrating.

For Flare, I have to attach all active listeners since the current
system has one DOM listener for each. In a follow up I plan on optimizing
that by only attaching one if there's at least one active listener
which would allow us to start with only passive and then upgrade.

* Desperate attempt to save bytese

* Add test for mouseover replaying

We need to check if the "relatedTarget" is mounted due to how the old
event system dispatches from the "out" event.

* Fix for nested boundaries and suspense in root container

This is a follow up to #16673 which didn't have a test because it wasn't
observable yet. This shows that it had a bug.

* Rename RESPONDER_EVENT_SYSTEM to PLUGIN_EVENT_SYSTEM
2019-09-23 11:21:10 -07:00
Andrew Clark
a87d245fc2 [work loop] Prevent work loop from being inlined (#16865)
Uses Closure Compiler's `@noinline` directive.

See https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler#noinline
2019-09-23 11:12:47 -07:00
Nicolas Gallagher
312b462d54 [react-interactions] Improve consistency of Tap responder (#16837)
Makes sure that touch events with modifier keys behave the same way as other
pointer types (i.e., does not call `onTapStart` if the gesture begins with a
modifier key held down)
2019-09-23 10:48:11 -07:00
Dominic Gannaway
70754f10d4 [react-interaction] Tweak Focus Table component (#16862) 2019-09-23 16:39:43 +02:00
Dominic Gannaway
d7f6dd5a80 [react-interactions] Fix typo in FocusTable (#16860) 2019-09-23 14:20:43 +02:00
Dan Abramov
cef47cbc01 Rename experimental react-ui => react-interactions (#16842) 2019-09-20 11:51:03 +01:00
Dominic Gannaway
57a5805a9f [react-ui] Add preventDefault+stopPropagation to Keyboard + update Focus components (#16833) 2019-09-20 11:21:38 +02:00
Brian Vaughn
08b51aa384 Added React DevTools v4.1.0 release date to CHANGELOG 2019-09-19 15:22:22 -07:00
Brian Vaughn
b5cebedfbe React DevTools version bump 4.0.6 -> 4.1.0 2019-09-19 15:11:48 -07:00
Sebastian Markbåge
35bf9d27a3 Exclude react-dom when flow checking other builds (#16737)
This is because the HostConfig can't be guaranteed to be consistent with
other code such as code that touches the DOM directly.

Ideally we'd have a more systemic solution to this since it will pop
up for other packages later too.
2019-09-19 12:41:51 -07:00
Nicolas Gallagher
fd870e6b6a [react-ui/events] Tap responder API changes (#16827)
This patch limits the `onTap*` callbacks to the primary pointer button.
Auxiliary button and modified primary button interactions call
`onAuxiliaryTap`, cancel any active tap, and preserve the native behavior.
2019-09-19 09:36:29 -07:00
Dan Abramov
4ddcb8e134 [DevTools] Remove Welcome dialog (#16834) 2019-09-19 08:41:18 -07:00
Dominic Gannaway
924a305780 [react-ui] Remove event object warnings (#16822) 2019-09-19 12:46:17 +02:00
halvves
a5df18a9e5 prevent firefox marking required textareas invalid (#16578)
* prevent firefox marking required textareas invalid

Bug was caused by an IE10/IE11 bugfix dealing with the placeholder attribute and textContent. Solved by avoiding the IE bugfix when textContent was empty.

Closes #16402

* more explicit conditional check for textContent

re: @philipp-spiess code review

* clarify textarea test fixture's expected result

better describe the behavior we are testing for
re: @philipp-spiess code review
2019-09-18 14:38:02 -07:00
Dan Abramov
f818af9b03 [Fresh] Always remount classes (#16823) 2019-09-18 16:32:11 +01:00
Ricky
6ecfa90eb0 [React Native] Fix for view config registrations (#16821) 2019-09-18 15:31:00 +01:00
Dominic Gannaway
18cb59050b [react-core] Do not null fiber.sibling in detachFiber (#16820) 2019-09-18 14:18:32 +02:00
Kuba Juszczyk
d862f0ea56 Optimize objectIs (#16212) 2019-09-17 23:55:43 +02:00
Pavlo Tymchuk
d1c2555861 [react-devtools-shared] Added string type check for object name prop in getDisplayName function (#16798)
* [react-devtools-shared] Added string type check for object name prop in getDisplayName function from utils.js file; tests included;

* Re-added empty string check to getDisplayName()

* Tweaked tests to use real functions

This more closely simulates how the utility is being used in production, and would catch cases like anonymous functions (with empty string names).
2019-09-17 13:17:04 -07:00
Brian Vaughn
70dcdd265d Updated pending CHANGELOG for DevTools 2019-09-17 13:15:53 -07:00
Brian Vaughn
e8c7ddeef2 Release script filters DevTools NPM pakcages (#16810) 2019-09-17 12:46:13 -07:00
Dominic Gannaway
8f1533f4d8 [react-ui] Fix bundle name [hotfix] (#16811) 2019-09-17 21:10:51 +02:00
Dominic Gannaway
7c802de797 [react-a11y] Add react-ui/accessibility to bundle build (#16804) 2019-09-17 20:22:09 +02:00
Andrew Clark
901139c291 [scheduler][profiler] Start time of delayed tasks (#16809)
Fixes a bug in the Scheduler profiler where the start time of a delayed
tasks is always 0.
2019-09-17 10:24:48 -07:00
Dominic Gannaway
f40ceb0010 [react-ui] FocusGrid -> ReactFocusTable + tweaks and fixes (#16806) 2019-09-17 19:22:10 +02:00
Dominic Gannaway
2f1e8c5f78 [react-core] Clear more properties in detachFiber (#16807) 2019-09-17 17:30:22 +02:00
Dan Abramov
8e0c574122 Follow-up to initial Trusted Types support (#16795)
* Follow-up to initial Trusted Types support

* Fast-path both strings and numbers

* Move shared objects out of every test
2019-09-17 16:06:26 +01:00
Nicolas Gallagher
3af05de1aa [react-ui] usePress from useKeyboard and useTap (#16772)
This implements 'usePress' in user-space as a combination of 'useKeyboard' and 'useTap'.  The existing 'usePress' API is preserved for now. The previous 'usePress' implementation is moved to 'PressLegacy'.
2019-09-16 14:36:27 -07:00
Dominic Gannaway
494300b366 [react-ui] Move experimental event+a11y work to react-ui package (#16794) 2019-09-16 20:05:50 +02:00
Nicolas Gallagher
9691eb273a [react-events] Keyboard support for virtual clicks (#16780)
This accounts for all clicks that are natively dispatched following relevant
keyboard interactions (e.g., key is "Enter"), as well as programmatic clicks,
and screen-reader virtual clicks.
2019-09-16 10:40:05 -07:00
Emanuel Tesař
b8d079b413 Add trusted types to react on client side (#16157)
* Add trusted types to react on client side

* Implement changes according to review

* Remove support for trusted URLs, change TrustedTypes to trustedTypes

* Add support for deprecated trusted URLs

* Apply PR suggesstions

* Warn only once, remove forgotten check, put it behind a flag

* Move comment

* Fix PR comments

* Fix html toString concatenation

* Fix forgotten else branch

* Fix PR comments
2019-09-16 13:43:22 +01:00
Heaven
cdbfa5044b fix typo inteval -> interval & continutation -> continuation (#16760)
* fix typo alterate -> alternate

* fix typo interal -> interval & continutation -> continuation
2019-09-14 12:51:20 -07:00
Andrew Clark
45b6443c90 Spelling is fundamental (#16782) 2019-09-13 16:27:18 -07:00
Andrew Clark
45898d0be0 [Scheduler] Prevent event log from growing unbounded (#16781)
If a Scheduler profile runs without stopping, the event log will grow
unbounded. Eventually it will run out of memory and the VM will throw
an error.

To prevent this from happening, let's automatically stop the profiler
once the log exceeds a certain limit. We'll also print a warning with
advice to call `stopLoggingProfilingEvents` explicitly.
2019-09-13 15:50:25 -07:00
Nicolas Gallagher
87eaa90ef8 [react-events] Keyboard calls preventDefault on 'click' events (#16779)
Make sure to call preventDefault for any 'click' events that follow a 'keydown'
event that matches 'preventKeys'
2019-09-13 13:19:18 -07:00
Brian Vaughn
0c0b30b8c7 Remove unnecessary interaction tracing ping wrapper (#16777) 2019-09-13 11:04:36 -07:00
Andrew Clark
137ea783b1 Re-enable risky work loop changes (#16771)
The stack of PRs in #16743 was reverted. This adds them back.
2019-09-13 09:33:46 -07:00
Brian Vaughn
d6f6b951e1 Support disabling interaction tracing for suspense promises (#16776)
* Support disabling interaction tracing for suspense promises

If a thrown Promise has the __reactDoNotTraceInteractions attribute, React will not wrapped its callbacks to continue tracing any current interaction(s).

* Added optional '__reactDoNotTraceInteractions' attribute to Flow Thenable type
2019-09-13 08:59:57 -07:00
Dominic Gannaway
b4b8a349a3 [react-interactions] Add experimental FocusGrid API (#16766) 2019-09-13 12:29:39 +02:00
Andrew Clark
a7dabcb60a Revert "Re-arrange slightly to prevent refactor hazard (#16743)" (#16769)
This reverts commit ab4951fc03.

* Track "pending" and "suspended" ranges

A FiberRoot can have pending work at many distinct priorities. (Note: we
refer to these levels as "expiration times" to distinguish the concept
from Scheduler's notion of priority levels, which represent broad
categories of work. React expiration times are more granualar. They're
more like a concurrent thread ID, which also happens to correspond to a
moment on a timeline. It's an overloaded concept and I'm handwaving over
some of the details.)

Given a root, there's no convenient way to read all the pending levels
in the entire tree, i.e. there's no single queue-like structure that
tracks all the levels, because that granularity of information is not
needed by our algorithms. Instead we track the subset of information
that we actually need — most importantly, the highest priority level
that exists in the entire tree.

Aside from that, the other information we track includes the range of
pending levels that are known to be suspended, and therefore should not
be worked on.

This is a refactor of how that information is tracked, and what each
field represents:

- A *pending* level is work that is unfinished, or not yet committed.
  This includes work that is suspended from committing.
  `firstPendingTime` and `lastPendingTime` represent the range of
  pending work. (Previously, "pending" was the same as "not suspended.")
- A *suspended* level is work that did not complete because data was
  missing. `firstSuspendedTime` and `lastSuspendedTime` represent the
  range of suspended work. It is a subset of the pending range. (These
  fields are new to this commit.)
- `nextAfterSuspendedTime` represents the next known level that comes
  after the suspended range.

This commit doesn't change much in terms of observable behavior. The one
change is that, when a level is suspended, React will continue working
on the next known level instead of jumping straight to the last pending
level. Subsequent commits will use this new structure for a more
substantial refactor for how tasks are scheduled per root.

* Get next expiration time from FiberRoot

Given a FiberRoot, we should be able to determine the next expiration
time that needs to be worked on, taking into account the levels that
are pending, suspended, pinged, and so on.

This removes the `expirationTime` argument from
`scheduleCallbackForRoot`, and renames it to `ensureRootIsScheduled` to
reflect the new signature. The expiration time is instead read from the
root using a new function, `getNextExpirationTimeToWorkOn`.

The next step will be to remove the `expirationTime` argument from
`renderRoot`, too.

* Don't bind expiration time to render callback

This is a fragile pattern because there's only meant to be a single
task per root, running at a single expiration time. Instead of binding
the expiration time to the render task, or closing over it, we should
determine the correct expiration time to work on using fields we
store on the root object itself.

This removes the "return a continuation" pattern from the
`renderRoot` function. Continuation handling is now handled by
the wrapper function, which I've renamed from `runRootCallback` to
`performWorkOnRoot`. That function is merely an entry point to
`renderRoot`, so I've also removed the callback argument.

So to sum up, at at the beginning of each task, `performWorkOnRoot`
determines which expiration time to work on, then calls `renderRoot`.
And before exiting, it checks if it needs to schedule another task.

* Update error recovery test to match new semantics

* Remove `lastPendingTime` field

It's no longer used anywhere

* Restart on update to already suspended root

If the work-in-progress root already suspended with a delay, then the
current render definitely won't finish. We should interrupt the render
and switch to the incoming update.

* Restart on suspend if return path has an update

Similar to the previous commit, if we suspend with a delay, and
something in the return path has a pending update, we should abort
the current render and switch to the update instead.

* Track the next unprocessed level globally

Instead of backtracking the return path. The main advantage over the
backtracking approach is that we don't have to backtrack from the source
fiber. (The main disadvantages are that it requires another module-level
variable, and that it could include updates from unrelated
sibling paths.)

* Re-arrange slightly to prevent refactor hazard

It should not be possible to perform any work on a root without
calling `ensureRootIsScheduled` before exiting. Otherwise, we could
fail to schedule a callback for pending work and the app could freeze.

To help prevent a future refactor from introducing such a bug, this
change makes it so that `renderRoot` is always wrapped in try-finally,
and the `finally` block calls `ensureRootIsScheduled`.

* Remove recursive calls to `renderRoot`.

There are a few leftover cases where `renderRoot` is called recursively.
All of them are related to synchronously flushing work before its
expiration time.

We can remove these calls by tracking the last expired level on the
root, similar to what we do for other types of pending work, like pings.

* Remove argument from performSyncWorkOnRoot

Read the expiration time from the root, like we do
in performConcurrentWorkOnRoot.
2019-09-12 14:21:57 -07:00
Dominic Gannaway
4b0b556dcf [react-interactions] Refactor TabFocusController (#16768) 2019-09-12 22:28:07 +02:00
Brian Vaughn
fb39f62925 Added upcoming changes to DevTools CHANGELOG 2019-09-12 08:34:28 -07:00
Anton Korzunov
ba932a5ad9 fix: inspect ClassComponent.render instead of constructor, fixes #16749 (#16759) 2019-09-12 08:32:42 -07:00
Dominic Gannaway
35a202d0e7 [react-events] Ensure we restore currentInstance + currentTimers (#16758) 2019-09-12 12:44:05 +02:00
Dominic Gannaway
3717c25a7e [react-interactions] More Tab Focus control handling (#16751) 2019-09-11 22:35:33 +02:00
Andrew Clark
0a2215cc0e [Scheduler][www] Put profiling feature behind flag (#16757)
Our infra currently doesn't support loading a separate profiling
build of Scheduler. Until that's fixed, the recommendation is to load
a single build and gate the profiling feature behind a flag.

Alternative to #16659
2019-09-11 13:28:03 -07:00
Brian Vaughn
8f03109cd2 Moved backend injection to the content script (#16752)
* Moved backend injection logic to content script

* Moved backend injection logic to content script

* Moved injection logic to content script

* Formatting changes

* remove ability to inject arbitrary scripts

* Removed done(), added some comments explaining the change

* Lint fixes

* Moved inline comment.

* Deleted inject() script since it was no longer being used
2019-09-11 09:51:32 -07:00
Brian Vaughn
efa780d0ab Removed DT inject() script since it's no longer being used 2019-09-11 09:51:24 -07:00
Brian Vaughn
4290967d4c Merge branch 'tt-compat' of https://github.com/onionymous/react into onionymous-tt-compat 2019-09-11 09:34:31 -07:00
Brian Vaughn
f09854a9e8 Moved inline comment. 2019-09-11 09:30:57 -07:00
Stephanie Ding
776d1c69b9 Lint fixes 2019-09-11 08:11:14 -07:00
Dominic Gannaway
3a49dff386 [react-events] Use context.objectAssign in Tap responder (#16748) 2019-09-11 17:06:40 +02:00
Stephanie Ding
2e75000f40 Removed done(), added some comments explaining the change 2019-09-11 08:05:27 -07:00
Matt Kane
56114a4b22 Change trackedTouchCount console.error to warn (#16750) 2019-09-11 14:10:26 +02:00
Dominic Gannaway
ae724be7be [react-interactions] Add TabFocusContainer and TabbableScope UI components (#16732) 2019-09-11 12:46:41 +02:00
Andrew Clark
ab4951fc03 Re-arrange slightly to prevent refactor hazard (#16743)
* Track "pending" and "suspended" ranges

A FiberRoot can have pending work at many distinct priorities. (Note: we
refer to these levels as "expiration times" to distinguish the concept
from Scheduler's notion of priority levels, which represent broad
categories of work. React expiration times are more granualar. They're
more like a concurrent thread ID, which also happens to correspond to a
moment on a timeline. It's an overloaded concept and I'm handwaving over
some of the details.)

Given a root, there's no convenient way to read all the pending levels
in the entire tree, i.e. there's no single queue-like structure that
tracks all the levels, because that granularity of information is not
needed by our algorithms. Instead we track the subset of information
that we actually need — most importantly, the highest priority level
that exists in the entire tree.

Aside from that, the other information we track includes the range of
pending levels that are known to be suspended, and therefore should not
be worked on.

This is a refactor of how that information is tracked, and what each
field represents:

- A *pending* level is work that is unfinished, or not yet committed.
  This includes work that is suspended from committing.
  `firstPendingTime` and `lastPendingTime` represent the range of
  pending work. (Previously, "pending" was the same as "not suspended.")
- A *suspended* level is work that did not complete because data was
  missing. `firstSuspendedTime` and `lastSuspendedTime` represent the
  range of suspended work. It is a subset of the pending range. (These
  fields are new to this commit.)
- `nextAfterSuspendedTime` represents the next known level that comes
  after the suspended range.

This commit doesn't change much in terms of observable behavior. The one
change is that, when a level is suspended, React will continue working
on the next known level instead of jumping straight to the last pending
level. Subsequent commits will use this new structure for a more
substantial refactor for how tasks are scheduled per root.

* Get next expiration time from FiberRoot

Given a FiberRoot, we should be able to determine the next expiration
time that needs to be worked on, taking into account the levels that
are pending, suspended, pinged, and so on.

This removes the `expirationTime` argument from
`scheduleCallbackForRoot`, and renames it to `ensureRootIsScheduled` to
reflect the new signature. The expiration time is instead read from the
root using a new function, `getNextExpirationTimeToWorkOn`.

The next step will be to remove the `expirationTime` argument from
`renderRoot`, too.

* Don't bind expiration time to render callback

This is a fragile pattern because there's only meant to be a single
task per root, running at a single expiration time. Instead of binding
the expiration time to the render task, or closing over it, we should
determine the correct expiration time to work on using fields we
store on the root object itself.

This removes the "return a continuation" pattern from the
`renderRoot` function. Continuation handling is now handled by
the wrapper function, which I've renamed from `runRootCallback` to
`performWorkOnRoot`. That function is merely an entry point to
`renderRoot`, so I've also removed the callback argument.

So to sum up, at at the beginning of each task, `performWorkOnRoot`
determines which expiration time to work on, then calls `renderRoot`.
And before exiting, it checks if it needs to schedule another task.

* Update error recovery test to match new semantics

* Remove `lastPendingTime` field

It's no longer used anywhere

* Restart on update to already suspended root

If the work-in-progress root already suspended with a delay, then the
current render definitely won't finish. We should interrupt the render
and switch to the incoming update.

* Restart on suspend if return path has an update

Similar to the previous commit, if we suspend with a delay, and
something in the return path has a pending update, we should abort
the current render and switch to the update instead.

* Track the next unprocessed level globally

Instead of backtracking the return path. The main advantage over the
backtracking approach is that we don't have to backtrack from the source
fiber. (The main disadvantages are that it requires another module-level
variable, and that it could include updates from unrelated
sibling paths.)

* Re-arrange slightly to prevent refactor hazard

It should not be possible to perform any work on a root without
calling `ensureRootIsScheduled` before exiting. Otherwise, we could
fail to schedule a callback for pending work and the app could freeze.

To help prevent a future refactor from introducing such a bug, this
change makes it so that `renderRoot` is always wrapped in try-finally,
and the `finally` block calls `ensureRootIsScheduled`.

* Remove recursive calls to `renderRoot`.

There are a few leftover cases where `renderRoot` is called recursively.
All of them are related to synchronously flushing work before its
expiration time.

We can remove these calls by tracking the last expired level on the
root, similar to what we do for other types of pending work, like pings.

* Remove argument from performSyncWorkOnRoot

Read the expiration time from the root, like we do
in performConcurrentWorkOnRoot.
2019-09-10 20:07:12 -07:00
Sebastian Markbåge
b0a8a3e041 Mark root as already hydrated after committing (#16739)
* Mark root as already hydrated after committing

* Remove current/child check for hydration and rely on the root flag instead
2019-09-10 20:02:02 -07:00
Sebastian Markbåge
e04f4259c4 Handle SuspenseListComponent getting retried (#16745)
This happens for example when a deleted boundary transfers its pending
promises to the list so that the list can be retried.

This wasn't caught by unit tests because this flag wasn't on in those
tests.
2019-09-10 19:38:44 -07:00
Stephanie Ding
8a6cd3cd12 remove ability to inject arbitrary scripts 2019-09-10 18:06:23 -07:00
Stephanie Ding
d51f062d03 Formatting changes 2019-09-10 17:46:29 -07:00
Stephanie Ding
85c7211014 Moved injection logic to content script 2019-09-10 17:45:27 -07:00
Stephanie Ding
788036c7ed Moved backend injection logic to content script 2019-09-10 17:34:12 -07:00
Stephanie Ding
c93038fabe Moved backend injection logic to content script 2019-09-10 17:22:04 -07:00
Brian Vaughn
2c98af77c3 DevTools: Props editing interface tweaks (#16740)
* Fix DevTools new prop input size
* Don't allow adding new values unless an overridePropsFn function has been provided.
* Do not show empty 'none' label ablve a new prop input
2019-09-10 14:57:33 -07:00
Brian Vaughn
2ce5801c25 Added upcoming changes to DevTools CHANGELOG 2019-09-10 13:32:53 -07:00
Hristo Kanchev
709baf1fec [DevTools] Support for adding props | Improved state/props value editing (#16700)
* Extracted sanitizeForParse

* Added canAddEntries flag to InspectedElementTree

* Added EditableKey component.

* Added support to add an additional entry.

* Added support to add more complex data structures in the EditableValue component. Added support to change the dataType of the value that is being changed.

* Fixed flow error.

* Removed unneeded fragment.

* Renamed EditableKey -> EditableName

* Removed unneeded dependency

* Removed problematic props to state hook.

* Prettified changes.

* Removed unused import.

* Fixed shouldStringify check.

* Removed testing props from EditableProps.

* Made some inline tweaks
2019-09-10 13:30:43 -07:00
Hristo Kanchev
4ef6387d6e [DevTools] [Context] Legacy Context (#16617)
* Added hasLegacyContext check.

* Passed hasLegacyContext as prop to SelectedElement

* Changing context labels based on hasLegacyContext

* Fixed flow types.

* Fixed typos.

* Added tests for hasLegacyContext.

* Renamed test.

* Removed test imports.
2019-09-10 13:30:20 -07:00
Liad Yosef
c317fc273b Correct link for troubleshooting react-dev-tools (#16690) (#16708)
* Correct link for troubleshooting react-dev-tools (#16690)

As pointed out in #16690 - the link for 'React Tab Doesn't Show Up' points to the empty README.MD.
This points it to that section in the v3 version README.MD - until an updated section will be added to the new dev-tools.

* Add a "The React Tab Doesn't Show Up" section

Add the troubleshooting section to the react dev tools readme

* point to the correct section in react-dev-tools readme

After adding the troubleshooting section to the readme - this will point to the correct place

* Moved README file to GitHub

* Update new issue link to include DevTools label
2019-09-10 13:14:19 -07:00
Nicolas Gallagher
41a78cd85c [react-events] Tap: add maximumDistance prop (#16689)
A prop for configuring the maximum distance that the active pointer can move before the tap is cancelled.
2019-09-10 12:52:43 -07:00
Dan Abramov
2400400788 react-refresh@0.4.2 2019-09-10 20:46:34 +01:00
Dan Abramov
ba6bb0fccf [Fresh] Hash signatures (#16738) 2019-09-10 20:28:13 +01:00
Dominic Gannaway
fd3e8cb0ae [react-events] Remove stopPropagation (Press) + use document for delegation (#16730) 2019-09-10 20:31:24 +02:00
Heaven
38c03ce006 Fix typo in commet (#16727) 2019-09-10 10:27:38 -07:00
Hristo Kanchev
4905590e1e Fixed font family issue in FF. (#16701) 2019-09-09 16:21:04 -07:00
Daniel Lo Nigro
35f447ddbf Remove console.log from copyWithSet (#16716) 2019-09-09 16:18:09 -07:00
Sebastian Markbåge
440cbf2ee5 Let's schedule the passive effects even earlier (#16714)
It turns out I needed to schedule mine in the mutation phase and there
are also clean up life-cycles there.
2019-09-09 15:06:03 -07:00
Sebastian Markbåge
cc2492ccf1 Schedule passive callbacks before layout effects are invoked (#16713) 2019-09-09 13:34:57 -07:00
Nicolas Gallagher
031eba789f [react-events] Tap: change order of events (#16694)
Before:

start -> change -> update -> end (cancel) -> change

Now:

start -> change -> update -> change -> end (cancel)
2019-09-09 09:08:17 -07:00
Nicolas Gallagher
f26fe8c0a7 [react-events] Keyboard: fix callback return types (#16693) 2019-09-09 09:07:42 -07:00
Heaven
9444c876d5 Remove wrong copy-paste code in test (#16695) 2019-09-09 11:34:08 +01:00
Dan Abramov
b260bef398 [Fresh] Add skipEnvCheck option to Babel plugin (#16688) 2019-09-06 20:30:16 +01:00
Dan Abramov
2f15881859 react-refresh@0.4.1 2019-09-06 20:02:43 +01:00
Dan Abramov
9044bb0fa3 [Fresh] Fix a crash with implicit arrow return (#16687) 2019-09-06 19:58:07 +01:00
Dan Abramov
21d79ce040 Add FreshRuntime WWW bundle, remove ESLint (#16684) 2019-09-06 16:48:07 +01:00
Alex Rohleder
206d61f722 fix typos on react-devtools comments (#16681) 2019-09-06 07:47:44 -07:00
Heaven
61836fba2a Fix typo: wnless -> unless (#16680) 2019-09-06 07:47:35 -07:00
Sebastian Markbåge
e11bf42cea Check for Suspense boundary in a root Container (#16673)
If we find a Container that might mean that we're on a node that is inside
a Suspense boundary that is directly inside the Container root.

Imagine the div is a Container and the span is a dehydrated instance:

```
<div>
  <!--$-->
  <span />
  <!--/$-->
</div>
```

There's no way to tests this yet since I'm not actually utilizing
the return value yet.

The solution is to just use the same path to check for a Suspense boundary
as if we find a parent instance.
2019-09-05 16:06:05 -07:00
Dan Abramov
962dfc2c33 Remove experimental scheduler flags (#16672) 2019-09-05 20:08:06 +01:00
Nicolas Gallagher
ff006451ad [react-events] Fix isTargetWithinNode type (#16671)
isTargetWithinNode passes the childTarget to getClosestInstanceFromNode which
does not account for a null value of 'node'.
2019-09-05 11:36:31 -07:00
Dan Abramov
040ca0fad7 Enable MessageLoop implementation by default (#16408) 2019-09-05 19:25:51 +01:00
Brian Vaughn
d96f478f8a use-subscription tearing fix (#16623)
* Add (failing) subscription tearing test and bugfix
* Added more inline comments to test
* Simplified tearing test case slightly
2019-09-05 11:12:46 -07:00
Luna Ruan
79e46b6778 updated flags from false to dicated on www (#16647) 2019-09-05 09:51:44 -07:00
Sebastian Markbåge
8d7c733f1f [Partial Hydration] Don't invoke listeners on parent of dehydrated event target (#16591)
* Don't invoke listeners on parent of dehydrated event target

* Move Suspense boundary check to getClosestInstanceFromNode

Now getClosestInstanceFromNode can return either a host component,
host text component or suspense component when the suspense
component is dehydrated.

We then use that to ignore events on a suspense component.

* Attach the HostRoot fiber to the DOM container

This lets us detect if an event happens on this root's subtree before it
has rendered something.

* Add todo

The approach of checking isFiberMounted answers if we might be in an
in-progress hydration but it doesn't answer which root or boundary
might be in-progress so we don't know what to wait for.

This needs some refactoring.

* Refactor isFiberMountedImpl to getNearestMountedFiber

We'll need the nearest boundary for event replaying so this prepares for
that.

This surfaced an issue that we attach Hydrating tag on the root but normally
this (and Placement) is attached on the child. This surfaced an issue
that this can lead to both Placement and Hydrating effects which is not
supported so we need to ensure that we only ever use one or the other.

* Add todo for bug I spotted

* Cache tags

* Check the ContainerInstanceKey before the InstanceKey

The container is inside the instance, so we must find it before the
instance, since otherwise we'll miss it.
2019-09-05 08:51:31 -07:00
Nicolas Gallagher
9ce8711d5a [react-events] Tap responder (#16628)
This is a partial replacement for the 'Press' responder:

1. `useTap` is scoped to pointers (no keyboard support). Our current thinking is
that "responders" should be limited to working with pointers, and that they can
be combined with 'useKeyboard' in user-space. For example, we might create a
'usePress' hook in user-space that combines 'useTap' with 'useKeyboard' to react
to both pointers and keyboard interactions.

2. `useTap` cancels the gesture once the pointer moves over an element that is
not within the responder target's subtree. This differs from `usePress` (and
React Native), where the gesture remains active after the pointer exits the
target's subtree and is restarted once the pointer reenters. One of the
drawbacks with the `usePress` behavior is that it requires repeatedly measuring
DOM elements (which can cause jank) to perform hit region tests. `useTap` avoids
doing this and relies on `document.elementFromPoint` only to support the
TouchEvent fallbacks.

3. `useTap` calls `onTapUpdate` when the active gesture's state changes,
`onTapEnd` when the gesture successfully completes. and `onTapCancel` when it
fails. There is no `onTap` callback. `usePress` did not explicitly report back
when the gesture failed, and product developers were confused about the
difference between `onPress` and `onPressEnd`.

4. `useTap` explicitly separates the PointerEvent implementation from the
MouseEvent/TouchEvent fallback.

5. `useTap` has better unit test coverage . All pointer types and the fallback
environment are tested. The shape of the gesture state object is also defined
and tested.
2019-09-04 17:09:33 -07:00
Dominic Gannaway
e86146e714 [react-events] Refine executeUserEventHandler (#16662) 2019-09-05 00:36:29 +01:00
Dominic Gannaway
c66edb9f8b [react-events] Refactor getCurrentTarget to getResponderNode (#16660) 2019-09-04 20:04:35 +01:00
Dominic Gannaway
9ff60ff16b [react-events] Fix Scope listener issue (#16658) 2019-09-04 18:57:39 +01:00
Dominic Gannaway
7126a37bf4 [react-events] Keyboard responder propagation handling (#16657) 2019-09-04 18:25:05 +01:00
Dominic Gannaway
539640d89f [react-events] Various core tweaks for event responder system (#16654) 2019-09-04 18:05:56 +01:00
Dominic Gannaway
af032764a9 [react-events] Adds preventKeys support to Keyboard responder (#16642) 2019-09-04 01:38:36 +01:00
Brian Vaughn
f705e2bac7 Updated pending CHANGELOG for DevTools 2019-09-03 08:37:12 -07:00
Hristo Kanchev
77bb102398 [DevTools] [Profiler]: Save profile now working in Firefox (#16612)
* Added anchor dom element in order to successfully download profiling data.
* Reworked downloadFile to accept a DOMElement in order for FF to successfully download profiling data.
* Prettify downloadFile changes.
2019-09-03 08:35:12 -07:00
Heaven
92f094d86d fix typo: oncurrent - concurrent (#16633) 2019-09-02 11:21:48 +01:00
Dominic Gannaway
46f912fd57 [react-core] Add more support for experimental React Scope API (#16621) 2019-08-30 18:27:14 +01:00
Paul O’Shannessy
2c1e6bf619 Adopt Contributor Covenant (#16613)
In order to foster healthy open source communities, we're adopting the
[Contributor Covenant](https://www.contributor-covenant.org/). It has been
built by open source community members and represents a shared understanding of
what is expected from a healthy community.
2019-08-29 16:04:47 -07:00
Brian Vaughn
f962feb882 Updated extensions build-from-source instructions in README 2019-08-29 08:49:08 -07:00
Simen Bekkhus
ac6193687f add integrity field in yarn.lock (#16601) 2019-08-29 16:36:02 +01:00
Sebastian Silbermann
16329bd954 chore: Update nvmrc with latest lts (#16610) 2019-08-29 16:30:35 +01:00
Dominic Gannaway
4e544cffee [react-events] Split out mixed event responder tests (#16608) 2019-08-29 16:13:37 +01:00
Gerald Monaco
f61138e068 Use renderToStaticMarkup for tests (#16516) 2019-08-29 16:08:38 +01:00
James George
980112b146 rephrase comment (#16559) 2019-08-29 14:51:07 +01:00
Bas Peeters
8a7c2e50f1 Remove duplicate character in regex group (#16572) 2019-08-29 14:49:27 +01:00
Tom Quirk
557d472fe3 add <thead>, <tfoot> to table > tr warning (#16535) 2019-08-29 14:46:27 +01:00
Simen Bekkhus
37fcd04681 chore: upgrade to danger 9 (#16602) 2019-08-29 13:46:53 +01:00
Dominic Gannaway
bd79be9b68 [react-core] Add experimental React Scope component API (#16587) 2019-08-29 12:06:51 +01:00
Brian Vaughn
996acf9036 Updated DevTools extension build script to work when run remotely (#16603) 2019-08-28 17:01:26 -07:00
Dominic Gannaway
34aaec6f90 [react-events] Ensure screen reader virtual clicks support preventDefault (#16600) 2019-08-28 17:39:07 +01:00
Dan Abramov
01fb68b9bf Don't ignore dependencies for render phase update (#16574) 2019-08-28 16:55:56 +01:00
LEE SUK JAE
1b585f630b Fix link on error-codes/README.md (#16595) 2019-08-28 15:49:45 +01:00
Brian Vaughn
0f3e82f3c4 Merge branch 'devtools-v4-merge' 2019-08-28 07:39:49 -07:00
Brian Vaughn
b8390310b1 Revert "Import React DevTools v4"
This reverts commit b438699d36.
2019-08-28 07:39:32 -07:00
Brian Vaughn
b438699d36 Import React DevTools v4
Imports the entire React DevTools v4 git repository (with history).
2019-08-28 07:35:53 -07:00
Brian Vaughn
ada5991422 Removed an unnecessary/unused DT Flow type 2019-08-28 07:28:06 -07:00
Brian Vaughn
08ce280cbc Updated DT regression fixture path 2019-08-28 07:25:52 -07:00
Brian Vaughn
b034ac6d38 Merge branch 'master' into devtools-v4-merge 2019-08-28 07:13:49 -07:00
Luna Ruan
f512537754 Babel Transform JSX to React.jsx/React.jsxDEV Plugin (#16432)
This babel transform is a fork of the @babel/plugin-transform-react-jsx transform and is for experimentation purposes only. We don't plan to own this code in the future, and we will upstream this to Babel at some point once we've proven out the concept.

As per the RFC to simplify element creation, we want to change the JSX transform from targeting React.createElement(type, props, children) to React.jsx(type, props, key). This modifies the existing @babel/plugin-transform-react-jsx (and helper) babel plugin to support React.jsx and React.jsxDEV.

The main differences between React.jsx/React.jsxDEV and React.createElement are:
1.) key is now passed as an explicit argument rather than through props
3.) children are now passed through props rather than as an explicit argument
4.) props must always be an object
5.) __source and and __self are now passed as separate arguments into React.jsxDEV rather than through props

Part of the rationale for this change is that we want to deprecate key spread through props because this is an expensive dynamic comparison operation. We want users instead always explicitly pass key as a prop. However, in the interim, we need a way to distinguish between <div {...props} key={foo} /> and <div key={foo} {...props} />. Therefore, until we completely deprecate key spreading, we will use React.createElement to transform <div {...props} key="Hi" /> and React.jsx to transform everything else.
2019-08-27 16:00:20 -07:00
Nicolas Gallagher
cb15f18dc1 [react-events] Improve mock event object accuracy (#16590)
* Better simulation for pointercancel
* Fix pressure values for different pointers
* Add describe/test helpers for pointer events
2019-08-27 15:45:54 -07:00
Brian Vaughn
bc8b15332b Updated README docs, example screenshots, etc 2019-08-27 15:20:34 -07:00
Brian Vaughn
7153dd516f Fixed a StyleEditor variable resolution regression 2019-08-27 12:53:38 -07:00
Brian Vaughn
33d439f8fd Merge branch 'master' into devtools-v4-merge 2019-08-27 11:00:41 -07:00
Brian Vaughn
fb316787cb Removed unused Chrome Flow types 2019-08-27 10:54:21 -07:00
Brian Vaughn
8e1434e80e Added FB copyright header 2019-08-27 10:54:01 -07:00
Brian Vaughn
49b0f87d10 Suppress act/renderer warning for DevTools tests 2019-08-27 10:46:27 -07:00
Brian Vaughn
8c684bf7e1 Removed forked DevTools Flow types 2019-08-27 10:42:02 -07:00
Brian Vaughn
9a016c0c2b Removed outdated snapshot 2019-08-27 10:31:36 -07:00
Brian Vaughn
f55b4f8e28 CI runs DevTools tests against built source 2019-08-27 10:28:58 -07:00
Dominic Gannaway
4ef269606c [react-events] Support screen reader virtual clicks (#16584) 2019-08-27 17:32:50 +01:00
Brian Vaughn
892ca8137e Disabled DevTools tests from yarn-build target 2019-08-27 09:08:49 -07:00
Brian Vaughn
896c993ada Fixed remaining DevTools broken tests by fixing a hydration/spread bug 2019-08-27 08:50:36 -07:00
Brian Vaughn
e3cc42be97 Fix Console patching test by resetting modules 2019-08-26 13:53:29 -07:00
Brian Vaughn
177f357d9d Updated DevTools test setup to no longer mock test renerer 2019-08-26 13:46:00 -07:00
Brian Vaughn
a48593a8d3 Iterating on DevTools tests: Trying to run tests against pre-build react-dom and react-test-renderers 2019-08-26 13:43:09 -07:00
Brian Vaughn
ee4806f47a Fixed flushing problem with tests 2019-08-26 13:08:35 -07:00
Brian Vaughn
9d4fd7a249 Merged changes from 4.0.5 -> 4.0.6 from DevTools fork 2019-08-26 10:12:18 -07:00
Brian Vaughn
4c1514495b Merge branch 'source' of github.com:bvaughn/react-devtools-experimental 2019-08-26 10:06:00 -07:00
Brian Vaughn
13a93e7b82 Configured CI to run DevTools tests. Updated other test configs not to include DevTools tests. 2019-08-26 09:58:28 -07:00
Brian Vaughn
c00a920640 Merge branch 'master' into devtools-v4-merge 2019-08-26 09:42:25 -07:00
Brian Vaughn
0da7bd0604 React DevTools CHANGELOG entry for 4.0.6 2019-08-26 09:34:06 -07:00
Brian Vaughn
a39d9c3dff 4.0.5 -> 4.0.6 2019-08-26 08:42:38 -07:00
Brian Vaughn
1e3b0b520e Added a null check around memoizedProps 2019-08-24 09:04:26 -07:00
Brian Vaughn
84b492f344 Polyfill Symbol usage 2019-08-23 17:38:45 -06:00
Dominic Gannaway
fc80772078 [react-events] Ensure updateEventListeners updates in commit phase (#16540) 2019-08-22 23:58:16 +01:00
Dan Abramov
0f6e3cd61c [Scheduler] Profiler Features (second try) (#16542)
* Revert "Revert "[Scheduler] Profiling features (#16145)" (#16392)"

This reverts commit 4ba1412305.

* Fix copy paste mistake

* Remove init path dependency on ArrayBuffer

* Add a regression test for cancelling multiple tasks

* Prevent deopt from adding isQueued later

* Remove pop() calls that were added for profiling

* Verify that Suspend/Unsuspend events match up in tests

This currently breaks tests.

* Treat Suspend and Resume as exiting and entering work loop

Their definitions used to be more fuzzy. For example, Suspend didn't always fire on exit, and sometimes fired when we did _not_ exit (such as at task enqueue).

I chatted to Boone, and he's saying treating Suspend and Resume as strictly exiting and entering the loop is fine for their use case.

* Revert "Prevent deopt from adding isQueued later"

This reverts commit 9c30b0b695d81e9c43b296ab93d895e4416ef713.

Unnecessary because GCC

* Start counter with 1

* Group exports into unstable_Profiling namespace

* No catch in PROD codepath

* No label TODO

* No null checks
2019-08-22 13:58:12 -07:00
Nicolas Gallagher
474b650cac [react-events] Rename hook exports (#16533)
For example, 'useHoverResponder' becomes 'useHover'
2019-08-22 13:30:35 -07:00
Nicolas Gallagher
2f03aa6eed [react-events] Fix middle-click for Press (#16546)
Browsers always report 'buttons' as 0 when a pointer is released.
2019-08-22 10:22:14 -07:00
Bruno Scopelliti
16c3408638 Only warn in case the fourth argument is a function (#16543) 2019-08-22 17:31:27 +01:00
Sebastian Markbåge
05f5192e81 [Partial Hydration] Dispatching events should not work until hydration commits (#16532)
* Refactor a bit to use less property access

* Add test for invoking an event before mount

* Add Hydration effect tag

This is equivalent to a "Placement" effect in that it's a new insertion
to the tree but it doesn't need an actual mutation.

It is only used to determine if a subtree has actually mounted yet.

* Use the Hydration flag for Roots

Previous roots had a Placement flag on them as a hack for this case but
since we have a special flag for it now, we can just use that.

* Add Flare test
2019-08-22 08:46:20 -07:00
Brian Vaughn
bf9415834f Fixed outdated extension popup wording 2019-08-21 14:28:57 -07:00
Brian Vaughn
6dda816102 Remove emoji prefix from Firefox extension tab labels
Firefox adds these already for React, so the extra emoji character was confusing. For now, we still prepend it for Chrome
2019-08-21 14:23:51 -07:00
Brian Vaughn
79bda69d88 Renamed DevTools Jest config to be more concistent with others 2019-08-21 13:40:24 -07:00
Dan Abramov
8a01b50fc3 eslint-plugin-react-hooks@2.0.1 2019-08-21 21:40:20 +01:00
Dan Abramov
3ed289b3b1 Clear canceled task node early (#16403) 2019-08-21 19:49:22 +01:00
Dan Abramov
0672829053 Bump ESLint plugin to 2.0 (#16528) 2019-08-21 19:14:34 +01:00
Nicolas Gallagher
2559111c21 [react-events] Rely on 'buttons' rather than 'button' (#16479)
The semantics of 'button' on events differs between PointerEvent and
MouseEvent, whereas they are the same for 'buttons'. Furthermore, 'buttons'
allows developers to determine when multiple buttons are pressed as the same
time.

https://w3c.github.io/pointerevents/#the-button-property
2019-08-21 10:07:15 -07:00
Dan Abramov
c433fbb593 Revert "Revert "[ESLint] Forbid top-level use*() calls (#16455)"" (#16525)
* Revert "Revert "[ESLint] Forbid top-level use*() calls (#16455)" (#16522)"

This reverts commit 507f0fb372.

* Update RulesOfHooks.js
2019-08-21 15:43:31 +01:00
Brian Vaughn
66c9fedc34 Flow fixes 2019-08-20 13:33:33 -07:00
Brian Vaughn
fe943c339d Add custom DevTools Flow definitions to shared flowconfig 2019-08-20 11:37:45 -07:00
Brian Vaughn
2e549efae5 Moved DevTools custom Flow definitions 2019-08-20 11:37:31 -07:00
Brian Vaughn
4da836af71 Merged changes from 4.0.0 -> 4.0.5 from DevTools fork 2019-08-20 11:34:51 -07:00
Brian Vaughn
3ad50710a7 Merge branch 'source' of github.com:bvaughn/react-devtools-experimental 2019-08-20 11:00:02 -07:00
Brian Vaughn
833f206348 Merge branch 'master' into devtools-v4-merge 2019-08-20 10:41:38 -07:00
Brian Vaughn
2843a1556e Fixed invalid object-assign version (4.0.4 -> 4.0.1) 2019-08-20 09:45:09 -07:00
Brian Vaughn
aa56fe34ac Improved GitHub issue repro instructions prompt 2019-08-20 09:44:41 -07:00
Brian Vaughn
5441b094a4 4.0.4 -> 4.0.5 2019-08-19 09:26:55 -07:00
Brian Vaughn
01b1e7e2cf Alpha-sort props/state/context keys 2019-08-19 09:17:52 -07:00
Brian Vaughn
d2456c7572 Fixed standalone target not properly serving backend over localhost:8097 2019-08-19 07:36:41 -07:00
Brian Vaughn
14c2eab7c3 Resolved Yarn conflict for object-assign 2019-08-19 07:04:47 -07:00
Brian Vaughn
3c6a219466 4.0.3 -> 4.0.4 2019-08-18 08:45:52 -07:00
Brian Vaughn
4697f5b379 Profiler bugfix for filtering out all commits after selecting a fiber 2019-08-18 08:34:40 -07:00
Brian Vaughn
95ca079556 Fixed standalone bug that prevented backend from being served over localhost:8097 2019-08-17 21:11:10 -07:00
Brian Vaughn
95ffd3ccf8 4.0.2 -> 4.0.3 2019-08-17 11:31:31 -07:00
Brian Vaughn
2935d6a18d Unserializable data type fix for standalone shell 2019-08-17 11:31:20 -07:00
Brian Vaughn
ce65df7092 Added support for unserializable types (e.g. Set/Map, Immutable) 2019-08-17 10:20:26 -07:00
Brian Vaughn
f66a20f439 Caps lock bug template request for repro steps :) 2019-08-16 14:47:55 -07:00
Brian Vaughn
69b2ecc531 Added explicit (empty) label next to empty arrays and objects 2019-08-16 13:47:09 -07:00
Brian Vaughn
024bac4263 Support single-quote strings in style editor 2019-08-16 13:35:30 -07:00
Brian Vaughn
74f4a3f972 Improved editing props demo experience for TODO list 2019-08-16 13:15:16 -07:00
Brian Vaughn
f616613059 Display hook values for components that only use context 2019-08-16 11:33:28 -07:00
Brian Vaughn
454157dd66 Multi-renderer profiling improvements
Add support for mixed v15/v16 renderers that previously caused profiling to fail with 'profiling not supported by this renderer' type errors
2019-08-16 11:25:44 -07:00
Brian Vaughn
49399aa3e7 Prettier 2019-08-16 09:05:26 -07:00
Brian Vaughn
5e043adba7 Added Set+Map to dev shell, even though we don't support deep inspecting them yet 2019-08-16 09:05:21 -07:00
Brian Vaughn
2bcc6c6d04 4.0.1 -> 4.0.2 2019-08-15 17:35:30 -07:00
Brian Vaughn
527fc4a63f Refactored to remove need for new webNavigation permission 2019-08-15 17:34:34 -07:00
Brian Vaughn
c100cc7b31 4.0.0 -> 4.0.1 2019-08-15 16:29:13 -07:00
Brian Vaughn
545de6f02e Removed some unnecessary manifest permissions 2019-08-15 16:28:10 -07:00
Brian Vaughn
d0dcbe5594 Changed version name string to show version and date. Moved commit number into description string. 2019-08-15 14:38:16 -07:00
Brian Vaughn
0763c48ed8 Bumped all versions to 4.0.0 2019-08-15 14:28:09 -07:00
Brian Vaughn
732f3a6ef1 4.0.0-alpha.9 -> 4.0.0-alpha.10 2019-08-15 11:26:04 -07:00
Brian Vaughn
db9e5c9715 Updated all GitHub links to point to React repo 2019-08-15 11:17:59 -07:00
Brian Vaughn
85fbe3be3f Merge branch 'master' into devtools-v4-merge 2019-08-15 10:14:34 -07:00
Brian Vaughn
7ce229d3b0 Made some incremental progress on Jest tests 2019-08-15 09:53:22 -07:00
Brian Vaughn
4c4f5fd27f Disable @babel/plugin-transform-block-scoping "throwIfClosureRequired" option for tests 2019-08-14 19:04:43 -07:00
Brian Vaughn
41db902ed4 Removed unused __TEST__ files 2019-08-14 19:03:32 -07:00
Brian Vaughn
a6aba5a587 Add explicit MIT license file (previously only in package.json) 2019-08-14 17:04:05 -07:00
Brian Vaughn
9ec9938ff4 print-warnings script should ignore DevTools packages 2019-08-14 14:02:12 -07:00
Brian Vaughn
a473dca59e Merge branch 'master' into devtools-v4-merge 2019-08-14 14:01:46 -07:00
Brian Vaughn
4078167255 Removed (no longer necessary) node->node-events mapping 2019-08-14 11:43:59 -07:00
Brian Vaughn
d7ca8847f5 Add build-info.json to package files array for non-private DT packages 2019-08-14 11:40:09 -07:00
Brian Vaughn
39209dc5b5 Update react-devtools-inline to embed react-debug-tools since it's not published yet 2019-08-14 11:37:48 -07:00
Brian Vaughn
45dff31a75 Patched up react-devtools-core Webpack configs 2019-08-14 11:22:28 -07:00
Brian Vaughn
58b39c60db Fixed web extensions 2019-08-14 10:33:33 -07:00
Brian Vaughn
30b8ef3756 Iterated on Webpack configs until I got the inline and shell packages seemingly working 2019-08-14 09:24:35 -07:00
Brian Vaughn
44e410900d Merged master (with events -> legacy-events package rename) 2019-08-14 07:35:49 -07:00
Brian Vaughn
441d014cef Cleaned up some extnesions build script stuff 2019-08-13 22:15:38 -07:00
Brian Vaughn
380da5fccc Moved OVERVIEW 2019-08-13 22:09:20 -07:00
Brian Vaughn
b73e293cc5 Moved CHANGELOG 2019-08-13 22:05:45 -07:00
Brian Vaughn
ac2e861fbe Fixed a bunch of Lint issues 2019-08-13 21:59:07 -07:00
Brian Vaughn
51626ae2f9 Prettier 2019-08-13 18:12:19 -07:00
Brian Vaughn
f7afe1b864 Moved shell fixture into packages/react-devtools-shell 2019-08-13 18:11:59 -07:00
Brian Vaughn
183f96f2ac Prettier 2019-08-13 17:58:03 -07:00
Brian Vaughn
edc46d7be7 Misc Flow and import fixes
1. Fixed all reported Flow errors
2. Added a few missing package declarations
3. Deleted ReactDebugHooks fork in favor of react-debug-tools
2019-08-13 17:53:28 -07:00
Brian Vaughn
08743b1a8e Reorganized folders into packages/* 2019-08-13 15:59:43 -07:00
Brian Vaughn
ec7ef50e8b Reorganized things again into packages 2019-08-13 11:37:25 -07:00
Brian Vaughn
7cabb3946e Reorganized fixtures 2019-08-13 11:11:25 -07:00
Brian Vaughn
c8922c3dbf Updated yarn.lock file 2019-08-13 11:08:40 -07:00
Brian Vaughn
9c825b59f1 Moved dev shell into fixtures/devtools 2019-08-13 11:05:37 -07:00
Brian Vaughn
65b93cd165 Merge remote-tracking branch 'devtools-merge/master' into devtools-v4-merge 2019-08-13 10:46:18 -07:00
Brian Vaughn
56b1c20cf0 Reorganized to avoid merge conflicts with React repo folder structure 2019-08-13 10:33:56 -07:00
Brian Vaughn
e3ac9d219d Merging DevTools fork 2019-08-13 10:10:41 -07:00
Brian Vaughn
848327760f Initializing empty merge repo 2019-08-13 10:09:17 -07:00
Brian Vaughn
6eb04b2b16 4.0.0-alpha.8 -> 4.0.0-alpha.9 2019-08-12 11:34:00 -07:00
Brian Vaughn
2f1c100e7c Misc. Profiler tweaks
* Disabled (with a follow up TODO) the  call in the reload-and-profile toggle.
* Disabled reload-and-profile in Firefox extension for now, since it was triggering a disconnected port error.
* Fixed Safari layout bug that caused profiler charts to be hidden.
2019-08-12 11:13:38 -07:00
Brian Vaughn
8fa608d9ab Fixed a selection-sync edge case for Elements/Components tabs 2019-08-12 10:31:50 -07:00
Brian Vaughn
8001b6432c Fixed raw-loader + Jest problem 2019-08-12 08:49:26 -07:00
Brian Vaughn
b5195a5f16 Fixed a couple of edge case styling and layout issues I noticed while testing the inline target 2019-08-12 08:26:48 -07:00
Brian Vaughn
2eb3f4e9b8 README typofix 2019-08-06 10:45:16 -07:00
Brian Vaughn
2015a39c2e 4.0.0-alpha.7 -> 4.0.0-alpha.8 2019-08-06 10:22:12 -07:00
Brian Vaughn
e015e3d937 Added not about sync/batched root API being required 2019-08-06 08:57:34 -07:00
Brian Vaughn
2349f04478 Handle case where :root styles aren't (yet) applied when SettingsContext mounts
This fixes a possible bug in the inline shell where line-heights are NaN so the Tree (react-window List) gets created with a itemSize of NaN
2019-08-06 08:46:42 -07:00
Brian Vaughn
baac1dcc52 Inline package tweaks:
* Ignore messages from the DevTools browser extension.
* Cleanup/clarify README
2019-08-05 14:00:18 -07:00
Brian Vaughn
dc8580e64d New NPM package react-devtools-inline (#363) 2019-08-05 10:09:26 -07:00
Sam Horton
6f1e283b76 feat: match HOC display names during search (#360)
* feat: match HOC display names during search

* chore: update tests for new search logic
2019-08-05 09:44:48 -07:00
Brian Vaughn
6b3ae64598 Suppress known/expected warnings and errors in local DEV shell 2019-08-04 14:33:38 -07:00
Brian Vaughn
db8542ad97 Refactor inspect/select logic so that $r contains hooks data (#364)
* Refactor inspect/select logic so that  var contains hooks data
* Legacy renderer resets $r to null when inspecting non class/function element
2019-08-03 17:59:35 -07:00
Dominic Gannaway
644c9c4e1c [Flare] useListener -> useResponder (#362) 2019-08-02 10:14:25 -07:00
Brian Vaughn
9727f4e88f Don't let a DevTools or React internal error interfere with logging. 2019-08-02 09:39:39 -07:00
Brian Vaughn
abbaedd264 Updated Flow type for DevTools tab id 2019-08-02 09:27:13 -07:00
Brian Vaughn
62e5fd57a1 NPM package versions 4.0.0-alpha.5 -> 4.0.0-alpha.6 2019-08-01 08:26:32 -07:00
Brian Vaughn
51a15e0e4d Added CHANGELOG entries for HOC badges and no in-line props 2019-08-01 07:56:10 -07:00
Brian Vaughn
aed31fdf12 Element keys are selectable text
Changed truncation to be CSS-driven, and enabled double-click selection of text, so that long keys could be copied from within the tree.
2019-07-31 14:48:39 -07:00
Brian Vaughn
11e7b1d290 Updated OVERVIEW doc 2019-07-31 14:22:43 -07:00
Brian Vaughn
e4ccafc099 Updated CHANGELOG based on Dan's feedback 2019-07-31 14:08:44 -07:00
Brian Vaughn
52b0c20a62 Added dynamic indentation to change log 2019-07-31 13:44:32 -07:00
Brian Vaughn
271aa75cf2 Removed the Profiler screenshot capture feature
This wasn't reliable because of browser extension API limitations and required serious throttling to avoid harming performance, so I've decided to just remove it entirely for now.
2019-07-31 11:36:01 -07:00
Brian Vaughn
4f8b7864ee Add "Welcome to the new DevTools" notification
This dialog is shown in the browser extension the first time a user views v4. It is off by default for the standalone extension, but can be enabled via a public API.
2019-07-31 11:22:51 -07:00
Brian Vaughn
c57d2a2901 Added CHANGELOG 2019-07-31 10:50:56 -07:00
Brian Vaughn
9a36e56d34 Added missing Flow header 2019-07-28 17:21:00 -07:00
Brian Vaughn
8e2134beee Re-add try/catch inside Agent's getIDForNode() 2019-07-28 08:42:21 -07:00
Philipp Spiess
82881ab261 Allow Inspecting Elements Within Iframes (#355)
This change adds support for element inspecting within `<iframe/>`s.

The iframes are kept in a Set so that we only append listeners once and
clean them up properly. I’ve run a few tests and it seems to behave as
expected.

The fixture includes a cross-origin iframe to make sure we do not error
in this case.
2019-07-28 08:40:02 -07:00
Brian Vaughn
50512a223b Reverted a Webpack config change that broke browser extension styles 2019-07-27 09:30:23 -07:00
Brian Vaughn
ca4aac5014 Tweaked recent search changes
1. Compare element indices rather than ids (since these don't necessarily correlate)
2. Restored previous behaior when new search text reduces the number of results past the currently-selected element.
2019-07-27 09:15:53 -07:00
Fanny
29a6bf2a7b Feature: tweak search behaviour (#353)
Merge PR #353 from @fanny

This change changes search beahvior to initially select the result nearest the currently selected element (rather than selecting the first result in the set).
2019-07-27 09:04:20 -07:00
Brian Vaughn
3b2905b690 NPM package versions 4.0.0-alpha.4 -> 4.0.0-alpha.5 2019-07-26 10:13:52 -07:00
Brian Vaughn
7385de9fc2 react-devtools-core standalone bugfix: prevent electron crash
CSS source maps require the style-loader to use URL.createObjectURL (rather than just a <style> tag). For some reason, this crashes Electron's webview process, which completely breaks the embedded extension inside of Nuclide and other Electron apps. This commit turns (CSS) source maps off for production builds to avoid this crash.
2019-07-26 10:13:07 -07:00
Brian Vaughn
76c67399db Re-enabled packages backend build to be production mode (whoops) 2019-07-25 15:10:30 -07:00
Brian Vaughn
050cb8452d 4.0.0-alpha.3 -> 4.0.0-alpha.4 2019-07-25 10:26:52 -07:00
Brian Vaughn
1e8aa8105a Re-enable "view source" button for standalone shell
But only do this if we can verify the element file path. This hopefully avoids the case where clicking the button does nothing because of an invalid/incomplete path.
2019-07-25 09:28:45 -07:00
Brian Vaughn
c6fb743910 Flow type cleanup 2019-07-25 09:13:45 -07:00
Dominic Gannaway
a7948e8342 [Flare] Remove the old EventComponent/EventTarget system (#354) 2019-07-25 08:45:59 -07:00
Brian Vaughn
270f34f7f0 Support new Flare hook, unstable_useListener 2019-07-25 08:21:41 -07:00
Brian Vaughn
8d1c829019 Reverted style-prop hiding change because it caused a regression in the browser extension 2019-07-24 15:48:48 -07:00
Brian Vaughn
c7aff5503f 4.0.0-alpha.2 -> 4.0.0-alpha.3 2019-07-24 14:46:53 -07:00
Brian Vaughn
2e8b9fad36 Make style editor inputs more obvious resemble inputs 2019-07-24 14:43:29 -07:00
Brian Vaughn
4c610950a4 Hide "style" prop if we are showing the style editor
Also add react-native-web to test harness
2019-07-24 14:05:56 -07:00
Brian Vaughn
9a05e0b600 Disable view-source button in standalone mode if no project roots are provided 2019-07-24 13:36:51 -07:00
Brian Vaughn
722d366e9f Updated snapshot 2019-07-24 11:27:15 -07:00
Brian Vaughn
56b0017615 4.0.0-alpha.1 -> 4.0.0-alpha.2 2019-07-24 11:25:52 -07:00
Brian Vaughn
f74c89b145 Misc improvements based on user feedback from Tim
* Added shadow to modals
* Change default "collapse new nodes" to be disabled rather than enabled
* Changed setting label "Collapse newly added components by default" to "Expand component tree by default"
* Change CSS media query for settings popup to show labels at smaller size
* Hide "Inspect the matching DOM element" button (since it doesnt really serve a purpose in standalone)
* Fixed small size bug for settings icon (viewbox of 20x20 instead of 24x24)
* bugfix: window.addEventListener/window.removeEventListener is not defined in Hermes.
2019-07-24 11:25:11 -07:00
Brian Vaughn
13959aa8fb Removed accidental log statement 2019-07-24 11:13:30 -07:00
Brian Vaughn
1178d57257 Fixed a module resolution issue and a syntax error from a bad merge 2019-07-23 07:46:19 -07:00
Brian Vaughn
ffb19346c7 NPM packages 4.0.0-alpha.0 -> 4.0.0-alpha.1 2019-07-22 11:19:53 -07:00
Brian Vaughn
4b34a77d29 Improve Bridge Flow types (#352)
* Updated local fork of react-window
* Updated Fow 97 -> 103
* Lint ignore NPM dist
* Improved Bridge Flow types
2019-07-20 14:08:23 -07:00
Brian Vaughn
39ad101ea2 Removed reference to setDefaultThemeName() method
This functionality was added to v3 to support external changing of theme at runtime. This isn't supported in v4.
2019-07-20 09:28:09 -07:00
Brian Vaughn
33da657178 Make console override detectable (for RN YellowBox) 2019-07-20 08:05:08 -07:00
Brian Vaughn
167daf7a4a Updating NPM packages as 4.0.0-alpha.0 2019-07-19 10:09:49 -07:00
Brian Vaughn
abe75b0e39 Slight tweak to avoid setting an invalid numeric value in props editor 2019-07-19 09:19:03 -07:00
Brian Vaughn
f0a4b2f8e8 Merge branch 'fix-input-number-in-props' of https://github.com/koba04/react-devtools-experimental into koba04-fix-input-number-in-props 2019-07-19 09:16:26 -07:00
Brian Vaughn
0abaefb7c2 Cleanup legacy backend event listener if modern backend is detected 2019-07-19 09:02:30 -07:00
Brian Vaughn
dbbf30a332 Make my code PRETTIER 2019-07-18 16:37:57 -07:00
Brian Vaughn
67e749a73a Tweaked modal font size style 2019-07-18 16:28:20 -07:00
Brian Vaughn
bd0a0c58fd Tweaked modal title to better fit without wrapping 2019-07-18 16:26:27 -07:00
Brian Vaughn
249a2e043d Detect React Native v3 backend and show warning 2019-07-18 16:24:22 -07:00
Brian Vaughn
9fb753b5cd Hardened logic around when and how to patch console methods 2019-07-17 15:08:34 -07:00
Brian Vaughn
cb3fb42129 Patch console to append component stacks (#348)
* Patch console.warn and console.error to auto-append owners-only component stacks.

This setting is enabled by default and will work for React Native even if no front-end DevTools shell is being used. The setting can be disabled via a new, persisted user preference though.
2019-07-17 11:12:39 -07:00
Toru Kobayashi
41c00cb0cb fix to input a number value to props 2019-07-14 23:11:08 +09:00
Brian Vaughn
0f2fb5badf Standalone NPM packages and React Native support (#335)
* Add version 4 react-devtools and react-devtools-core packages which support both React Native and e.g. Safari or iframe DOM usage.
* Replaces typed operations arrays with regular arrays in order to support Hermes. This is unfortunate, since in theory a typed array buffer could be more efficiently transferred between frontend and backend for the web extension, but this never actually worked properly in v8, only Spidermonkey, and it fails entirely in Hermes so for the time being- it's been removed.
* Adds support for React Native (paper renderer)
* Adds a style editor for react-native and react-native-web
2019-07-13 10:05:04 -07:00
Brian Vaughn
39a811debe Merge pull request #342 from marvinhagemeister/attach_configure
Fix reload-and-profile attach not configurable
2019-07-06 18:40:00 -04:00
Marvin Hagemeister
8e90194f7d Add comment about 3rd party integrations 2019-07-01 23:48:52 +02:00
Marvin Hagemeister
5ec387aa82 Mark reload-and-profile attach as configurable 2019-07-01 23:35:35 +02:00
Brian Vaughn
844cdb22d6 Merge pull request #331 from trueadm/flare_displayName
[Flare] Update event component displayName
2019-06-24 07:48:24 -07:00
Brian Vaughn
81e5e9be0b Updated @reach/tooltip to v0.2.2 for a bugfix 2019-06-19 15:43:15 -07:00
Brian Vaughn
35600be1da Changed Chrome manifest version from 4.0.0.0 to 4.0.0 2019-06-19 11:06:36 -07:00
Dominic Gannaway
89a0886872 [Flare] Update event component displayName 2019-06-19 17:43:15 +01:00
Brian Vaughn
083bf8d98b Don't try to convert absolute paths to relative 2019-06-18 18:40:05 -07:00
Brian Vaughn
0e4005e0a1 Added command to build Chrome CRX 2019-06-18 15:44:22 -07:00
Brian Vaughn
abc8ef3d5d Display unnamed custom hooks as 'Anonymous' 2019-06-18 11:37:29 -07:00
Brian Vaughn
a2c79f2d9e Fixed hydration for events meta data 2019-06-18 10:50:19 -07:00
Brian Vaughn
cf19916be7 Tweaked overflow check 2019-06-18 08:59:27 -07:00
Brian Vaughn
46def793de Merge branch 'when-render-hidden' of https://github.com/justingrant/react-devtools-experimental into justingrant-when-render-hidden 2019-06-18 08:52:08 -07:00
Brian Vaughn
3988c27d70 Merge pull request #325 from bvaughn/hydration
Lazily send props/state/hooks across the bridge
2019-06-18 08:50:21 -07:00
Brian Vaughn
6298fd4248 Hardened the hooks dehydration check 2019-06-18 08:47:37 -07:00
Brian Vaughn
a56fd4c36d Tidied up. Added comments. Renamed a few things. 2019-06-18 08:40:58 -07:00
Brian Vaughn
8e3cd8ab1e Debounce inspect-element polling 2019-06-18 07:41:30 -07:00
Brian Vaughn
6c03f6abbd Tidied up a bit 2019-06-17 14:49:19 -07:00
Brian Vaughn
717af9f5c3 Updated the hydration test harness to cover a bit more 2019-06-17 14:37:49 -07:00
Brian Vaughn
d3d8a5d8b1 Hooks hydrate/dehydrate 2019-06-17 14:30:34 -07:00
Brian Vaughn
7a94ad4e8a Added props/state/context inspection to KeyValue 2019-06-17 11:30:53 -07:00
Brian Vaughn
a6d3f30f95 Initial support for hydration added to both renderer interfaces. 2019-06-16 17:32:37 -07:00
Justin Grant
a15f776708 fix: ensure when-rendered content is never hidden 2019-06-15 09:24:37 -07:00
Brian Vaughn
5e8678a0a9 Don't send HTMLElements through the bridge when inspecting componetns 2019-06-13 09:09:31 -07:00
Brian Vaughn
9eb6d3465d Updated React version check to account for older (<15) versions 2019-06-12 18:56:39 -07:00
Brian Vaughn
96f7646a1a Updated hydration logic to handle custom objects 2019-06-12 15:43:15 -07:00
Brian Vaughn
cb10c3d6da Lintfix 2019-06-12 15:17:29 -07:00
Brian Vaughn
f6ec82553d Support toggling Suspense from within owners list 2019-06-12 15:13:51 -07:00
Brian Vaughn
f0a29984f4 Merge pull request #320 from gaearon/own
Fix owner tree for legacy backend
2019-06-12 09:58:17 -07:00
Dan
4bfabbc32b Fix owner tree for legacy backend 2019-06-12 17:56:25 +01:00
Brian Vaughn
2e40cc4b18 Merge pull request #319 from gaearon/legacy-fix
Fix some legacy backend bugs
2019-06-12 09:36:20 -07:00
Dan
fdf753021e Distinguish functions and classes 2019-06-12 17:23:29 +01:00
Dan
3137553f6d State and context are on the public instance 2019-06-12 16:50:15 +01:00
Dan
f352fe2625 Maintain rootID for lazily crawled trees 2019-06-12 16:38:35 +01:00
Dan
b5850fe304 Ignore SSR mounts 2019-06-12 16:15:58 +01:00
Brian Vaughn
6c8ae706ee Merge pull request #316 from gaearon/lighter
Make children selection lighter
2019-06-11 07:13:01 -07:00
Dan Abramov
3bca6b28cd Make children selection lighter 2019-06-10 20:10:24 -06:00
Brian Vaughn
a08e9279ec Merge pull request #315 from bvaughn/settings
Settings panel inlined
2019-06-10 15:44:23 -07:00
Brian Vaughn
dd748ef574 Moved logic to only send updated filters across Bridge to the Store (and added tests) 2019-06-10 15:36:29 -07:00
Brian Vaughn
91e3f6cd4d Removed console.log 2019-06-10 15:05:12 -07:00
Brian Vaughn
e2e598c824 Remember last preferences tab via local storage 2019-06-10 15:03:05 -07:00
Brian Vaughn
19ed98d0c2 Removed Settings panel in favor of new shared Settings modal 2019-06-10 14:57:26 -07:00
Brian Vaughn
402a68d816 Fixed minor border bug in Profiling tab toolbar 2019-06-10 11:14:27 -07:00
Brian Vaughn
37c331533d Merge pull request #173 from bvaughn/legacy
Support legacy React versions
2019-06-09 16:24:00 -07:00
Brian Vaughn
e66fcaf17d Nit 2019-06-09 16:22:23 -07:00
Brian Vaughn
8f53235017 Fixed regression fixtures 2019-06-09 16:16:06 -07:00
Brian Vaughn
80bf1ba0eb Merge branch 'master' into legacy 2019-06-09 16:00:12 -07:00
Brian Vaughn
ea03ddd583 Added Flow type coverage for all EventEmitter subclasses 2019-06-09 15:50:17 -07:00
Brian Vaughn
b3046c6e19 Merge pull request #310 from bvaughn/track-changed-props
Add profiling option to track why a component rendered
2019-06-08 17:45:46 -07:00
Brian Vaughn
3904d634bb Added an explicit 'did not render' label 2019-06-08 17:36:17 -07:00
Brian Vaughn
341d1574cb Tweaked a few inline comments 2019-06-08 17:30:11 -07:00
Brian Vaughn
9047f371e2 Fix minor toolbar border misalignment 2019-06-08 17:18:05 -07:00
Brian Vaughn
4f92af17ea Only show "rendered at" if selected Fiber committed at least once 2019-06-08 17:17:56 -07:00
Brian Vaughn
7a72ee5ac0 Added context changes to sidebar; fixed a initial-mount detection bug 2019-06-08 17:01:38 -07:00
Brian Vaughn
5672d686dc Fixed some minor CSS issues 2019-06-08 16:45:38 -07:00
Brian Vaughn
6ab522326d Added a test for added/removed props 2019-06-08 11:41:39 -07:00
Brian Vaughn
a2f469d742 Fixed an increment bug in sidebar for fiber-commits 2019-06-08 09:22:30 -07:00
Brian Vaughn
2d48401346 Added context support to change description 2019-06-08 09:10:54 -07:00
Dan Abramov
fdc5ca4ba6 Remove dead code 2019-06-07 18:42:12 -07:00
Dan Abramov
90fa0adc0a Fix lint 2019-06-07 18:37:24 -07:00
Dan Abramov
65ac53bba4 Fixes 2019-06-07 18:33:03 -07:00
Dan Abramov
ad7458bb42 Merge branch 'master' into legacy 2019-06-07 17:54:54 -07:00
Dan Abramov
9243bc194c Rewrite to make it sturdier 2019-06-07 17:21:30 -07:00
Brian Vaughn
bd5c2e4621 Initial change tracking implemented
* User profiling setting
* Background collects changed props/state (not added/removed or hooks yet)
* Tests updated
2019-06-07 15:38:26 -07:00
Brian Vaughn
88e59277e7 Added HOC badges to Jest Store serialization 2019-06-07 14:10:49 -07:00
Brian Vaughn
21bb66a8c7 Added HOC filter test 2019-06-07 14:06:08 -07:00
Brian Vaughn
956935f915 Merge pull request #308 from bvaughn/dependabot/npm_and_yarn/js-yaml-3.13.1
Bump js-yaml from 3.12.1 to 3.13.1
2019-06-07 13:15:10 -07:00
dependabot[bot]
c2c3e8e6e5 Bump js-yaml from 3.12.1 to 3.13.1
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 3.12.1 to 3.13.1.
- [Release notes](https://github.com/nodeca/js-yaml/releases)
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/3.12.1...3.13.1)

Signed-off-by: dependabot[bot] <support@github.com>
2019-06-07 20:12:54 +00:00
Brian Vaughn
78721bde4c Backend notifies the frontend of Storage API support. Frontend disables e.g. reload-and-profile based on this. 2019-06-07 13:08:49 -07:00
Brian Vaughn
3e3c83aecd Updated reload-and-profile temp key to use sessioStorage instead of localStorage 2019-06-07 12:40:59 -07:00
Brian Vaughn
89e36e3976 Wrap all calls to localStorage/sessionStorage to avoid potential runtime errors 2019-06-07 10:51:01 -07:00
Brian Vaughn
a987206a36 Fixed an overflow bug. Added mode-specific CSS style for Firefox. 2019-06-06 10:39:07 -07:00
Brian Vaughn
d1a88ffc5c Re-add plugin-transform-react-jsx-source plugin for tests 2019-06-05 14:36:01 -07:00
Brian Vaughn
dc9b0810f9 Changed react-window alias 2019-06-05 14:33:24 -07:00
Brian Vaughn
9d90189ee3 react-window sync flushes scroll updates 2019-06-05 14:30:43 -07:00
Brian Vaughn
6ff733873c Vendored react-window 2019-06-05 14:27:57 -07:00
Brian Vaughn
7ef5970b2f Removed __source info from production builds 2019-06-04 17:03:13 -07:00
Brian Vaughn
1afc83e7cd Tweaked manifest "version_name" logic 2019-06-04 14:56:36 -07:00
Sarhan Aissi
e158768b16 fix: remove version_name from Firefox WebExtension manifest 2019-06-04 22:34:20 +01:00
Brian Vaughn
7ed3f6815c Merge pull request #295 from bvaughn/horizontal-compression
Components tree changes to improve HOCs and browsing deep trees
2019-06-04 13:59:22 -07:00
Brian Vaughn
2245206c4c Add source location to debug logging info 2019-06-04 08:56:10 -07:00
Brian Vaughn
5963998fbe Display density preference updates :root fontSize
As a result, paddings and sizes (e.g. tab bar heights) will also be impacted now by this preference. More importantly, Profile charts will also use the line height preference, so the 'comfortable' setting will hopefully make profiling data easier to read.
2019-06-04 07:24:14 -07:00
Brian Vaughn
95a99867f7 Decreased contrast of HOC badges in selected props panel 2019-06-03 12:51:04 -07:00
Brian Vaughn
ef139a1811 Batched tweaks and bug fixes:
1. Bugfix: Hide tree grouping/background coloring when inside of collapsed subtree.
2. Bugfix: Don't measure and udpate indentation when Components tab is hidden.
3. Tweak: Lower background color for selected subtree in light theme to increase contrast for text.
4. Tweak: Remove FB-specific displayName check/hack since we will address that by modifying the internal require JS transform.
2019-06-03 12:47:26 -07:00
Brian Vaughn
edfc1bb2b3 Simplified background highlight style now that corner radius has been removed from selected highlight 2019-06-03 10:46:37 -07:00
Brian Vaughn
06b004b5d4 Renamed <Guideline> to <SelectedTreeHighlight> 2019-06-03 09:39:31 -07:00
Brian Vaughn
fbc6e5d68a Removed outdated comment and Eslint rule ignore 2019-06-03 09:33:48 -07:00
Brian Vaughn
6ac558df2d Reset max indentation when entering/exiting the owner tree 2019-06-03 09:32:28 -07:00
Brian Vaughn
a173f4eb85 Add HOC component filter 2019-06-03 08:51:50 -07:00
Brian Vaughn
78cf211286 Only shrink indentation. Don't increase it again. This avoids 'jumping'. 2019-06-03 08:01:48 -07:00
Brian Vaughn
f713265a00 Cap indentation increase at a max 2019-06-02 21:01:24 -07:00
Brian Vaughn
8261a3f453 Removed Tree padding 2019-06-02 20:25:57 -07:00
Brian Vaughn
dc08e80037 Cache list rows by Element ID rather than index
This is important since we are caching element sizes by DOM (in a WeakMap). Toggling (as well as insertion/deletion) might otherwise break this in some cases.
2019-06-02 20:10:30 -07:00
Brian Vaughn
6b6e571c68 Added HOC badge to owners list dropdown 2019-06-02 10:50:07 -07:00
Brian Vaughn
27d4f0b24d Fixed box drawing chars comment 2019-06-02 10:40:10 -07:00
Brian Vaughn
dc945f6b81 Fixed a typo in string truncation util 2019-06-02 10:06:05 -07:00
Brian Vaughn
17b04c321c Cleaned up how we measure children and adjust indentation size 2019-06-02 10:02:22 -07:00
Brian Vaughn
3f0606f3d9 Refactored badges to share code and show +count 2019-06-01 18:48:24 -07:00
Brian Vaughn
6a69a6e991 Added HOC badge to owners stack breadcrumbs 2019-06-01 18:05:59 -07:00
Brian Vaughn
c1989448f4 Disable guide/group highlight in owners tree mode 2019-06-01 17:49:51 -07:00
Brian Vaughn
96dc003a70 Removed debounce+animation from indentation adjustment 2019-06-01 17:48:01 -07:00
Brian Vaughn
b5f8998859 Added debounce and animation for resize 2019-06-01 11:16:18 -07:00
Brian Vaughn
de9fb0a8a2 Tweaked guideline background color style 2019-06-01 09:34:39 -07:00
Brian Vaughn
ab7ae78511 Tweaked a few styles 2019-06-01 09:19:32 -07:00
Brian Vaughn
2845a7883b Whoops I broke CI (updating snapshots) 2019-06-01 08:44:55 -07:00
Brian Vaughn
aa87b125e7 Lots of tweaks
Remove selected guideline in favor of background color for selected subtree.
Add badges in grid format to selected elements prop panel.
Show badges beside owners list.
2019-06-01 08:24:24 -07:00
Brian Vaughn
19d95a1368 Revert "Re-added indent lines"
This reverts commit 33432b037f.
2019-05-31 14:41:20 -07:00
Brian Vaughn
33432b037f Re-added indent lines 2019-05-31 13:34:55 -07:00
Brian Vaughn
5a269e7ced Initial POC for compressing horizontal offset for wide/deep trees 2019-05-31 11:24:34 -07:00
Dan Abramov
2794b92164 Add some support for reordering 2019-05-31 18:00:56 +01:00
Dan Abramov
c3be085910 Remove crawling for updates
It doesn't seem necessary to crawl because mounts only happen in the context of updates.

This fixes updates to not be treated as new mounts.
2019-05-31 17:41:11 +01:00
Dan Abramov
6fd83acb1d Default to showing host nodes for legacy renderer 2019-05-31 15:39:00 +01:00
Dan Abramov
9f44251ebf Remove unnecessary code for host text as we skip it anyway 2019-05-31 14:27:22 +01:00
Brian Vaughn
c0f686eed9 Show indent lines preference 2019-05-30 14:30:17 -07:00
Brian Vaughn
a2a468743f Remove hover guideline in favor of showing guidelines for every nesting level 2019-05-30 14:17:12 -07:00
Brian Vaughn
a957031fe7 Fixed bad Bridge disconnections 2019-05-30 09:27:28 -07:00
Brian Vaughn
8f8ac358c6 Turn off pointer events for guidelines 2019-05-30 08:43:45 -07:00
Brian Vaughn
ec421355bd Added selected and hovered guidelines to Components tree 2019-05-30 08:22:06 -07:00
Brian Vaughn
d5be489d5b Backed out Bridge shutdown refactor as it seems to have introduced bugs 2019-05-29 14:23:10 -07:00
Brian Vaughn
5429f651b4 Tweaks 2019-05-28 13:57:05 -07:00
Sunil Pai
388b03dd12 prettier 2019-05-28 20:24:35 +01:00
Sunil Pai
9e87e654f5 pass tests and flow 2019-05-28 20:21:55 +01:00
Sunil Pai
c7580fcd3f Merge remote-tracking branch 'upstream/master' into act-async 2019-05-28 20:21:38 +01:00
Brian Vaughn
92c2d8366b Updated Chrome installation
1. Removed auto-updates XML (since the feature doens't work for self hosted extensions)
2. Replaced CRX with packed ZIP (since people are having trouble with the CRX, and auto-udpates doesn't work anyway)
2019-05-28 08:52:21 -07:00
Brian Vaughn
fa0139afbf Merged master 2019-05-26 10:47:55 -07:00
Brian Vaughn
af47c39dbb Added and view-source support for Memo components 2019-05-26 10:33:19 -07:00
Brian Vaughn
4422337562 Added another (disabled) test; refactored getChildren slightly 2019-05-26 08:37:05 -07:00
Brian Vaughn
94bebda825 Merged master 2019-05-25 09:10:43 -07:00
Brian Vaughn
bda8a0aa98 Decreased contrast of disabled button icons to look more obviously disabled 2019-05-24 16:00:12 -07:00
Brian Vaughn
c8411019f1 Updated profiler overview 2019-05-24 14:43:56 -07:00
Brian Vaughn
e76cee394d Added section about inspecting element to OVERVIEW 2019-05-24 14:31:05 -07:00
Brian Vaughn
4cc7e748d1 Merge pull request #289 from bvaughn/cache-inspected-element
Cache inspected element data until it is updated
2019-05-24 09:26:31 -07:00
Brian Vaughn
efc2f82da2 Reorganize inspected element state vars slightly 2019-05-24 09:17:20 -07:00
Brian Vaughn
f580d0ece7 Don't (re)serialize inspected elements either unless they have re-rendered since last inspected. 2019-05-24 09:07:15 -07:00
Brian Vaughn
07db37f030 Cache inspected element data until it is updated 2019-05-24 07:37:46 -07:00
Brian Vaughn
408fbee23b Fix potential RTE caused by setting (saved) profiling data while profiling is in progress 2019-05-23 14:49:47 -07:00
Brian Vaughn
395c02567c Handle HTTPS Git clone URLs 2019-05-23 11:55:32 -07:00
Brian Vaughn
6e8c2015fc Tweaked Bridge shutdown sequence slightly 2019-05-23 11:46:28 -07:00
Brian Vaughn
34f6fa4fab Added a sanity test for Bridge shutdown 2019-05-23 11:22:02 -07:00
Brian Vaughn
f47b40fe6c Tweaked event display name logic 2019-05-23 09:30:31 -07:00
Dominic Gannaway
9a67ba2f98 Remove snapshot 2019-05-23 09:17:50 -07:00
Dominic Gannaway
70084e881b Update snapshot tests 2019-05-23 09:17:37 -07:00
Dominic Gannaway
8eb7eddd1f Run prettier 2019-05-23 09:17:37 -07:00
Dominic Gannaway
779fd167ff Adds inspectable event components + props
[Flare] Adds inspectable event components + props
2019-05-23 09:17:37 -07:00
Brian Vaughn
e4aa3c5b33 Update profiling-supported status each time roots change (and added tests) 2019-05-23 09:09:35 -07:00
Brian Vaughn
74d8207e06 Improved visual style of Profiling-disabled button 2019-05-23 08:52:27 -07:00
Brian Vaughn
541dd6c4b6 Moved profiling-supported subscription into ProfilerContext 2019-05-23 08:48:51 -07:00
Brian Vaughn
0608b1a554 Merge pull request #281 from bvaughn/persiste-profiling-data-after-navigation
[WIP] Don't erase profiler data on navigation
2019-05-23 08:38:59 -07:00
Brian Vaughn
44fbf3cd1d Added ProfilerContext tests 2019-05-23 08:36:34 -07:00
Brian Vaughn
5719454377 Persist profiling data after navigation 2019-05-22 20:00:21 -07:00
Brian Vaughn
351d5f662a Add Tab id to Tooltip 2019-05-22 20:00:06 -07:00
Brian Vaughn
f14a2fd05c Use @reach tooltips for TabBar, cleanup supports-profiling subscription 2019-05-22 18:44:43 -07:00
Brian Vaughn
98623dfdb0 Tweak 2019-05-22 16:40:40 -07:00
Dominic Gannaway
d98161874c [Flare] Ensure DOM inspection is Flare compatible 2019-05-22 16:29:54 -07:00
Brian Vaughn
eaaeb439b4 Fixed a missing remove-event-listener in ProfilerStore 2019-05-22 10:52:15 -07:00
Brian Vaughn
b556f7444d Profiler properly handles unmounted roots 2019-05-22 10:19:26 -07:00
Brian Vaughn
b4a3ef9fb2 Merge pull request #279 from bvaughn/profiling-architecture-eager-data-push
Refactor Profiler architecture
2019-05-22 10:00:52 -07:00
Brian Vaughn
962865e5bf Add datetime to the profiling export filename 2019-05-22 09:57:10 -07:00
Brian Vaughn
fbd82385d2 Fixed a state cleanup issue if Profiler data is cleared 2019-05-22 09:04:55 -07:00
Brian Vaughn
d1344768b2 Changed export code to (hopefully) support larger exports 2019-05-22 08:41:57 -07:00
Brian Vaughn
ec44eb1e4c Tweaked did-not-render text color to be slightly dimmer 2019-05-22 08:32:10 -07:00
Brian Vaughn
a03c3b5d14 Bumped Profiler exported data version 2019-05-22 08:22:33 -07:00
Brian Vaughn
d09299bf85 Cleaned up some tests 2019-05-22 08:05:34 -07:00
Brian Vaughn
99b6a44beb Updated event subscriptions and getters to use new ProfilerStore 2019-05-22 07:40:41 -07:00
Brian Vaughn
2d4bb01c01 Moved profiling data to ProfilerContext to fix re-import bug 2019-05-22 07:28:26 -07:00
Brian Vaughn
95bd6c8f63 Added export to web shell and removed 'downloads' API permission 2019-05-22 06:46:42 -07:00
Brian Vaughn
36d51f4eb6 Added root selector UI to Profiler 2019-05-22 06:40:04 -07:00
Brian Vaughn
c6de014a9a Massively overhauled profiling data architecture 2019-05-22 06:05:25 -07:00
Brian Vaughn
7ce9f4859c Renamed Store importedProfilingData -> profilingData 2019-05-20 10:45:16 -07:00
Brian Vaughn
f1561e9e17 Merge pull request #274 from bvaughn/commit-priority-level
Show commit priority levels in Profiler UI (if available)
2019-05-20 09:56:58 -07:00
Brian Vaughn
d440380719 Upgraded to canary with priority level info 2019-05-20 09:54:07 -07:00
Brian Vaughn
53de5b69cc Updated test snapshot 2019-05-20 09:42:37 -07:00
Brian Vaughn
16a81feb72 Moved priority level constants into rendeer interface 2019-05-20 09:39:26 -07:00
Brian Vaughn
9a6a19456f Show commit priority levels in Profiler UI 2019-05-20 09:39:26 -07:00
Brian Vaughn
146fd2ad3d Fixed snapshot diff 2019-05-17 07:54:07 -07:00
Brian Vaughn
629e500fe2 Merge pull request #275 from lucasecdb/fix/undefined-chartnode
Fix undefined chart node when switching commits in profiler
2019-05-17 07:52:07 -07:00
Lucas Cordeiro
1e025edb9a Fix undefined chart node when switching commits in profiler 2019-05-17 09:35:10 -03:00
Brian Vaughn
f10a6b379c Improve scanning Profiler chart for deep renders 2019-05-15 14:20:36 -07:00
Brian Vaughn
6fd2e72b5e Minor nits 2019-05-14 11:01:41 -07:00
Ivan Babak
76e569992b Cleanup profile export/import data types, add export/import test
Strengthened the I/O-boundary type conversion logic.

Fixed type inconsistencies uncovered by removing `any` and
by making explicit type annotations and transformations.

In particular, these were likely malformed when restored from a file:
- `commitDetails`
- `interactions`
- `initialTreeBaseDurations`

The mismatches were Map vs interleaved Array.
2019-05-13 23:59:01 -07:00
Brian Vaughn
1723c5d316 Changed "Unknown" fallback displayName to "Anonymous". Added memo/forwardRef labels to Profiler charts. 2019-05-13 15:26:14 -07:00
Brian Vaughn
6b4c758338 CSS tweaks 2019-05-13 14:51:56 -07:00
Brian Vaughn
e2746ffd0e Merge branch 'enhancement/display-change' of https://github.com/submetu/react-devtools-experimental into submetu-enhancement/display-change 2019-05-13 14:12:27 -07:00
Brian Vaughn
982eb84a13 Merge pull request #271 from tux-tn/master
Replaced adm-zip with node-archiver
2019-05-13 14:10:21 -07:00
Brian Vaughn
d9a0c42652 Bumped Profiler export version (since self durations are now included) 2019-05-13 14:04:53 -07:00
Brian Vaughn
cf99c3ee6c Moved calculation of self duration to the backend/renderer
This enables self duration to be computed accurately despite component filters
2019-05-13 10:13:29 -07:00
Subhan
74706b0c86 updates snapshots 2019-05-13 19:00:11 +02:00
Subhan
ec89ae88b6 Changes display of ForwardRef and Memo components 2019-05-13 18:58:03 +02:00
Sarhan Aissi
ad94f9ef08 Replaced adm-zip with node-archiver 2019-05-13 03:55:05 +01:00
Brian Vaughn
ffef7ffc57 Merge pull request #268 from frankcalise/master
Fixed build chrome not working on Windows due to rm command not existing
2019-05-12 07:43:19 -07:00
Brian Vaughn
faea8ed6a9 Delete package-lock.json 2019-05-12 07:43:07 -07:00
Frank Calise
285568825b Fixed build chrome not working on Windows due to rm command not existing 2019-05-12 10:12:17 -04:00
Brian Vaughn
b74f3f507a Added basic tests for InspectedElementContext 2019-05-10 09:13:54 -07:00
Brian Vaughn
61ab40c15c Test utils actSuspense -> actAsync 2019-05-10 08:27:14 -07:00
Brian Vaughn
8536995b11 Merge pull request #264 from bvaughn/filter-owners-list
Fetch owners list from renderer (using suspense)
2019-05-10 08:10:24 -07:00
Brian Vaughn
ac0022bf4a Added more tree context tests 2019-05-10 08:07:27 -07:00
Sunil Pai
7aaef6f41f reverting the rename 2019-05-10 12:18:40 +01:00
Sunil Pai
6243d19b9c pretty, witty, fine 2019-05-10 12:16:43 +01:00
Sunil Pai
ae3b98f5ad rewrite test act helpers based on react/#15591
This simplifies your test helpers to loop until all timers are flushed (including the ones that get queued after updates), and works in concurrent mode. I also renamed actSuspense to actAsync to be clearer.
2019-05-10 12:13:14 +01:00
Brian Vaughn
7160f6f584 Fixed owners stack direction and added current element to stack 2019-05-09 18:11:17 -07:00
Brian Vaughn
427f0f63c1 Added TreeContext tests 2019-05-09 15:52:50 -07:00
Brian Vaughn
5daf9b626f Fixed test describe name 2019-05-09 14:31:48 -07:00
Brian Vaughn
b6c135c165 Added Jest tests for OwnersListContext 2019-05-09 14:21:22 -07:00
Brian Vaughn
564a223368 Fetch owners list from renderer (using suspense)
Owners in the list may have been filtered out of the Store, but in the owners list view- it's important to still show them. The frontend cannot do this on its own, so this list needs to come from the renderer interface.
2019-05-09 11:47:22 -07:00
Brian Vaughn
17516b76ae Dim owners that have been filtered from the tree in rendered-by list 2019-05-08 18:23:54 -07:00
Brian Vaughn
0722a5a024 Tweaked REAMDE 2019-05-08 17:58:31 -07:00
Brian Vaughn
ee099124e2 Fixed a Profiler memoization bug and improved test coverage 2019-05-08 15:41:57 -07:00
Brian Vaughn
d42f86bb50 Updated Profiling chart tests to cover components with duration=0 2019-05-08 14:35:43 -07:00
Brian Vaughn
df10afba51 Merge pull request #262 from submetu/enhancement/label-improvement
Profiler: Improve labels for times that round to 0.0ms
2019-05-08 14:26:16 -07:00
Brian Vaughn
4f1d347c04 Custom filters are applied by default after extension reload 2019-05-08 14:22:06 -07:00
Subhan
34a38dc4f0 updates snapshots and removes extra formatting from formatTime 2019-05-08 23:33:26 +03:00
Subhan
d3522f1f66 Uses FormDuration and FormTime to format times that are 0 into something more readable 2019-05-08 23:18:43 +03:00
Brian Vaughn
98260f8614 Added installation instructions to README 2019-05-08 12:53:22 -07:00
Brian Vaughn
703706b40f Add toggle-suspense button to all elements
This button is disabled if the renderer returns canToggleSuspense=false.
2019-05-08 10:50:32 -07:00
Brian Vaughn
dbe68f7a67 Updated lint ignore for new dev shell dist folder 2019-05-08 08:52:48 -07:00
Subhan
60511aadc0 Profiler: Improve labels for times that round to 0.0ms 2019-05-08 10:11:52 +03:00
Brian Vaughn
a54581c2dd Fixed invalid DOM nesting warning 2019-05-07 15:25:17 -07:00
Brian Vaughn
44e90e6ef4 Upgrade @reach UI and remove tooltip fork 2019-05-07 15:22:57 -07:00
Brian Vaughn
97b7fdd2d9 Fixed a deprecated prop warning from react-window 2019-05-07 14:47:37 -07:00
Brian Vaughn
278661715c Show import error dialog if profiling data import fails 2019-05-07 14:38:11 -07:00
Brian Vaughn
acdc9bae67 Added export+import profiling data test coverage
Also fixed an incomplete import feature as well as a regression in export that had gone unnoticed due to previous lack of test coverage.
2019-05-07 13:08:46 -07:00
Brian Vaughn
90701815b6 Merge pull request #258 from bvaughn/profiler-test-experiments
Added profiler tests
2019-05-06 14:00:45 -07:00
Brian Vaughn
7ead699714 Prettier 2019-05-06 13:58:49 -07:00
Brian Vaughn
6ab8972345 Update to React canary release for interaction tracing bugfix 2019-05-06 13:52:27 -07:00
Brian Vaughn
c2bf71f406 Added commit tree builder test 2019-05-06 13:41:36 -07:00
Brian Vaughn
b25d996fc4 Added profiling chart data tests 2019-05-06 13:37:06 -07:00
Brian Vaughn
d86bc1020e Hardened tests to ensure expectations are flushed 2019-05-06 13:04:14 -07:00
Brian Vaughn
705cd9b109 Added Flow types to profiling test 2019-05-06 09:44:01 -07:00
Brian Vaughn
c29483122c Removed outdated TODO comment 2019-05-05 09:56:54 -07:00
Brian Vaughn
269969b645 Updated snapshot data after ReactDOM batch fix 2019-05-05 09:52:27 -07:00
Brian Vaughn
1c49a7ef59 Added remaining profiling tests. One currently fails because of a bug with act() and interaction tracing 2019-05-04 14:22:50 -07:00
Brian Vaughn
da1e5776b1 Added a second Profiling test (for CommitDetails) and fixed some module reset prolems 2019-05-04 13:11:56 -07:00
Brian Vaughn
dd96b3314c Cleaned up tests a bit. Profiling test uses mock timers now. 2019-05-04 09:36:13 -07:00
Brian Vaughn
f7c8e3a05c Experimenting with profiler tests 2019-05-03 15:01:26 -07:00
Brian Vaughn
a8ed95445c Store profiler snapshot data by root (and clear on root unmount) 2019-05-03 14:59:20 -07:00
Brian Vaughn
a552b7b5f7 Only clear Profiling snapshot on root-unmount 2019-05-03 10:12:45 -07:00
Brian Vaughn
73cf0fa32b Merge branch 'master' into sompylasar-232-clear-profiling-data-for-unmounted-root 2019-05-03 10:01:43 -07:00
Brian Vaughn
542409954a Merge pull request #257 from bvaughn/right-align-flame-graph
Right-align flame graph children
2019-05-03 10:01:23 -07:00
Brian Vaughn
8585ee37db Renamed assertOneMap -> assertEmptyMap 2019-05-03 09:30:48 -07:00
Brian Vaughn
8850a9a64a Merge branch '232-clear-profiling-data-for-unmounted-root' of https://github.com/sompylasar/react-devtools-experimental into sompylasar-232-clear-profiling-data-for-unmounted-root 2019-05-03 09:24:58 -07:00
Brian Vaughn
e71bda5257 Right-align flame graph children 2019-05-03 09:21:26 -07:00
Brian Vaughn
435e22ad1b Fixed deploy script 2019-05-03 08:55:31 -07:00
Brian Vaughn
07281993d1 Merge pull request #242 from sompylasar/improve-flow-coverage-any
Improve Flow coverage by reducing typecasts through `any`
2019-05-03 08:00:47 -07:00
Brian Vaughn
868cf67aa4 Removed findCurrentFiberUsingSlowPath() in favor of findCurrentFiberUsingSlowPathById() 2019-05-03 07:56:24 -07:00
Brian Vaughn
7f4482e438 Removed optional_chaining from Flow config 2019-05-03 07:48:30 -07:00
Brian Vaughn
40ed0ca839 Merge branch '165-add-flow-types-for-fiber' of https://github.com/sompylasar/react-devtools-experimental into sompylasar-165-add-flow-types-for-fiber 2019-05-03 07:48:21 -07:00
Brian Vaughn
4bf3ac1910 Fixed broken path-selection after filter changes 2019-05-02 15:21:29 -07:00
Brian Vaughn
d7447a8458 Fixed bug in Store.getIndexOfElementID() that caused roots with multiple top-level children to return an incorrect item index 2019-05-02 15:12:57 -07:00
Brian Vaughn
4e04907d13 Added badge for enabled filter count 2019-05-02 10:53:40 -07:00
Brian Vaughn
ef596be1ef Merge pull request #207 from sompylasar/131-highlight-all-children
Support highlighting of all DOM elements of Fragments, not just first
2019-05-02 08:31:22 -07:00
Brian Vaughn
1473e9efc8 Merge pull request #245 from bvaughn/custom-filtering
Add configurable component filters
2019-05-01 17:52:27 -07:00
Brian Vaughn
83b521c7b4 Updated Flamechart to support multiple nodes at root 2019-05-01 17:44:38 -07:00
Brian Vaughn
4a4786ac2f Misc cleanup 2019-05-01 14:18:20 -07:00
Brian Vaughn
e6da4b9058 Renamed FilterType -> ComponentFilterType 2019-05-01 14:01:03 -07:00
Brian Vaughn
e45deb5471 Removed $FlowFixMe comments 2019-05-01 13:59:54 -07:00
Brian Vaughn
540207901d Added some component filtering tests 2019-05-01 13:31:55 -07:00
Brian Vaughn
8429220164 Added filter UI (but with a lot of $FlowFixMe comments) 2019-05-01 10:45:18 -07:00
Brian Vaughn
0b4bfbc98f Add support for hide-by-name and hide-by-path component filter regexps 2019-05-01 10:45:18 -07:00
Brian Vaughn
a2ba90bf96 Fixed a path selection bug when filter pereferences are updated 2019-05-01 10:45:18 -07:00
Brian Vaughn
c4c51c0821 Prevent filter preference changes while profiling is active 2019-05-01 10:45:18 -07:00
Brian Vaughn
eb9705abc8 Removed FilterList UI for now (collapsed into Settings component) 2019-05-01 10:45:18 -07:00
Brian Vaughn
a241780dc2 Filter changes are applied to the renderer without reloading 2019-05-01 10:45:18 -07:00
Brian Vaughn
27a1820039 Refactored filter preferences a bit more to be stored in the Store 2019-05-01 10:45:18 -07:00
Brian Vaughn
ee1b38e4db Added filter preference types and plugged into renderer partly. Lots of work to do still. 2019-05-01 10:45:18 -07:00
Brian Vaughn
9db209ee64 Initial pass at adding filter-by-type Flow types and support to renderer 2019-05-01 10:45:18 -07:00
Brian Vaughn
17c5feb66a Reorganized types shared between backend and frontend slightly. 2019-05-01 10:45:18 -07:00
Brian Vaughn
18b34b4926 Rearranged Settings UI in prep for custom filter controls 2019-05-01 10:45:18 -07:00
Brian Vaughn
a9aa9f2106 Merge pull request #251 from gaearon/devserver
Use WebpackDevServer for local testing
2019-05-01 09:29:43 -07:00
Dan Abramov
b9ae9393b9 Use WebpackDevServer for local testing 2019-05-01 17:19:26 +01:00
Ivan Babak
cd89c0d75f Clear profiling data for root when the root is unmounted
Fixes https://github.com/bvaughn/react-devtools-experimental/issues/232
2019-05-01 01:46:47 -07:00
Ivan Babak
c6c71ef8f9 Fix profiling screenshots data structure to map rootID to commitIndex
Propagate `rootID` throughout the code for `captureScreenshot`.

Rename private profiling maps of `store` to make relations more clear.

Fix missing cleanup for screenshots data in `set importedProfilingData` of `store`.
2019-05-01 01:07:36 -07:00
Ivan Babak
d1f6e762e4 Improve Flow coverage by reducing typecasts through any
There are many unnecessary typecasts through `any` which
break the Flow of types across the program.

It's more bulletproof to avoid lying to ourselves about types.

Also fixed sketchy null check where zero ID would be skipped:
```diff
-  } else if (selectedElementID) {
+  } else if (selectedElementID !== null) {
```
2019-05-01 00:31:13 -07:00
Brian Vaughn
abcb613223 Minor Bridge code tweaks:
1. Renamed a variable
2. Coerced undefined to null
3. Added a couple of console.warn() for unexpected paths
2019-04-30 09:23:11 -07:00
Brian Vaughn
5204ae87bc Merge pull request #229 from sompylasar/217-workaround-disconnected-port-error
Fix for 'Attempting to use a disconnected port object'
2019-04-30 09:15:52 -07:00
Brian Vaughn
b24216a7b1 Merge pull request #234 from gaearon/nested-suspense-test
Add test coverage for nested Suspense
2019-04-30 08:51:58 -07:00
Brian Vaughn
9e1b1e8c91 Merge pull request #233 from gaearon/preset-env
Start using @babel/preset-env
2019-04-30 08:50:17 -07:00
Brian Vaughn
da951ec9bb Merge pull request #243 from sompylasar/rename-profiler-types-to-frontend-backend-to-disambiguate
Rename Profiler types to disambiguate which is Frontend and Backend
2019-04-30 08:47:05 -07:00
Brian Vaughn
44205f16d9 Merge pull request #247 from sompylasar/fix-flow-on-circleci
Fix Flow failure on CircleCI due to the number of workers
2019-04-30 08:32:37 -07:00
Ivan Babak
bfbde71657 Fix Flow failure on CircleCI due to the number of workers
https://github.com/flowtype/flow-bin/issues/138#issuecomment-448416874
https://github.com/flowtype/flow-bin/issues/138#issuecomment-450367472

> This will stop flow from trying to consume too many virtual CPUs (which CircleCI doesn't actually provide), letting it run to completion without first running out of memory and killing its sub processes.

The log output in CircleCI was:
https://circleci.com/gh/bvaughn/react-devtools-experimental/201
```
#!/bin/bash -eo pipefail
yarn flow
yarn run v1.10.1
$ /home/circleci/repo/node_modules/.bin/flow
Launching Flow server for /home/circleci/repo
Spawned flow server (pid=259)
Logs will go to /tmp/flow/zShomezScirclecizSrepo.log
Monitor logs will go to /tmp/flow/zShomezScirclecizSrepo.monitor_log
Launching Flow server for /home/circleci/repo
Spawned flow server (pid=361)
Logs will go to /tmp/flow/zShomezScirclecizSrepo.log
Monitor logs will go to /tmp/flow/zShomezScirclecizSrepo.monitor_log
Launching Flow server for /home/circleci/repo
Spawned flow server (pid=464)
Logs will go to /tmp/flow/zShomezScirclecizSrepo.log
Monitor logs will go to /tmp/flow/zShomezScirclecizSrepo.monitor_log
Launching Flow server for /home/circleci/repo
Spawned flow server (pid=567)
Logs will go to /tmp/flow/zShomezScirclecizSrepo.log
Monitor logs will go to /tmp/flow/zShomezScirclecizSrepo.monitor_log
Lost connection to the flow server (0 retries remaining): -Out of retries, exiting!
error Command failed with exit code 7.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
Exited with code 1
```
2019-04-29 21:56:53 -07:00
Ivan Babak
d35cf80921 Remove Fiber type properties we don't use in DevTools 2019-04-28 12:57:28 -07:00
Dan Abramov
d351b46aee Merge pull request #238 from sompylasar/fix-typo-recursivelyinitializetree
Fix typo `recursivelyIniitliazeTree` -> `recursivelyInitializeTree`
2019-04-28 13:38:49 +01:00
Dan Abramov
7c04883f8d Merge pull request #239 from sompylasar/remove-agent-addbridge
Remove Agent addBridge: there can only be one bridge, add in constructor
2019-04-28 13:38:34 +01:00
Ivan Babak
1b5f043e01 Fix for 'Attempting to use a disconnected port object'
Fixes https://github.com/bvaughn/react-devtools-experimental/issues/217

The error reproduces with any two React websites, e.g. `https://reactjs.org` and `https://nextjs.org`, by keeping the DevTools Components tab open and switching between these websites in the same browser tab.

There are several issues with the code that contribute to this:
1. `Bridge` leaves behind a dangling timer that fires `_flush` after the bridge has been abandoned ("shutdown").
2. `bridge.send('shutdown')` is asynchronous, so the event handlers do not get unsubscribed in time.
3. `port.onDisconnect` does not trigger on in-tab navigation like new URL or back/forward navigation.
4. State management design of the code that uses shared variables and callbacks makes it hard to handle race conditions originating from the browser.

This commit cleans up some of the lacking symmetry when using `addListener`/`removeListener`, but the code in `shells/browser/shared/src/main.js` is hard to reason about with regards to race conditions, and there are many possible race conditions originating from the browser, so maybe there could be a better design paradigm (like a formal state machine) to manage the state changes in response to sequences of events than plain old event listeners, callbacks, and shared variables.

Unrelated, but clicking Chrome Back/Forward/Back/Forward very fast makes the browser and the DevTools and the DevTools of DevTools stall and become unresponsive for some time, then recovers but the Back/Forward/Stop/Refresh button and favicon loading indicator may remain broken. Looks like a Chrome bug, some kind of a temporary deadlock in handling the browser history.
2019-04-28 04:45:57 -07:00
Ivan Babak
d3e5fcd81c Rename Profiler types to disambiguate which is Frontend and Backend
Flow IDE shows the original type, not the file-scoped alias,
so it's confusing to see incompatible variables that have types
with the same name.

This started from `src/devtools/ProfilingCache.js` where
`ProfilingSummary` was incompatible, but I decided to make a bigger
change for consistency and to avoid similar mistakes in the future.
2019-04-28 04:40:39 -07:00
Ivan Babak
9f06bc345f Add Flow types for Fiber
Fixes https://github.com/bvaughn/react-devtools-experimental/issues/165
2019-04-28 04:18:27 -07:00
Ivan Babak
0b817777b4 Remove Agent addBridge: there can only be one bridge, add in constructor
Let's make impossible states truly impossible, and fix Flow types, too.

All three usages of Agent called addBridge right after constructing it.
Agent has one field `_bridge` which is force-typed as not-null despite
there's a temporary zone between the constructor end and addBridge start
where `_bridge` is null.
2019-04-28 04:03:28 -07:00
Ivan Babak
19bfba7943 Fix typo recursivelyIniitliazeTree -> recursivelyInitializeTree 2019-04-28 03:52:33 -07:00
Dan Abramov
d81d74b236 Add test coverage for nested Suspense 2019-04-26 20:04:28 +01:00
Dan Abramov
e5ed266873 Start using @babel/preset-env 2019-04-26 19:37:23 +01:00
Dan Abramov
2118b1fe1b Merge pull request #230 from gaearon/assert-maps
Assert empty maps when there are no roots
2019-04-26 18:15:04 +01:00
Dan Abramov
b6a55989f5 Assert empty maps when there are no roots 2019-04-26 17:47:00 +01:00
Brian Vaughn
c28acc5d47 Changed owners back button label to say 'Up to <...>' 2019-04-26 09:38:25 -07:00
Ivan Babak
281616f462 Support highlighting of all DOM elements of Fragments, not just first
Fixes https://github.com/bvaughn/react-devtools-experimental/issues/131

Uses the new function `findAllCurrentHostFibers`.

Removes dependency on React's `renderer.findHostInstanceByFiber` function
which used to highlight only the first DOM element of a Fragment.

Reworked `src/backend/views/Overlay` to support highlighting
more than one element rectangle annotated with one tooltip.
Fixed minor issues with the tooltip position calculation.
2019-04-26 01:22:49 -07:00
Brian Vaughn
707b44834f Merge pull request #213 from wldcordeiro/fix-firefox-perms
fix: correct permissions for Firefox
2019-04-25 19:11:39 -07:00
Brian Vaughn
043b73e0a8 Merge pull request #223 from bvaughn/owners-list-intermediate-components
Owners list view should drill through intermediate components
2019-04-25 15:10:08 -07:00
Brian Vaughn
09029acf00 Refactored owners list to use cached metadata (and added more tests) 2019-04-25 15:06:24 -07:00
Brian Vaughn
15eacae02c Moved owners list calculations into the store and added tests
This is being done to fix a drill-through bug, although the initial fix is perhaps not the most performant one. At least we have test coverage now and a temporary fix.
2019-04-25 15:06:24 -07:00
Brian Vaughn
b6d617ac7f Added 'back to owner' button when owners stack is collapsed 2019-04-25 15:05:39 -07:00
Brian Vaughn
e88819a22e Reverse direction of menu items within drop-down owners list 2019-04-25 14:10:51 -07:00
Dan Abramov
a0b1fb37fb Merge pull request #227 from gaearon/string-table
Transfer strings in a string table
2019-04-25 17:54:11 +01:00
Dan Abramov
1bea469db0 Remove unneeded variable 2019-04-25 17:46:48 +01:00
Dan Abramov
af2d1374c4 Let -> const 2019-04-25 17:39:13 +01:00
Dan Abramov
3920ebd0a1 Clarify encoding in overview 2019-04-25 17:32:46 +01:00
Dan Abramov
c8f8943c9a Transfer strings in a string table 2019-04-25 17:11:24 +01:00
Dan Abramov
c1363b7e17 Merge pull request #226 from gaearon/mutate-children
Improve performance by mutating the children array
2019-04-25 15:27:36 +01:00
Dan Abramov
2e423c21b0 Merge pull request #221 from gaearon/heuristic
Use a heuristic for locating roots
2019-04-25 15:22:34 +01:00
Dan Abramov
e1383c666d Allow to set tracked path multiple times
Fixes #225. This happens when you close and reopen DevTools while on the same page.
2019-04-25 14:57:39 +01:00
Dan Abramov
2993b168e5 Mutate the children array 2019-04-25 14:47:05 +01:00
Dan Abramov
d5319566a1 Fix broken start:prod command 2019-04-25 14:21:58 +01:00
Dan Abramov
80597a2377 Use a heuristic for locating roots 2019-04-24 23:02:41 +01:00
Dan Abramov
942f67c936 Merge pull request #220 from gaearon/removed-ids
Select parent node if selection is removed
2019-04-24 19:25:05 +01:00
Brian Vaughn
7bae48f00c Fixed minor CSS overflow issue 2019-04-24 09:07:53 -07:00
Brian Vaughn
c855a862c3 Merge pull request #218 from gaearon/bump-react
Bump React versions
2019-04-24 08:45:16 -07:00
Dan Abramov
949384f4ca Select parent node if selection is removed 2019-04-24 16:29:23 +01:00
Dan Abramov
52deada495 Bump React versions 2019-04-24 15:57:43 +01:00
Dan Abramov
54aecf487e Merge pull request #215 from bvaughn/persist-selection
Try to restore selection between reloads
2019-04-24 15:50:29 +01:00
Dan Abramov
f123763fe1 Read index off the Fiber 2019-04-24 15:05:33 +01:00
Dan Abramov
5d2d4213ec Delete stale paths 2019-04-24 15:05:21 +01:00
Dan Abramov
e050529c7d Read renderer ID from operations 2019-04-24 15:00:46 +01:00
Dan Abramov
26162988aa Fix tests 2019-04-24 14:37:46 +01:00
Dan Abramov
7eb7c5a350 Match Fibers to saved selection as they mount
This implements matching Fibers against the tracked selection path.

The algorithm is optimized to do as little checks as possible:

* When not trying to restore selection, we don't do anything
* When restoring selection, we only check .return pointers of new mounts
* Only when .return pointers match our current deepest match, we compare the frames
2019-04-24 14:37:46 +01:00
Dan Abramov
3bb837b683 Implement getPathForElement to serialize the selected path
Note this doesn't restore the selection yet.
2019-04-24 14:37:46 +01:00
Dan Abramov
b1a7007cc5 Keep track of root insertion order in the renderer
Normally, Fibers have key or index which we'll use to match things up between reloads. However, roots don't have such a concept. We'll use their insertion order as an approximation. If it's consistent, we'll be able to restore the selection.
2019-04-24 14:37:46 +01:00
Dan Abramov
d8abecdcf9 Persist and restore selection in agent
This implements the infrastructure for saving and restoring renderer-specific selection state in the session storage.

Note this doesn't actually implement the calculation and tracking of paths in the renderer. It only simulates that the renderer can do it. The actual implementation will come in a later commit.
2019-04-24 14:37:46 +01:00
Brian Vaughn
085d00e877 Merge pull request #196 from bvaughn/selected-element-suspense
Convert inspected element (right panel) to use Suspense
2019-04-23 18:33:05 -07:00
Brian Vaughn
7262a30cf3 Reverted optimization to avoid re-sending inspected fiber unless it committed 2019-04-23 18:04:25 -07:00
Brian Vaughn
0aa7d2f800 Reverted optimization to avoid re-sending inspected fiber unless it committed 2019-04-23 14:03:58 -07:00
Brian Vaughn
1e5c0b7856 Re-added the selection message 2019-04-23 13:43:38 -07:00
Brian Vaughn
4dcb34ea32 Fixed Flow error 2019-04-23 11:32:07 -07:00
Brian Vaughn
53c7338420 Updated flow-bin to attempt to fix the error 2019-04-23 09:00:25 -07:00
Brian Vaughn
d85f566d66 Merged master (tooltip changes) 2019-04-23 08:49:40 -07:00
Brian Vaughn
8b33dd673d Added @reach/tooltip 2019-04-23 08:41:52 -07:00
Brian Vaughn
ec7536704d Locked down canary versions 2019-04-22 19:32:16 -07:00
Brian Vaughn
7f1531044b Differentiate between no-change and no-element-found when inspecting element 2019-04-22 15:37:55 -07:00
Brian Vaughn
00872e2e51 Fixed suspense fallback issue by moving inspection message side effect before suspending render 2019-04-22 15:25:55 -07:00
Brian Vaughn
64bb2d31f9 Fixed bug with cache invalidation 2019-04-22 15:18:32 -07:00
Brian Vaughn
64bc49d523 Run first setState with explicit priority in case of non-React event handlers 2019-04-22 15:11:04 -07:00
Wellington Cordeiro
2d8c28733d fix: correct permissions for Firefox
remove the `background` permissions as it's not used by Firefox, but `activeTab` is and we needed
it.

fix #136
2019-04-22 15:12:33 -06:00
Brian Vaughn
e31ae91023 Removed duplicate scheduler module 2019-04-22 13:10:47 -07:00
Brian Vaughn
ba640df982 Merge branch 'master' into selected-element-suspense 2019-04-22 10:47:34 -07:00
Brian Vaughn
433934f55e Refactored TreeContext to use less memoization (based on feedback from Sebastian) 2019-04-22 10:39:21 -07:00
Brian Vaughn
d53ae2ea8a Refactored TreeContext to use less memoization (based on feedback from Sebastian) 2019-04-22 10:19:59 -07:00
Brian Vaughn
70be637d48 Don't schedule an update with React unless the curent element was invalidated 2019-04-22 09:37:55 -07:00
Brian Vaughn
5970bf4b40 Changed polling approach. Fixed remove event typo. 2019-04-22 09:37:55 -07:00
Brian Vaughn
3de18de25e Tried to implement two setState pattern, but it does not feel right 2019-04-22 09:37:55 -07:00
Brian Vaughn
957c389566 Adding polling and initial stab at not serializing duplicate inspected Element props 2019-04-22 09:37:34 -07:00
Brian Vaughn
c6b19cc141 Refactored insepected element cache to use the context API 2019-04-22 09:37:34 -07:00
Brian Vaughn
09b023a6e6 Naive suspense implementation for selected element panel
This commit leaves a few major things uunresolved:
* We aren't yet polling for updates
* We aren't yet using the two setState pattern
* The resource cache will grow unbounded over time because we aren't yet clearing items from it
* The renderer interface is not smart enough to avoid resending unchanged data between requests
2019-04-22 09:37:34 -07:00
Brian Vaughn
76b29ad0a9 Merge pull request #201 from gaearon/scroll-fix
Fix scrolling to selected row in collapsed mode
2019-04-22 09:37:15 -07:00
Brian Vaughn
52652f3456 Toggle method no longer emits 'mutated' event unless it mutated the store 2019-04-21 12:20:23 -07:00
Brian Vaughn
129466ed91 Yarn deploy sets production NODE_ENV 2019-04-21 09:05:55 -07:00
Brian Vaughn
a01fc44a78 Merge pull request #205 from bvaughn/@reach/tooltip
[BLOCKED] Use new @reach/tooltip
2019-04-21 09:01:23 -07:00
Brian Vaughn
91f74a5134 Fixed focus styles for OwnersStack dropdown toggle button 2019-04-21 08:59:24 -07:00
Brian Vaughn
09b995ab1c Tidied up CSS variables 2019-04-21 08:38:58 -07:00
Brian Vaughn
66df03d179 Renamed CSS var color-text-color to color-text 2019-04-21 08:29:51 -07:00
Brian Vaughn
8220df734c Tweaked hover and focus colors. Temporarily disabled Tooltip. 2019-04-21 08:23:20 -07:00
Brian Vaughn
a129089891 Tweaking focus/active colors and only showing focus rect on tab 2019-04-20 15:44:24 -07:00
Brian Vaughn
403bf49a78 Use new @reach/tooltip 2019-04-20 14:29:03 -07:00
Brian Vaughn
4218dcbf99 Merge pull request #203 from gaearon/push-ops
Push operations directly to the array
2019-04-20 14:27:53 -07:00
Brian Vaughn
740993baa9 Merge branch 'master' into push-ops 2019-04-20 14:26:46 -07:00
Brian Vaughn
72156c744f Merge pull request #204 from gaearon/no-weakset
Replace WeakSet with return pointer check
2019-04-20 14:23:59 -07:00
Brian Vaughn
94d9f61a7d Merge pull request #206 from gaearon/leading
Ignore leading edge of find-by-DOM throttle
2019-04-20 14:22:49 -07:00
Dan Abramov
006e03c38e Ignore leading edge of find-by-DOM throttle 2019-04-20 22:17:12 +01:00
Dan Abramov
c0d7023a88 Replace WeakSet with return pointer check 2019-04-20 21:42:30 +01:00
Dan Abramov
02a3a22753 Push operations directly to the array 2019-04-20 21:05:52 +01:00
Brian Vaughn
4b9082eea1 Changed style and position of search-for-element button to more closely matchin Chrome ( based on user testing) 2019-04-20 10:44:03 -07:00
Dan Abramov
4ffdffb598 Fix scrolling to selected row in collapsed mode 2019-04-20 16:20:03 +01:00
Brian Vaughn
3697ed2bba Merge pull request #199 from gaearon/another-check
Filter out dehydrated Suspense nodes
2019-04-20 08:00:14 -07:00
Brian Vaughn
da2ed30471 Merge pull request #200 from gaearon/clear-stuff
Clear DOM overlay on shutdown
2019-04-20 07:57:11 -07:00
Dan Abramov
d05106e364 Clear DOM overlay on shutdown 2019-04-20 14:34:13 +01:00
Dan Abramov
a186dc2e8d Filter out dehydrated Suspense nodes 2019-04-20 13:57:33 +01:00
Brian Vaughn
d7e8fccd1a Fixed an OVERVIEW typo 2019-04-19 07:54:30 -07:00
Brian Vaughn
5b0b9c9fbc Merge pull request #193 from gaearon/no-reorder
Don't reorder a single child
2019-04-19 07:51:51 -07:00
Dan
9a395c2f2c No need to reorder empty children either 2019-04-19 13:21:09 +01:00
Dan
fb8ad3486e Don't reorder a single child 2019-04-19 13:19:58 +01:00
Dan Abramov
2adbfd9607 Merge pull request #186 from gaearon/more-suspensey-stuff
Fix more Suspense issues
2019-04-19 13:18:50 +01:00
Dan
efb5855c8c Nits 2019-04-19 13:17:17 +01:00
Dan
3e657a6031 Prettier 2019-04-19 13:09:25 +01:00
Dan Abramov
37dd1ec8f8 Merge branch 'master' into more-suspensey-stuff 2019-04-19 13:09:01 +01:00
Brian Vaughn
f286c0d901 Increased contrast for selected+inactive background color 2019-04-18 18:19:10 -07:00
Brian Vaughn
c6a27d1fea Merge branch 'master' of github.com:bvaughn/react-devtools-experimental 2019-04-18 18:13:43 -07:00
Brian Vaughn
c0b414d581 Node scripts should fail if not NODE_ENV specified 2019-04-18 18:13:34 -07:00
Brian Vaughn
131e2e52db Merge pull request #188 from gaearon/humble-search
Don't select search result unless user does something
2019-04-18 18:04:28 -07:00
Brian Vaughn
60b614f527 Renamed TREE_OPERATION_RESET_CHILDREN -> TREE_OPERATION_REORDER_CHILDREN 2019-04-18 17:59:53 -07:00
Brian Vaughn
24736e4ff5 Hardened reorder child invariants 2019-04-18 17:58:48 -07:00
Dan Abramov
3d09b4aaa5 Don't select search result unless user does something 2019-04-19 01:54:39 +01:00
Brian Vaughn
21afd6ea20 Merge pull request #184 from bvaughn/harden
Harden assertions
2019-04-18 17:50:17 -07:00
Dan Abramov
b0c0a11f1b Revert accidental change 2019-04-19 01:41:00 +01:00
Dan Abramov
72e67b343f Add Concurrent Mode test 2019-04-19 01:18:25 +01:00
Dan Abramov
534dfb0ca2 Optimize: don't recreate ID arrays all the time 2019-04-19 01:13:25 +01:00
Dan Abramov
8830ba890c Fix more Suspense traversal bugs 2019-04-19 01:09:57 +01:00
Dan Abramov
346b628b43 Add failing tests for Suspense with same type 2019-04-19 00:36:55 +01:00
Dan Abramov
d44bf272ad Refactor: materialize typed array in one place 2019-04-19 00:32:29 +01:00
Dan Abramov
ccecde76d1 Harden assertions 2019-04-19 00:29:49 +01:00
Brian Vaughn
3dfbf8ad6b Added a new invariant to the store (bridge operations handler) 2019-04-18 15:40:50 -07:00
Brian Vaughn
7930bad8c6 Deploy production extension builds 2019-04-18 14:45:24 -07:00
Brian Vaughn
e2aedb2ea7 Merge pull request #181 from gaearon/consoleerror
Fail tests on errors in renderer
2019-04-18 10:08:44 -07:00
Dan Abramov
d0b5e3a7cb Update setupTests.js 2019-04-18 18:06:34 +01:00
Brian Vaughn
d6e829d7a5 Fixed bug in reset-children to properly calculate new root weight 2019-04-18 09:54:26 -07:00
Brian Vaughn
89f7a0c048 Merge pull request #182 from bvaughn/suspense-toggle
Fixed a Suspense toggling bug that incorrectly impacted tree weight
2019-04-18 09:45:22 -07:00
Brian Vaughn
358e63ac3d Fixed a Suspense toggling bug that incorrectly impacted tree weight 2019-04-18 09:38:41 -07:00
Dan Abramov
8c5794eab3 Fail tests on errors in renderer 2019-04-18 17:03:04 +01:00
Brian Vaughn
b45e743f52 Merge pull request #180 from gaearon/suspense-more-fixes
Fix unmounting in Concurrent Mode
2019-04-18 08:52:30 -07:00
Dan Abramov
6a13ffd231 Traverse the previous current tree when switching from primary to fallback 2019-04-18 16:22:50 +01:00
Dan Abramov
24309fde06 Add failing Concurrent Mode stress tests 2019-04-18 16:22:50 +01:00
Dan Abramov
0f44e9fb98 Move sync stress tests in their own file 2019-04-18 16:22:50 +01:00
Brian Vaughn
456e937b83 Merge pull request #178 from gaearon/removal-integrity
Assert removal happens in the right order
2019-04-18 08:16:22 -07:00
Dan Abramov
d02d93712e Assert removal happens in the right order 2019-04-18 16:02:08 +01:00
Brian Vaughn
08279fb342 Merge pull request #174 from robertknight/mousedown-tab-select
Select tab when the mouse is pressed
2019-04-18 08:00:01 -07:00
Brian Vaughn
d995f19339 Merge pull request #175 from lucasecdb/assign-timeout
Assign timeoutID to avoid multiple requests
2019-04-18 07:56:32 -07:00
Lucas Cordeiro
6df050e726 Assign timeoutID to avoid multiple requests 2019-04-18 06:46:06 -03:00
Robert Knight
c2865dbab9 Select tab when the mouse is pressed
Selecting the tab when the mouse is pressed rather than only when it is
released makes tab switching feel faster and also matches how the Chrome dev
tools behave.

The previous tab selection handler which listens for the radio button's
selection has been kept for the benefit of interaction methods which
don't trigger the mousedown handler.
2019-04-18 08:16:52 +01:00
Brian Vaughn
29811cd24e Added legacy (v15) tests 2019-04-17 15:30:20 -07:00
Brian Vaughn
7ab93402a8 Initial support for v15+ via new legaacy renderer 2019-04-17 14:36:15 -07:00
Brian Vaughn
0d932d770b Merge pull request #168 from bvaughn/collapse-nodes-by-default
Configurable tree default collapsed/expanded behavior
2019-04-17 13:29:25 -07:00
Brian Vaughn
75e1e1431b Expanded the reorder tests slightly 2019-04-17 13:11:18 -07:00
Brian Vaughn
634d4fece2 Added more inline comments 2019-04-17 13:03:18 -07:00
Brian Vaughn
29d43a2230 Merge pull request #171 from bvaughn/improve-contrast-light-mode
Improve contrast for light mode
2019-04-17 11:44:25 -07:00
Brian Vaughn
3fb9f6cdaa Improve contrast for light mode 2019-04-17 11:40:55 -07:00
Brian Vaughn
c107e03132 Flow fix 2019-04-17 09:45:03 -07:00
Brian Vaughn
74be389124 Fixed a bug with re-ordering of children within a collapsed node 2019-04-17 09:39:54 -07:00
Brian Vaughn
178e89927a Fixed some edge cases with collapsed by default. Still some bugs existing. 2019-04-17 07:45:33 -07:00
Brian Vaughn
037bb0034c Throw if root node is collapsed 2019-04-16 14:10:06 -07:00
Brian Vaughn
4b64d7c017 Support configurable node/tree collapsed by default behavior 2019-04-16 13:59:36 -07:00
Dan Abramov
85179fe4a7 Merge pull request #164 from gaearon/fix-lots-of-stuff
Fix reordering and Suspense logic
2019-04-16 19:11:28 +01:00
Dan Abramov
3a6d656090 Remove unnecessary condition 2019-04-16 19:10:39 +01:00
Dan Abramov
9182d0b0aa Bump alpha to get Andrew's fix 2019-04-16 19:09:52 +01:00
Dan Abramov
58bb7cea41 Remove unused lines 2019-04-16 18:21:40 +01:00
Dan Abramov
8576c85b0d Move stress tests to their own file 2019-04-16 18:10:15 +01:00
Dan Abramov
d4db178d33 Bump to canary 2019-04-16 17:39:26 +01:00
Dan Abramov
3cf67ab859 Harden the tests and fix Flow 2019-04-16 17:02:42 +01:00
Dan Abramov
b1dea26251 Fix the remaining issue when primary child is null
This lets us unlock the rest of the Suspense test.
2019-04-16 16:57:10 +01:00
Dan Abramov
fe21ee7ca0 Enable part of Suspense test that was failing before
This PR fixes it.
2019-04-16 16:47:26 +01:00
Dan Abramov
f4e223bceb When resetting Suspense children, use the fallback child set if needed
This fixes the bug I introduced in the previous refactor which Suspense test caught.
2019-04-16 16:45:56 +01:00
Dan Abramov
dd935ea178 Propagate the need to reset children to closest visible Fiber
This fixes the bug.
2019-04-16 16:34:08 +01:00
Dan Abramov
57e8513a30 Refactor: remove early returns from updateFiberRecursively
This doesn't change any logic, just the shape of the control flow.
I want to unify some branches at the end, so it's easier if there are no early returns.
2019-04-16 16:34:08 +01:00
Dan Abramov
f4c3008cf5 Refactor: split recordUpdate() into profiling and reorder
This doesn't change the actual algorithm but splits unrelated parts.
2019-04-16 16:34:08 +01:00
Dan Abramov
b081ffc518 Add stress test for reordering 2019-04-16 16:34:08 +01:00
Brian Vaughn
20193f03c0 Merge pull request #162 from gaearon/suspense-test
Add Suspense stress test
2019-04-16 07:49:11 -07:00
Dan
d89f79d6e6 Add Suspense stress test 2019-04-16 00:14:49 +01:00
Brian Vaughn
8c974ae432 Flow and lint fix 2019-04-15 09:43:52 -07:00
Brian Vaughn
97636fa7fc Merge pull request #161 from gaearon/fast
Don't materialize typed array until the transfer
2019-04-15 09:40:33 -07:00
Brian Vaughn
2b3ecc63b3 Merge pull request #158 from gaearon/stress-test
Add a stress test for tree traversal
2019-04-15 09:34:40 -07:00
Dan Abramov
6b9b80faac Don't materialize typed array until the transfer 2019-04-15 16:27:19 +01:00
Brian Vaughn
b3546e0e02 Merge pull request #160 from gaearon/add-prod-shell
Add production mode to dev shell
2019-04-15 07:40:39 -07:00
Dan Abramov
947e3c2c04 Add production mode to dev shell 2019-04-15 15:39:25 +01:00
Brian Vaughn
7489b8508b Merge pull request #159 from gaearon/l-to-the-r-to-the-u
Use LRU for encoded strings
2019-04-15 07:09:10 -07:00
Dan Abramov
255385d255 Use LRU for encoded strings 2019-04-15 14:42:12 +01:00
Dan
f569d27f86 Add a stress test for tree traversal 2019-04-15 01:52:15 +01:00
Brian Vaughn
b76372c93d Fixed an edge case profiling bug where the number of commits was wrong 2019-04-13 18:29:39 -07:00
Brian Vaughn
7f6fdfea95 Add package commands for creating dev builds for easier debugging 2019-04-13 18:25:56 -07:00
Brian Vaughn
00f6466ec1 Temporarily disabled hooks lint failure for Tree useEffect 2019-04-13 15:49:06 -07:00
Brian Vaughn
97f089bdfe Merge pull request #148 from gaearon/scroll-consistent
Consistently scroll component name into view
2019-04-13 15:39:25 -07:00
Brian Vaughn
518f3d75f8 Tweaked an inline comment. 2019-04-13 15:38:56 -07:00
Brian Vaughn
b2cf896e8c Fixed misplaced padding in Tree 2019-04-13 15:33:10 -07:00
Brian Vaughn
236f47f073 Tweaked .eslintignore and .gitignore 2019-04-13 15:32:26 -07:00
Brian Vaughn
86f9293376 Merge pull request #154 from gaearon/resize-hilite
Adjust highlighting on window resize
2019-04-13 15:25:17 -07:00
Brian Vaughn
d5266f9409 Merge pull request #155 from gaearon/view-dom-inspect
View DOM button opens Elements tab
2019-04-13 15:23:09 -07:00
Brian Vaughn
453a06a465 Merge pull request #150 from gaearon/bump-hooks-plugin
Bump React Hooks plugin
2019-04-13 15:20:08 -07:00
Brian Vaughn
826cac0070 Merge pull request #149 from gaearon/dont-reset
Don't reset selected item on search mismatch or exit
2019-04-13 15:19:38 -07:00
Dan
ce335b8975 View DOM button opens Elements tab 2019-04-13 18:59:47 +01:00
Dan
6d53a2ec10 Adjust highlighting on window resize 2019-04-13 18:24:59 +01:00
Dan
9162b7165a Prefer to keep the start anchor visible 2019-04-13 16:49:10 +01:00
Dan
6d70028a26 Bump React Hooks plugin 2019-04-13 16:38:34 +01:00
Dan
55dcfe25e8 Don't reset selected item on search mismatch or exit 2019-04-13 16:20:16 +01:00
Brian Vaughn
ca7eb3c829 Changed highlight-on-search behavior to use TreeContext 2019-04-12 18:14:46 -07:00
Dan Abramov
097d0386b1 Track search navigation in DOM 2019-04-12 18:14:46 -07:00
Brian Vaughn
7145c78325 Merge pull request #147 from gaearon/no-propagation
Polish some mouse interactions
2019-04-12 18:09:16 -07:00
Dan
ba9c763954 Consistently scroll component name into view 2019-04-13 01:58:05 +01:00
Dan
454bcf1e01 Polish some mouse interactions 2019-04-13 01:07:35 +01:00
Brian Vaughn
1e08261975 Added missing instruction to Chrome install steps 2019-04-12 15:08:14 -07:00
Brian Vaughn
818255dfde Merge pull request #145 from bvaughn/deploy-chrome-updates
Auto-update Chrome extension
2019-04-12 15:02:11 -07:00
Brian Vaughn
801bb5e33a Udpated Firefox installation instructions 2019-04-12 14:45:39 -07:00
Brian Vaughn
670d1348f1 Chrome build+deploy script auto-increment a prerelease version 2019-04-12 14:42:34 -07:00
Brian Vaughn
26361427ae Auto-update Chrome extension 2019-04-12 13:46:05 -07:00
Brian Vaughn
9c1dad5059 react-window 1.8.0 2019-04-12 10:57:56 -07:00
Brian Vaughn
b18c836ef5 Merge branch 'smart-scroll' of https://github.com/gaearon/react-devtools-experimental into gaearon-smart-scroll 2019-04-12 10:56:27 -07:00
Brian Vaughn
dbd1d6b0bd Firefox only supports peristent background extensions so I've removed the persistent:false flag 2019-04-12 10:20:23 -07:00
Dan Abramov
403f150ade Use smart scrolling 2019-04-12 18:13:26 +01:00
Brian Vaughn
8f17ade7e5 Circle CI config changes 2019-04-12 09:27:53 -07:00
Brian Vaughn
af8a5d9311 Added devEngines entry to package.json 2019-04-12 09:24:16 -07:00
Brian Vaughn
a57b6dbef5 Merge pull request #133 from bvaughn/tests
Automated tests [WIP]
2019-04-12 09:22:11 -07:00
Brian Vaughn
be930d5490 Use Circle CI to run lint, prettier, flow, and tests 2019-04-12 09:17:42 -07:00
Brian Vaughn
7bb2299de4 Moved __DEV__ setup from setupTests to setupEnv 2019-04-12 08:55:29 -07:00
Brian Vaughn
e0ffa2b88d Moved a few vars inside of the setupTest beforeEach block 2019-04-12 08:55:29 -07:00
Brian Vaughn
158b0b5567 Added expand/collapse tests; chronologically ordered snapshots 2019-04-12 08:55:29 -07:00
Brian Vaughn
16a7119bf2 Added a simple Suspense test 2019-04-12 08:55:29 -07:00
Brian Vaughn
4ad85b26c0 Cleaned up setup/polyfills 2019-04-12 08:55:29 -07:00
Brian Vaughn
81183b1492 Named snapshots. Tests use act() abstraction. 2019-04-12 08:55:29 -07:00
Brian Vaughn
5d6a2082cc Updated React test utils for newer version of act() 2019-04-12 08:55:29 -07:00
Brian Vaughn
1bdae952b5 Added separate mount+update tests 2019-04-12 08:55:29 -07:00
Brian Vaughn
25e918b4d9 Added [root] indicator to Store snapshot reprensentation 2019-04-12 08:55:29 -07:00
Brian Vaughn
4926d160d6 Removed unnecessary configurable Bridge batch duration 2019-04-12 08:55:29 -07:00
Brian Vaughn
9fb794b6ed Added multi-test setup logic 2019-04-12 08:55:29 -07:00
Brian Vaughn
7621df5baf Initial example test. Will iterate from here. 2019-04-12 08:55:29 -07:00
Brian Vaughn
7aadcdf624 Use :hidden attribute to collapse props/hooks 2019-04-12 08:53:41 -07:00
Brian Vaughn
ae7ea00e06 Fix small sizing issue with expand collapse toggle 2019-04-12 08:42:27 -07:00
Brian Vaughn
da4accda31 Added expand/collapse toggles to custom hooks 2019-04-12 08:39:03 -07:00
Brian Vaughn
94810b2b5a Add Git revision to extension manifests 2019-04-11 19:06:07 -07:00
Brian Vaughn
9a0cf68a4d Add Git revision to build version 2019-04-11 18:44:44 -07:00
Brian Vaughn
3ea5fac959 Enable text to wrap within error boundary stacks 2019-04-11 18:29:06 -07:00
Brian Vaughn
f32b65d7b0 Merge pull request #135 from lucasecdb/fiber-info-overflow
Fix fiber info sidepanel not scrollable
2019-04-11 18:21:57 -07:00
Lucas Cordeiro
2671e7e0e0 Fix fiber info sidepanel not scrollable 2019-04-11 21:38:57 -03:00
Brian Vaughn
9642d26674 Added ErrorBoundary with GitHub bug link 2019-04-11 17:19:16 -07:00
Dan Abramov
da508fc23f Merge pull request #126 from bvaughn/js-hover
Ignore hover when navigating with keyboard
2019-04-12 01:16:26 +01:00
Brian Vaughn
367249c175 Don't drill into owners list if no owner metadata is available 2019-04-11 14:00:27 -07:00
Brian Vaughn
75657c81e8 Merge branch 'keyboard-stuff' of https://github.com/gaearon/react-devtools-experimental 2019-04-11 11:55:39 -07:00
Dan Abramov
38b7cf5693 Ignore hover when navigating with keyboard 2019-04-11 13:27:49 +01:00
Dan Abramov
0281a0d905 Add a missing dep 2019-04-11 13:20:32 +01:00
Brian Vaughn
a5eb96fbc0 Merge pull request #134 from sophiebits/bridge-batch
Improve bridge batching logic
2019-04-10 17:21:30 -07:00
Sophie Alpert
7c13ea2f2b Improve bridge batching logic
Fixes #132.
2019-04-10 16:31:11 -07:00
Brian Vaughn
40469a190e Fixed horizontal alignment for collapsable hooks 2019-04-10 12:47:51 -07:00
Brian Vaughn
84a5a13525 Editable name not text-selectable 2019-04-10 12:37:20 -07:00
Brian Vaughn
e9f385591e Double clicking on a name toggles expanded state in KeyValue 2019-04-10 12:36:26 -07:00
Brian Vaughn
4f254c0a05 Refactored KeyValue toggle so columns with toggles align better below those without 2019-04-10 11:44:45 -07:00
Dan Abramov
952c8cda00 Fix a bug that caused it to jump over nodes when pressing too fast 2019-04-10 19:30:45 +01:00
Brian Vaughn
f0fb1805fe Added new color-expand-collapse-toggle CSS var 2019-04-10 11:03:32 -07:00
Brian Vaughn
3e19b164b5 Merge branch 'collapse-props' of https://github.com/lucasecdb/react-devtools-experimental into lucasecdb-collapse-props 2019-04-10 11:03:04 -07:00
Lucas Cordeiro
944a6192e2 Use button instead of div for a11y 2019-04-10 15:01:05 -03:00
Dan Abramov
6420f11d65 Left and right arrows only traverse parents 2019-04-10 18:49:52 +01:00
Lucas Cordeiro
2d516199ea Update opener icon and remove negative margin 2019-04-10 14:47:39 -03:00
Brian Vaughn
0aacc2547e Merge pull request #123 from gaearon/focus-keyboard
Picking a DOM node focuses the tree
2019-04-10 10:31:05 -07:00
Lucas Cordeiro
99a1e07aa6 Fix flow type 2019-04-10 14:28:48 -03:00
Lucas Cordeiro
0f955980a3 Add collapsible icon for object and array types 2019-04-10 14:28:48 -03:00
Dan Abramov
1c381c588a Picking a DOM node focuses the tree 2019-04-10 18:27:40 +01:00
Brian Vaughn
88e51adc35 Merge pull request #122 from gaearon/prevent
Prevent default on all key navigations
2019-04-10 10:17:12 -07:00
Brian Vaughn
4b0424fbed Flow fix 2019-04-10 10:16:09 -07:00
Brian Vaughn
268a7cb5b4 Moved blur/focus up to the AutoSizer wrapper and removed an effect+ref 2019-04-10 10:14:21 -07:00
Brian Vaughn
caa74472f2 Replaced nested ternary 2019-04-10 10:01:03 -07:00
Brian Vaughn
6836f15924 Tweaked inactive CSS colors 2019-04-10 09:56:21 -07:00
Brian Vaughn
d9ef0839a4 Merge branch 'inactive-window' of https://github.com/lucasecdb/react-devtools-experimental into lucasecdb-inactive-window 2019-04-10 09:51:29 -07:00
Dan Abramov
5b480a85cb Prevent default on all key navigations 2019-04-10 17:46:34 +01:00
Brian Vaughn
11c03bf7bc Merge pull request #120 from gaearon/mutation-index
Update selected index after mutation
2019-04-10 09:35:00 -07:00
Brian Vaughn
7263e768e5 Merge pull request #116 from bvaughn/issues/105
Add collapse/toggle UI to Tree
2019-04-10 09:31:12 -07:00
Brian Vaughn
56be358847 Merge pull request #114 from gaearon/lazy-sync
Send the bridge sync event lazily
2019-04-10 09:28:54 -07:00
Dan Abramov
f1a8bd2923 Update selected index after mutation 2019-04-10 17:28:36 +01:00
Brian Vaughn
f89f2b2146 Reverted misguided index/collapsed behavior 2019-04-10 09:23:24 -07:00
Brian Vaughn
ba46f2df0a Merge pull request #118 from gaearon/required-title
Add missing Button titles
2019-04-10 09:10:24 -07:00
Brian Vaughn
98240f18ae Merge pull request #117 from gaearon/hide-shell
Put DevTools in dev shell above the inspector
2019-04-10 09:10:10 -07:00
Brian Vaughn
74c9904e5d Rewrote weightDelta calculation to be more readable based on PR feedback 2019-04-10 08:59:43 -07:00
Brian Vaughn
dd84e8ff2b Newly selected components always auto-expand their ancestors 2019-04-10 08:57:42 -07:00
Brian Vaughn
1f7f0ea691 Update Store.getIndexOfElementID to take isCollapsed into account 2019-04-10 07:53:06 -07:00
Brian Vaughn
b004a79415 Reverted some unnecessary changes to TreeContext after Dan's PR 101 was merged 2019-04-10 07:45:45 -07:00
Brian Vaughn
102267b1d6 Renamed _numElements attribute based on PR feedback 2019-04-10 07:42:32 -07:00
Brian Vaughn
61203f77cf Hide toggle arrows in owners list mode 2019-04-10 07:42:32 -07:00
Brian Vaughn
55b3635f28 Left/right arrow toggles node collapsed state as well 2019-04-10 07:42:32 -07:00
Brian Vaughn
f7212d8035 Upgrade react-window to fix a scroll-to bug 2019-04-10 07:42:32 -07:00
Brian Vaughn
4c522c4c38 Selected search result auto-opens collapsed nodes when necessary.
Also fixed an unrelated bug about when we reset search index when text changes.
2019-04-10 07:42:32 -07:00
Brian Vaughn
b6df86c90c Added toggle button to Tree > Element views 2019-04-10 07:38:40 -07:00
Brian Vaughn
79827c535b Added isToggled boolean to tree nodes and toggleIsCollapsed() method to Store 2019-04-10 07:38:40 -07:00
Brian Vaughn
0decb17837 Merge pull request #101 from gaearon/find-nit
Pressing next forces search to select
2019-04-10 07:38:28 -07:00
Dan Abramov
1102fc5c11 Refactor: extract a variable 2019-04-10 15:25:03 +01:00
Dan Abramov
3eca0bbe61 Use heuristic suggested by @sophiebits 2019-04-10 15:08:13 +01:00
Dan
07299828c9 Pressing next forces search to select 2019-04-10 14:57:39 +01:00
Dan Abramov
75a4312d87 Add missing Button titles 2019-04-10 14:40:41 +01:00
Dan Abramov
84478a41ff Put DevTools in dev shell above the inspector 2019-04-10 14:26:33 +01:00
Brian Vaughn
6d222080ad Format logElementToConsole() slightly 2019-04-09 18:13:11 -07:00
Lucas Cordeiro
1c57ca0a1c Use focus state from elements tree instead of ownerDocument 2019-04-09 19:04:03 -03:00
Lucas Cordeiro
26106a4b9d Add check for inactive window on selected element 2019-04-09 19:03:59 -03:00
Dan Abramov
43bb821f60 Send the bridge sync event lazily 2019-04-09 20:04:33 +01:00
Brian Vaughn
edc598e62a Fixed Tree minWidth initial case to fill 100% width 2019-04-09 11:43:49 -07:00
Brian Vaughn
1cc219009a Tweaked owners stack CSS to fix another overflow issue 2019-04-09 11:12:39 -07:00
Brian Vaughn
49f6a22b5b Remember max Tree width as new nested items are rendered 2019-04-09 10:58:43 -07:00
Brian Vaughn
d6bd3dc503 Fixed owner stack size calculation bug that sometimes caused bad overflow 2019-04-09 10:18:04 -07:00
Brian Vaughn
f1fc4b0331 Merge pull request #108 from bvaughn/reach-ui-menubutton
Use @reach MenuButton for owner stack menu [WIP]
2019-04-09 08:58:08 -07:00
Brian Vaughn
dbf6942512 Added (local) fork of @reach/portal to unblock OwnersStack MenuButton PR 2019-04-09 08:54:43 -07:00
Brian Vaughn
a29ab9ab79 Tree arrow navigation respects event.defaultPrevented
This prevents Reach MenuButton operations from also changing the tree selection in the background
2019-04-09 08:37:34 -07:00
Brian Vaughn
163bc234df Disable text selection for OwnersStack buttons 2019-04-09 08:36:54 -07:00
Brian Vaughn
db629fa073 Updated OwnersStack CSS to properly override React styles 2019-04-09 08:30:24 -07:00
Dan Abramov
4bde8f6503 Merge pull request #103 from gaearon/sad-one-way
Make DOM selection binding one-way
2019-04-09 13:25:08 +01:00
Dan Abramov
153666b484 Merge pull request #107 from sophiebits/flicker
pointer-events: none to fix flicker on Overlay "tip"
2019-04-09 11:40:47 +01:00
Brian Vaughn
ba99444515 Use @reach MenuButton for owner stack menu 2019-04-08 18:34:48 -07:00
Sophie Alpert
a2d84fa613 pointer-events: none to fix flicker on Overlay "tip"
If click-to-inspect then hover an element in just the right place, it flickers between two elements because this "tip" element catches the hover. This should fix it.
2019-04-08 18:26:30 -07:00
Dan
72eccb465d Make DOM selection binding one-way 2019-04-09 01:30:40 +01:00
Dan Abramov
267ab34fbd Merge pull request #99 from gaearon/sync-tabs
Sync DevTools Elements and Components tabs
2019-04-08 23:55:16 +01:00
Dan
3b793953b1 Keep DOM selection if last $0 resolves to same component 2019-04-08 23:46:47 +01:00
Dan
436912ab2d Remove unnecessary logic 2019-04-08 23:35:01 +01:00
Dan
7aecd58d81 Nits 2019-04-08 23:28:31 +01:00
Dan
c91676b557 Don't change browser selection unless React selection changed 2019-04-08 21:57:13 +01:00
Brian Vaughn
5db5e40bf1 Replaced Agent setInterval with throttle+memoize 2019-04-08 13:50:04 -07:00
Dan Abramov
388677fcbc Merge branch 'master' into continuous-select 2019-04-08 20:50:58 +01:00
Dan Abramov
4a301bd0e0 Sync DevTools Elements and Components tabs 2019-04-08 20:41:01 +01:00
Brian Vaughn
44ecff31e3 Fixed an unpleasant interaction with owners modal "..." button 2019-04-08 12:20:45 -07:00
Brian Vaughn
e43cfa0239 Don't re-measure owners stack sizes unnecessarily 2019-04-08 12:05:07 -07:00
Brian Vaughn
174125c854 Merge branch 'master' of github.com:bvaughn/react-devtools-experimental 2019-04-08 11:41:56 -07:00
Brian Vaughn
58ae3c63a8 Added export-log icon. Removed unnecessary variable assignment. 2019-04-08 11:41:25 -07:00
Dan Abramov
ab89d6500f Fix missing key 2019-04-08 19:01:28 +01:00
Brian Vaughn
fefb2bc99b Merge branch 'inspect-log' of https://github.com/gaearon/react-devtools-experimental into gaearon-inspect-log 2019-04-08 10:41:58 -07:00
Brian Vaughn
b3ba758798 Updated flow-bin 2019-04-08 10:40:46 -07:00
Brian Vaughn
7115408751 Added for itemData 2019-04-08 10:40:40 -07:00
Dan Abramov
5b120d6b24 Add a separate button for logging values 2019-04-08 18:39:37 +01:00
Dan Abramov
b176cd4414 Refactor: split inspectElementRaw 2019-04-08 18:37:36 +01:00
Brian Vaughn
14105e865a Merge pull request #92 from gaearon/highlight-on-hover
Select DOM nodes on hover
2019-04-08 10:23:56 -07:00
Dan Abramov
52014671bf Make Flow happy 2019-04-08 18:03:48 +01:00
Dan Abramov
c6ee445ea9 Address review 2019-04-08 18:00:48 +01:00
Dan Abramov
6538e7141a Add a comment 2019-04-08 17:58:12 +01:00
Dan Abramov
39223239bb Select DOM nodes on hover 2019-04-08 17:58:12 +01:00
Dan Abramov
cb164eb9fb Merge pull request #91 from gaearon/fix-scroll
Fix spurious autoscroll
2019-04-08 17:51:35 +01:00
Brian Vaughn
c619d56b1c Merge pull request #93 from gaearon/keep-mounted
Preserve state when switching tabs
2019-04-08 08:43:31 -07:00
Brian Vaughn
e86d7b51ea Merge pull request #94 from gaearon/rendered-by
Rename "owner stack" label to "rendered by"
2019-04-08 08:20:56 -07:00
Dan Abramov
edfab66104 Rename "owner stack" label to "rendered by" 2019-04-08 15:40:40 +01:00
Dan Abramov
132529da79 Preserve state when switching tabs 2019-04-08 15:29:51 +01:00
Dan
0a6d637619 Fix spurious autoscroll 2019-04-08 00:51:31 +01:00
Brian Vaughn
2ba3ee6c1c Merge pull request #86 from gaearon/owner-stack-id
Preserve selection on exiting owner mode
2019-04-07 15:42:43 -07:00
Brian Vaughn
7e2ef6a34e Merge pull request #87 from gaearon/bump-overscan
Bump overscan to 3
2019-04-07 15:36:20 -07:00
Brian Vaughn
77267e8544 Fixed Toggle Flow prop types 2019-04-07 15:34:35 -07:00
Brian Vaughn
f61507158e Merge branch 'hristo-kanchev-owner-stack-enhancement' 2019-04-07 15:33:42 -07:00
Brian Vaughn
e489c8ac8e Owners stack modal behaves and looks more like a modal 2019-04-07 15:32:13 -07:00
Brian Vaughn
2ac815784b Removed unnecessary layout effect in favor of a setState 2019-04-07 15:19:17 -07:00
Dan Abramov
a9c20f0b36 Merge pull request #88 from gaearon/remove-ring
Remove tree focus ring
2019-04-07 20:16:06 +01:00
Brian Vaughn
ae2e8128bd Merge pull request #89 from gaearon/toggle-fix
Pass Toggle label through
2019-04-07 10:54:35 -07:00
Dan
5a118701b0 Pass Toggle label through 2019-04-07 18:44:11 +01:00
Brian Vaughn
2e5e88e127 Cleaned up is-overflowing hook and dependencies 2019-04-07 10:34:44 -07:00
Dan
2607b39fe1 Remove tree focus ring 2019-04-07 18:20:34 +01:00
Brian Vaughn
5b6dbb8dd7 Replaced some passive effects with layout effects to avoid flash of overflowed owners 2019-04-07 10:01:18 -07:00
Brian Vaughn
df00a9639e Removed some unnecessary functions 2019-04-07 09:58:34 -07:00
Dan
a42a3a2d72 Bump overscan 2019-04-07 17:55:27 +01:00
Brian Vaughn
850dda0fb9 Cleaned up an old Overlay helper function 2019-04-07 09:53:34 -07:00
Brian Vaughn
252a87efe5 Use 'classnames' in TabBar to simplify an attribute 2019-04-07 09:51:54 -07:00
Brian Vaughn
9255ad1025 Replaced "colon" icon with more standard 3-dot "more" 2019-04-07 09:46:44 -07:00
Dan
f2951fb51f Preserve selection on exiting owner mode 2019-04-07 17:43:10 +01:00
Brian Vaughn
9a2f9ac880 Moved getElementDimensions() back into Overlay component 2019-04-07 09:42:52 -07:00
Brian Vaughn
d686b9d890 Merge branch 'owner-stack-enhancement' of https://github.com/hristo-kanchev/react-devtools-experimental into hristo-kanchev-owner-stack-enhancement 2019-04-07 09:13:33 -07:00
Brian Vaughn
2b868821d5 Improved keyboard navigation for tabs, interactions, and fiber-commits 2019-04-07 09:00:52 -07:00
Brian Vaughn
44c0febd23 Profiler shows commit times and durations for selected fiber 2019-04-07 08:36:37 -07:00
Hristo Kanchev
2620050abf Removed unneeded min-height. Using throttle for resize function. 2019-04-07 11:48:35 +02:00
Hristo Kanchev
ce04f531d4 Implemented new OwnerStack UI enhancement 2019-04-07 11:37:12 +02:00
Brian Vaughn
5334249bda Fixed a typo in flamegraph duration label 2019-04-06 18:01:44 -07:00
Brian Vaughn
d766d3b2e5 Throttle screenshots to reduce impact on performance. 2019-04-06 13:58:55 -07:00
Brian Vaughn
bfcef10af3 Merge pull request #84 from gaearon/dead
Remove dead code
2019-04-06 13:37:50 -07:00
Dan
9fc2a3400c Remove dead code 2019-04-06 21:36:08 +01:00
Dan
99593444b9 Address review 2019-04-06 21:30:57 +01:00
Dan
785bb9f56c Continuously update tree selection in DOM inspection mode 2019-04-06 20:27:36 +01:00
Dan Abramov
985fe59826 Merge pull request #81 from gaearon/overlay-owner
Show owner in DOM highilght overlay
2019-04-06 18:26:50 +01:00
Dan
5eec8aed33 Nit 2019-04-06 18:26:17 +01:00
Dan
ab9c1b84c8 Show owner in DOM highilght overlay 2019-04-06 17:07:06 +01:00
Dan Abramov
72d9f0597a Merge pull request #71 from gaearon/suspense-special
Fix Suspense fragment edge cases
2019-04-05 23:59:17 +01:00
Dan
d3d5c050bd Naming 2019-04-05 23:45:34 +01:00
Dan
7a03c5a885 Update the commit tree to assume operations do not repeat 2019-04-05 23:42:02 +01:00
Dan
80d9d8d841 Fix profiler and nits 2019-04-05 23:34:27 +01:00
Dan
0f536bba5c Rewrite the Suspense logic 2019-04-05 23:12:57 +01:00
Dan Abramov
d6257d382d Expand the test fixture 2019-04-05 21:49:37 +01:00
Dan
9bcd5b2576 Fix Suspense fragment edge cases 2019-04-05 21:49:37 +01:00
Dan Abramov
387ad54d80 Merge pull request #75 from gaearon/fix-double-add
Fix double-adding fibers when traversing
2019-04-05 18:45:42 +01:00
Dan Abramov
2a5b8a9206 Hard crash 2019-04-05 18:41:26 +01:00
Dan Abramov
96a7adf49e Add error logs in __DEBUG__ 2019-04-05 18:27:02 +01:00
Dan Abramov
9170e5695a Fix double-adding fibers when traversing 2019-04-05 18:18:39 +01:00
Brian Vaughn
0c8129c78a Sync selected Profiler node back to the Components tab
Also show element keys in Profiler charts
2019-04-05 08:47:23 -07:00
Brian Vaughn
d1a5346c48 Improved keyboard UX and focus UI for Tree and OwnersStack 2019-04-05 08:08:02 -07:00
Dan Abramov
632647fbac Merge pull request #61 from gaearon/toggle-suspense-2
Allow to toggle Suspense in Components pane
2019-04-05 13:22:41 +01:00
Dan
b8245de5a1 Nits 2019-04-05 13:19:39 +01:00
Dan Abramov
48a5aca127 Fix highlighting timed out Suspense DOM node 2019-04-05 13:19:35 +01:00
Dan Abramov
4f5437edf7 Allow to toggle Suspense in Components pane 2019-04-05 13:19:30 +01:00
Brian Vaughn
bfbb4ac545 Merge pull request #72 from gaearon/search-bug
Don't move selection unless search text increased length
2019-04-04 17:55:12 -07:00
Dan
a8e46c67e6 Don't move selection unless search text increased length 2019-04-05 00:49:27 +01:00
Brian Vaughn
16951fe7fb Merge pull request #70 from gaearon/free-debug
Explicitly guard debug calls
2019-04-04 16:12:45 -07:00
Dan
2928a0be74 Explicitly guard debug calls 2019-04-05 00:03:17 +01:00
Brian Vaughn
9b05184ccb Merge pull request #63 from gaearon/smarter-search-match
Match search at word boundaries
2019-04-04 14:41:08 -07:00
Brian Vaughn
6c5c2cd3ad Renamed innerElementType -> InnerElementType to avoid confusing hooks lint rule 2019-04-04 14:10:14 -07:00
Brian Vaughn
8d435595cd Added truncation UI indicator for hooks. Addressed lint rule violations. 2019-04-04 14:09:10 -07:00
Brian Vaughn
11d068d794 Merge branch 'fix-nested-hooks' of https://github.com/gaearon/react-devtools-experimental into gaearon-fix-nested-hooks 2019-04-04 13:54:41 -07:00
Brian Vaughn
64b0fd8ecd Fixed owners header font family too 2019-04-04 13:52:53 -07:00
Brian Vaughn
43782e6696 Merge branch 'larger-items' of https://github.com/gaearon/react-devtools-experimental into gaearon-larger-items 2019-04-04 13:48:24 -07:00
Brian Vaughn
93f83d27dd Merge pull request #66 from gaearon/dont-dismiss-menu
Stop mouseup propagation while inspecting
2019-04-04 13:47:59 -07:00
Dan Abramov
9351c8070d Fix it all 2019-04-04 19:54:56 +01:00
Dan Abramov
18e337707a Stop mouseup propagation while inspecting 2019-04-04 19:52:18 +01:00
Dan Abramov
194f523331 Add size to owner stack items 2019-04-04 19:36:04 +01:00
Dan Abramov
8478a526e6 Don't crash for deeply nested Hooks 2019-04-04 19:28:42 +01:00
Brian Vaughn
ded2ce03ee Renamed TreeWrapper to innerElementType 2019-04-04 10:08:48 -07:00
Brian Vaughn
c86793ef18 Merge branch 'a11y-tree' of https://github.com/gaearon/react-devtools-experimental into gaearon-a11y-tree 2019-04-04 09:54:46 -07:00
Dan Abramov
2afda3de37 Add back regex support 2019-04-04 17:05:34 +01:00
Dan Abramov
0f0062a71c Fix special cases 2019-04-04 17:00:35 +01:00
Dan Abramov
39da33a7bf Fix regex 2019-04-04 16:38:49 +01:00
Brian Vaughn
a9fced9b0d Prettier 2019-04-04 08:35:42 -07:00
Brian Vaughn
8c3a97401f Chagned owner div to be actual button 2019-04-04 08:35:25 -07:00
Brian Vaughn
485f389d05 Merge branch 'tab-owner' of https://github.com/gaearon/react-devtools-experimental into gaearon-tab-owner 2019-04-04 08:32:16 -07:00
Dan Abramov
8cfb0e20c7 Match search at word boundaries 2019-04-04 16:22:21 +01:00
Brian Vaughn
14969c24a9 Merge pull request #62 from gaearon/search-fix
Move selection when typing in search field
2019-04-04 08:14:57 -07:00
Dan Abramov
ec71171bec Move selection when typing in search field 2019-04-04 15:59:06 +01:00
Dan
b1c675b8b1 Make owner stack reachable by keyboard 2019-04-04 09:56:37 +01:00
Brian Vaughn
7fbdfd9f5a Copied findCurrentFiberUsingSlowPath Suspense bug fix from recent PR https://github.com/facebook/react/pull/15312/files 2019-04-03 18:20:18 -07:00
Brian Vaughn
99f2e0da6f Hardened background script against potential errors 2019-04-03 18:16:00 -07:00
Brian Vaughn
ed6e34da8e Added option to disable screenshot capturing while profiling 2019-04-03 14:32:16 -07:00
Brian Vaughn
07bf8e53c1 Renamed GlobalHook content script references to injectGlobalHook to avoid confusion 2019-04-03 11:01:28 -07:00
Dan Abramov
c60f991d87 Make tree reachable by focus 2019-04-03 19:01:04 +01:00
Brian Vaughn
5b879ac095 Fixed a name typo in a radio button 2019-04-03 09:57:13 -07:00
Brian Vaughn
f92d2bbf83 Fixed editing props for memo and forwardRef components 2019-04-03 09:29:33 -07:00
Brian Vaughn
5bc5e31cee Merge pull request #51 from gaearon/tweak-el-display
Add a space in <Foo />
2019-04-03 09:09:11 -07:00
Dan Abramov
b2cd77d2e6 Add a space in <Foo /> 2019-04-03 17:04:31 +01:00
Brian Vaughn
6493db4acc Fixed an arrow navigation bug 2019-04-03 08:12:43 -07:00
Brian Vaughn
6772f2a9e1 Revert fa317be (temporarily show previously selected element props) 2019-04-03 07:52:30 -07:00
Brian Vaughn
d1a68c4b14 Merge pull request #45 from gaearon/rename
Tab name: "Elements" -> "Components"
2019-04-02 17:55:01 -07:00
Brian Vaughn
c111288c54 Store screenshots after each commit when profiling 2019-04-02 15:04:04 -07:00
Dan Abramov
83bd211c9e Elements -> Components (naming) 2019-04-02 19:58:18 +01:00
Dan Abramov
de730da230 Elements -> Components (label) 2019-04-02 19:54:22 +01:00
Brian Vaughn
f415e2447e Added missing Flow annotation 2019-04-02 11:53:18 -07:00
Brian Vaughn
fa317bed61 Merge pull request #41 from gaearon/smoother-right-pane
Avoid flashing "Loading..." in right pane
2019-04-02 10:09:43 -07:00
Brian Vaughn
b8ada905ff Merge pull request #35 from bvaughn/reload-and-profile
Eagerly inject renderer (before document) to support reload-and-profile
2019-04-01 14:47:51 -07:00
Brian Vaughn
2a80f8ca9c Show is-recording indicator earlier after a reload-and-profile 2019-04-01 14:43:46 -07:00
Brian Vaughn
f5f7cb5bdf Fixed some missing operations that could happen after reload-and-profile 2019-04-01 14:29:52 -07:00
Brian Vaughn
74cd1a5d29 Misc cleanup of comments and localStorage key names 2019-04-01 09:05:40 -07:00
Brian Vaughn
2c14f3e88e Inject early on when reloading-and-profiling 2019-04-01 07:48:14 -07:00
Brian Vaughn
37ed5a7175 Merge pull request #38 from lucasecdb/patch-1
Fix casing on store import
2019-04-01 07:25:03 -07:00
Lucas Cordeiro
e634777027 Fix casing on store import 2019-04-01 10:25:57 -03:00
Brian Vaughn
628c1b2f08 Disable export profiling data option in Firefox. (downloads.download seems to just fail silently.) 2019-03-31 19:18:06 -07:00
Brian Vaughn
bfb152f160 Import/export feature 2019-03-31 17:02:30 -07:00
Brian Vaughn
e5400f76f0 Added save profiling data button to Profiler 2019-03-30 14:16:34 -07:00
Brian Vaughn
7cac619c68 Added initial support for EventComponent/EventTarget 2019-03-30 09:02:02 -07:00
Brian Vaughn
7bd8c02f10 Added export and clear buttons for Profiler, cleaned up record toggle 2019-03-30 09:01:52 -07:00
Dan Abramov
b223ec3b39 Avoid flashing "Loading..." in right pane 2019-03-29 23:58:42 -07:00
Brian Vaughn
a450a23e31 Improved Profiler suspense boundary UI 2019-03-29 08:53:39 -07:00
Brian Vaughn
61a251f01a Disable reload-and-profile button if no renderers support profiling 2019-03-27 09:50:19 -07:00
Brian Vaughn
7d24e83989 Implemented reload-and-profile. Also fixed an couple of minor profiling bugs along the way 2019-03-27 09:41:12 -07:00
Brian Vaughn
ea5f310fe1 Webpack config injects a __DEV_ constant 2019-03-26 13:22:55 -07:00
Brian Vaughn
691068b0a3 Suppress horizontal scroll bars in snapshot selector 2019-03-26 11:23:19 -07:00
Brian Vaughn
894990919c Fixed a tab restoration bug in browser extension 2019-03-26 11:13:40 -07:00
Brian Vaughn
3fa951d3c3 Cleaned up a no-selection state 2019-03-25 10:34:22 -07:00
Brian Vaughn
030914fdca Moved some shared CSS vars into CSS 2019-03-25 10:29:25 -07:00
Brian Vaughn
3ba64e5955 Cleaned up edge cases around filtered commits 2019-03-25 10:18:38 -07:00
Brian Vaughn
5718eaf0f3 Added arrow key navigation for commits and interactions 2019-03-24 18:53:59 -07:00
Brian Vaughn
d973452c36 Removed some outdated TODO comments 2019-03-24 10:14:28 -07:00
Brian Vaughn
9d942b486a Show commit boxes in interaxctions sidebar 2019-03-24 09:58:56 -07:00
Brian Vaughn
afba752034 Clicking commits and interactions link to each other 2019-03-24 09:46:54 -07:00
Brian Vaughn
5602fc5371 Added interaction tracing test harness to shell 2019-03-24 09:21:37 -07:00
Brian Vaughn
69cdd38c9d Interaction chart with commit blocks rendering 2019-03-24 09:07:00 -07:00
Brian Vaughn
64e355bb74 Added basic Interactions view (without graph for now) 2019-03-20 11:12:46 -07:00
Brian Vaughn
17a966651c Added suspense to TODO list and added interactions to 'Commit Info' panel 2019-03-20 09:39:14 -07:00
Brian Vaughn
3e82e4152e Added getInteractions message 2019-03-19 18:13:44 -07:00
Brian Vaughn
433b6aadd6 Added placeholder Profiler sidebar views 2019-03-19 12:41:49 -07:00
Brian Vaughn
ac1a986ace Handle RTE in profiler when commit does not contain selected node 2019-03-19 11:19:30 -07:00
Brian Vaughn
1846d4fe59 Fixed a bug where treeBaseDurations were undefined for fibers that were unmounted during profiling 2019-03-19 11:08:51 -07:00
Brian Vaughn
2fc03eb151 Fixed keyboard/mouse events inside of extension by using ref.ownerDocument 2019-03-18 15:11:41 -07:00
Brian Vaughn
b64a76e6bd Reset selected commit and fiber between profiling sessions 2019-03-18 13:53:10 -07:00
Brian Vaughn
9b6ee0bb22 Merge pull request #33 from bvaughn/portals
Experimenting with portals [WIP]
2019-03-18 13:37:56 -07:00
Brian Vaughn
5f154b376e Added profiling-not-supported message for browser extension 2019-03-18 13:37:37 -07:00
Brian Vaughn
be48150fc6 innerTagName -> innerElementType 2019-03-18 10:09:09 -07:00
Brian Vaughn
50b6b1d5f9 Added some inline comments about portal props 2019-03-18 09:57:08 -07:00
Brian Vaughn
e728ebc7b9 Unmount and remount when main URL changes to avoid staleness problems 2019-03-18 09:36:47 -07:00
Brian Vaughn
c9920f0954 Added a few inline comments 2019-03-18 09:20:00 -07:00
Brian Vaughn
2664036dbe Tweaked profiling did-not-render color to be dimmer 2019-03-18 09:18:22 -07:00
Brian Vaughn
11573bf8d9 Refactored portaling and fixed disconnected CSS vars 2019-03-18 09:11:28 -07:00
Brian Vaughn
f3f4643a3a Experimenting with portals 2019-03-17 13:52:37 -07:00
Brian Vaughn
d3ee02cd35 Added "Profiler" tab 2019-03-17 10:58:20 -07:00
Brian Vaughn
d685efd72f Fixed mutation bug in CommitTreeBuilder 2019-03-17 10:25:40 -07:00
Brian Vaughn
c82a7fb560 First pass at flame graph chart 2019-03-17 09:49:10 -07:00
Brian Vaughn
01ad9f1da6 Implemented ranked chart 2019-03-16 14:06:41 -07:00
Brian Vaughn
734e4146e7 Added Ranked chart data generation; fixed some logic errors in backend tree base duration tracking 2019-03-16 10:52:08 -07:00
Brian Vaughn
a93dab7f83 Reset commit tree cache between profiles 2019-03-16 08:50:28 -07:00
Brian Vaughn
821a6504b8 Added commit tree reconstruction 2019-03-15 20:05:52 -07:00
Brian Vaughn
8a7be78ed7 Finished iterating on commit selector UI for now 2019-03-15 11:51:35 -07:00
Brian Vaughn
585c1cb3d2 Refactored Profiler tree to better work with suspense 2019-03-15 10:26:21 -07:00
Brian Vaughn
e8f84dd5c4 Iterating on Profiling tab suspense. Stashing changes but planning to refactor immediately. 2019-03-15 08:34:08 -07:00
Brian Vaughn
210c2371cf Naive pass at commit durationfiltering 2019-03-13 17:00:44 -07:00
Brian Vaughn
8b3546b437 Profiler CSS/layout tweaks 2019-03-13 16:25:29 -07:00
Brian Vaughn
0edf4e9dc1 Plugged react-window into commit selector 2019-03-13 14:57:52 -07:00
Brian Vaughn
b8a52078c6 Added initial Suspense cache and loaded commit metadata 2019-03-12 15:50:29 -07:00
Brian Vaughn
e7e62acbf9 Merge pull request #32 from reznord/fix/long-props-fix
Break the text into next line for long props
2019-03-11 11:26:41 -07:00
Brian Vaughn
f5ba99e6ba Moved some things from ProfilerContext reducer into (root) Store 2019-03-11 11:26:30 -07:00
Anup
896c9a79b2 Fixes #19 - Break the text into next line for long props 2019-03-11 23:37:39 +05:30
Brian Vaughn
22a3c757fb Tidied up Profiler toolbar UI 2019-03-11 09:50:20 -07:00
Brian Vaughn
e5280307c9 Added snapshot selector placeholder UI 2019-03-10 19:16:34 -07:00
Brian Vaughn
565d739569 Added commit time filter 2019-03-10 10:13:20 -07:00
Brian Vaughn
2d68007288 Initial profiling shell added
Lots of TODOs and unfinished views here.
2019-03-10 09:01:05 -07:00
Brian Vaughn
2606d119be Merge branch 'master' of github.com:bvaughn/react-devtools-experimental 2019-03-09 14:09:04 -08:00
Brian Vaughn
c687252b6a Updated Profiling overview/proposal again 2019-03-09 14:08:51 -08:00
Brian Vaughn
a5de36b0c2 Merge pull request #29 from tsriram/fix-import
Fix import file name
2019-03-08 17:41:58 -08:00
Sriram Thiagarajan
3118dae375 fix import file name 2019-03-09 07:03:42 +05:30
Brian Vaughn
5386917f59 Refined OVERVIEW a little more 2019-03-07 14:31:03 -08:00
Brian Vaughn
20b613dcde Updated Profiler OVERVIEW 2019-03-07 14:15:12 -08:00
Brian Vaughn
0ac84f3065 Added explicit Profiler goals to OVERVIEW 2019-03-06 18:30:17 -08:00
Brian Vaughn
4257ba4983 Changed profilerSummary messages to be lazy as well 2019-03-06 18:21:38 -08:00
Brian Vaughn
181e8aff30 Added planned Profiler architecture to OVERVIEW doc to share with others 2019-03-06 18:12:11 -08:00
Brian Vaughn
e9028d1d35 Re-organized views slightly in preparation for Profiler UI 2019-03-06 14:01:52 -08:00
Brian Vaughn
c18449326d Disabled transferrables for now (to avoid a Chrome runtime error) 2019-03-06 13:17:20 -08:00
Brian Vaughn
0db7770cf7 Merged master 2019-03-03 12:41:08 -08:00
Brian Vaughn
235851da87 Merge pull request #27 from gaurav5430/master
Update OVERVIEW.md
2019-03-03 08:14:05 -08:00
Gaurav Gupta
f94401c10e Update OVERVIEW.md
Fixed the superscript reference
2019-03-03 18:29:58 +05:30
Brian Vaughn
515b60cc5e Fixed a typo in OVERVIEW 2019-03-01 08:38:05 -08:00
Brian Vaughn
8aa6f96279 Fixed selecterd element background color being cut-off when tree scrolls
This required a bit of unusual CSS but seems to work well for Firefox and Chrome. We can remove it and revisit other approaches (like PR#24) in the future if needed.
2019-03-01 08:28:16 -08:00
Brian Vaughn
0401f34f55 Removed unnecessary relative position style from Element CSS 2019-02-28 14:50:27 -08:00
Brian Vaughn
90001e892d Udpated param name in injected renderer overrideHookState type 2019-02-28 13:55:49 -08:00
Brian Vaughn
d70dbfdb65 Added intro to OVERVIEW 2019-02-28 13:46:36 -08:00
Brian Vaughn
c249e31932 Fixed docs typo: chlid -> child 2019-02-28 13:26:39 -08:00
Brian Vaughn
7da5f83a28 Updated to account for facebook/react/pull/14906/commits/cdd9ba4 2019-02-28 13:22:27 -08:00
Brian Vaughn
c7f8557202 Improve selected node highlighting by using minWidth instead of width 2019-02-28 12:56:49 -08:00
Brian Vaughn
bffa72c601 Add placeholders to clarify between empty string, null, and undefined 2019-02-28 10:46:17 -08:00
Brian Vaughn
d34a32d389 Disable text selection in tree 2019-02-28 09:44:04 -08:00
Brian Vaughn
d6a2ba2616 Added OVERVIEW doc 2019-02-28 08:52:54 -08:00
Brian Vaughn
bcb6c2fd9f Removed an unnecessary entry from add-root operation array 2019-02-28 08:52:46 -08:00
Brian Vaughn
13ca37384d Maybe fixed checkbox alignment issue Dan reported? 2019-02-27 13:54:53 -08:00
Brian Vaughn
0153eaedee Left arrow selects parent in tree 2019-02-27 13:49:46 -08:00
Brian Vaughn
bf02b2ffbf Select DOM element mode should useCapture to prevent clicks from passing through 2019-02-27 13:33:10 -08:00
Brian Vaughn
05ef0ad7dc Disable view-source button rather than hiding it to avoid jumping when selecting new components 2019-02-27 13:30:03 -08:00
Brian Vaughn
1e4434ecc4 Changed select-on-click to select-on-mouse-down and fixed a scrollIntoView problem 2019-02-27 13:11:23 -08:00
Brian Vaughn
8041bfb92f Add .vscode to .gitignore 2019-02-27 13:07:09 -08:00
Brian Vaughn
bc4e8950f6 Updated test code to include a deeply nested DIV 2019-02-27 13:05:43 -08:00
Brian Vaughn
4d9e7e75c6 Merge branch 'scroll-into-view' of https://github.com/Jessidhia/react-devtools-experimental into Jessidhia-scroll-into-view 2019-02-27 12:58:03 -08:00
Brian Vaughn
89df0a6363 Yarn upgrade 2019-02-24 18:32:29 -08:00
Brian Vaughn
9f24e8c7a2 Renamed overrideHook -> overrideHookState (to stay in sync with React PR) 2019-02-23 09:12:17 -08:00
Brian Vaughn
9b96b1f809 Updated deploy scripts and pre-release template 2019-02-23 08:59:21 -08:00
Brian Vaughn
7b2f06e3d3 Added (temporary) deploy scripts for pre-release extensions 2019-02-22 14:36:10 -08:00
Brian Vaughn
53632883b6 Implemented view-source button for DOM extension 2019-02-22 13:24:03 -08:00
Brian Vaughn
105b53f0fb Split :active and :focus styles for Button+Toggle 2019-02-22 10:54:18 -08:00
Brian Vaughn
5fd9cb5dfb Added copy props/state/hooks/context button 2019-02-22 09:39:05 -08:00
Brian Vaughn
1edbfbf6cb Fixed some small overflow/scrollbar issues 2019-02-22 08:44:05 -08:00
Brian Vaughn
0c346ceea8 Re-added transferrables (after 'shutdown' evt fix) and guard against a tree mutation race 2019-02-21 14:56:11 -08:00
Brian Vaughn
caf2eb973a Split large InspectedElementTree file into separate component-files 2019-02-21 14:20:14 -08:00
Brian Vaughn
9898db02d1 Restore input focus after clicking reset value button 2019-02-21 14:13:48 -08:00
Brian Vaughn
4f64c9ef9e Tweaked colors; Esc key to undo edits 2019-02-21 14:11:06 -08:00
Brian Vaughn
ddeb78001c Tweaked colors based on Andrew's feedback 2019-02-21 14:02:45 -08:00
Brian Vaughn
290e8c6926 Fixed null input value. Tweaked useReducer test harness. 2019-02-21 13:40:23 -08:00
Brian Vaughn
bdf8065137 Merge branch 'master' of github.com:bvaughn/react-devtools-experimental 2019-02-21 13:24:15 -08:00
Brian Vaughn
6f118497e8 Updated editable hooks UI and added limited undo feature 2019-02-21 13:24:01 -08:00
Brian Vaughn
2b27f63a61 Updated ESLint hooks rule 2019-02-21 11:55:28 -08:00
Brian Vaughn
df4a09d9b8 Updated flow-bin from 91 -> 93 and removed unnecessary fixmes 2019-02-21 09:15:47 -08:00
Brian Vaughn
e35819e68d Renamed nativeHookIndex -> index 2019-02-21 08:59:46 -08:00
Brian Vaughn
532cca8013 Merge pull request #4 from mishaor/linux-support
Added support for Linux
2019-02-21 08:24:33 -08:00
Michael Orishich
b0ccd9d89e added basic support for Linux 2019-02-21 20:00:11 +02:00
Brian Vaughn
8cd8b29015 Added support for editable hook values (pending facebook/react/pull/14906) 2019-02-20 15:58:52 -08:00
Brian Vaughn
90f98372a9 Fixed broken 'shutdown' event that lead to CPU problems when reloading DevTools 2019-02-20 11:55:48 -08:00
Brian Vaughn
42795b22bf Installed eslint-plugin-react-hooks@next and added to ESLint config 2019-02-20 11:03:50 -08:00
Brian Vaughn
bec073365d Fix hooks warnings identified by prerelease version of react-hooks ESLint plugin 2019-02-19 13:15:57 -08:00
Brian Vaughn
a31415011d Removed numeric key code 2019-02-19 08:59:27 -08:00
Brian Vaughn
3376daaa41 Merge pull request #2 from Jessidhia/fix-utf-encoding
Fix encoding of Unicode keys greater than U+00FF
2019-02-19 08:56:21 -08:00
Jessica
044e6ba9cd Pass options to scrollIntoView 2019-02-19 16:36:43 +09:00
Jessica
65d493cae9 Just use codepoints as it'll be copied into an Uint32Array anyway 2019-02-19 16:03:53 +09:00
Jessica
4ee74f7e6c Fix encoding of Unicode keys greater than U+00FF (greater than U+FFFF handled by surrogate pairs) 2019-02-19 15:52:24 +09:00
Jessica
28ea0a352e Scroll to newly selected component if it's out of view 2019-02-19 12:22:19 +09:00
Brian Vaughn
a4212dcdce Support editable props, state, and context values 2019-02-17 13:07:39 -08:00
Brian Vaughn
6c226b0c80 Added link to now.sh preview to README 2019-02-16 09:46:10 -08:00
Brian Vaughn
c4d6fdbfdb Fixed overlay position bug 2019-02-16 08:33:38 -08:00
Brian Vaughn
1d95098177 Implemented select-DOM-element button 2019-02-16 08:29:26 -08:00
Brian Vaughn
2fbacbff01 Tab bar resizes properly for narrow screens 2019-02-15 11:42:55 -08:00
Brian Vaughn
0008bb00d7 Inspectable complex hook values 2019-02-14 21:55:09 -08:00
Brian Vaughn
47a5fd59cb Reduced tree padding (left) slightly to make larger trees easier to inspect 2019-02-14 15:13:43 -08:00
Brian Vaughn
04a0d24f0f Fixed a potential source of duplicate key 2019-02-14 15:06:38 -08:00
Brian Vaughn
3f40d38203 Fixed edge case mutation bugs in selected element and tree context 2019-02-14 14:36:29 -08:00
Brian Vaughn
bf2f13d32a Removed some stale TODO comments 2019-02-14 13:37:40 -08:00
Brian Vaughn
9cfa25bdcc Tidied up Flow types for Bridge and Store 2019-02-14 13:32:30 -08:00
Brian Vaughn
b167dd339b Style, theme, and button CSS cleanup 2019-02-14 13:20:24 -08:00
Brian Vaughn
a07d9862ca Fixed edge-case display density bug 2019-02-14 12:46:27 -08:00
Brian Vaughn
15c5396169 Re-added "Settings" panel to browser extension and (hopefully) fixed a lot of sources of error 2019-02-14 11:45:11 -08:00
Brian Vaughn
5a301cd26e Tweaked the owner stack exit icon 2019-02-14 09:23:54 -08:00
Brian Vaughn
36e596ecd1 Changed dark theme to have more React blues 2019-02-14 09:17:29 -08:00
Brian Vaughn
94aab74253 Avoid NPE in Agent if renderer can't be found for an ID 2019-02-14 08:13:35 -08:00
Brian Vaughn
c229837f33 Temporarily disabled Settings panel 2019-02-13 11:36:43 -08:00
Brian Vaughn
79f57532b9 Split demo app into multiple roots and fixed a multi-root bug 2019-02-13 11:22:22 -08:00
Brian Vaughn
4ea81337f3 Initial pass at adding Settings panel to browser extension 2019-02-13 10:59:49 -05:00
Brian Vaughn
aed1713154 Added NOW config file for dev shell 2019-02-12 21:09:50 -05:00
Brian Vaughn
95b859209f Fixed NaN warning for pre-mount CSS prop read 2019-02-12 21:09:33 -05:00
Brian Vaughn
d203ebf165 Added new tabs UI and theme/display-density preferences 2019-02-12 20:41:39 -05:00
Brian Vaughn
8e5a35b762 Misc cleanup and prep for dark mode CSS 2019-02-12 09:45:00 -05:00
Brian Vaughn
f3f497f40f Cleaned up CSS vars and reduced font size a bit 2019-02-08 20:27:10 -05:00
Brian Vaughn
a6126c9e27 Initial stab at 'View in DOM' button 2019-02-08 18:48:29 -05:00
Brian Vaughn
baa6142801 Removed non-functioning tree arrows (for now) 2019-02-08 16:16:15 -05:00
Brian Vaughn
c6b0338f13 Reverted immutable element change (for now) 2019-02-08 16:05:48 -05:00
Brian Vaughn
872d0f78d4 Tweaked owners breadcrumb style to batter match tree colors 2019-02-08 15:49:52 -05:00
Brian Vaughn
41514d67f0 Small refinements to Store: read-only Elements in map, added revision to guard against tearing 2019-02-08 15:37:52 -05:00
Brian Vaughn
0380186501 Refactored tree, search, selection, and owners contexts 2019-02-08 14:44:07 -05:00
Brian Vaughn
45641e98e5 Added owner tree exploration view 2019-02-07 14:34:24 +00:00
Brian Vaughn
fc924d136a Combined search and selection contexts to avoid complicated dependencies 2019-02-07 09:29:42 +00:00
Brian Vaughn
9c093ac731 Fixed regexp parsing 2019-02-06 21:33:44 +00:00
Brian Vaughn
c61e0f0d54 Added a clarifying comment to SearchInput 2019-02-06 17:09:46 +00:00
Brian Vaughn
e77ba00336 Replaced SearchContext useStates with useReducer and fixed an edge-case search bug 2019-02-06 16:31:02 +00:00
Brian Vaughn
998e69a10d Added search support 2019-02-05 17:14:06 +00:00
Brian Vaughn
e723ec82bc Added $r support 2019-02-05 13:19:08 +00:00
Brian Vaughn
ce7f060e26 Cleaned up property borders 2019-02-05 11:26:37 +00:00
Brian Vaughn
6dc3fa6fbd Cleaned up style vars 2019-02-05 11:23:37 +00:00
Brian Vaughn
1566141177 Strip React elements from serialized data (and display <name/> instead 2019-02-05 10:25:33 +00:00
Brian Vaughn
33deb79ce4 Added simple hooks support (same as in legacy DevTools for now)
I had to add a couple of  comments because Flow was being a mysterious little shit and I got tired of trying to work around it.
2019-02-05 09:23:14 +00:00
Brian Vaughn
d0d5b677de Added better context support 2019-02-05 08:32:02 +00:00
Brian Vaughn
6f952ede2f Fixed regression in browser shell 2019-02-04 18:01:44 +00:00
Brian Vaughn
b56bc1a626 Initial pass at properties panel. Lots of TODOs remaining. 2019-02-04 17:49:30 +00:00
Brian Vaughn
406df2a617 Added properties panel and selected element context 2019-02-02 13:57:32 -08:00
Brian Vaughn
9aa6e13d5f Tidied up devtools frontend a little 2019-02-01 09:25:54 -08:00
Brian Vaughn
ad74c54670 Adding tearing warning to Store 2019-01-31 15:59:08 -08:00
Brian Vaughn
1866aef67c Fixed small CSS bug 2019-01-31 15:48:47 -08:00
Brian Vaughn
1eccdd6f8a Moved search icon into separate React component 2019-01-31 14:46:18 -08:00
Brian Vaughn
89f4955b93 Don't show roots in Elements tree 2019-01-31 14:31:12 -08:00
Brian Vaughn
bdfaeede6d Fixed potential race cases in bridge/store/backend initialization 2019-01-31 14:27:16 -08:00
Brian Vaughn
62f8c985df Added stub search row (not connected to anythign yet) 2019-01-31 09:42:07 -08:00
Brian Vaughn
6363fc0767 Tweaked error message to provide more helpful info if shown 2019-01-30 14:39:37 -08:00
Brian Vaughn
ca6151ca01 Reload extension on navigate 2019-01-30 14:16:55 -08:00
Brian Vaughn
6d37857df3 Fixed an Array type bug in Store 2019-01-30 11:31:13 -08:00
Brian Vaughn
a60c8e139a Renamed app.js to App.js for consistency 2019-01-30 10:49:50 -08:00
Brian Vaughn
037071c0e1 Remove root from "roots" list on unmount 2019-01-30 10:41:53 -08:00
Brian Vaughn
1f46df66cb Tidying up 2019-01-30 10:38:52 -08:00
Brian Vaughn
f542f879d6 Added inline comments for types 2019-01-29 14:04:00 -08:00
Brian Vaughn
fc4af4d018 Fixed text wrap bug in extension panel 2019-01-29 13:48:35 -08:00
Brian Vaughn
fdfadef928 Refactored bridge to support transferrables (e.g. typed array buffers) and added transferable param to postMessage for op codes 2019-01-29 13:17:37 -08:00
Brian Vaughn
3f93b029a4 Replaced node objects with typed array of tree operations; windowing works in small test harness 2019-01-28 15:50:48 -08:00
Brian Vaughn
c9a5f8cc29 Stashing partial windowing implementation 2019-01-27 16:04:17 -08:00
Brian Vaughn
b7cbd38214 Misc updates to better handle tearing and add some future TODOs 2019-01-27 07:58:09 -08:00
Brian Vaughn
13ca26e153 Removed throttling. It's too error prone because of mutations (Fibers). We'll optimize later by using the effects list for updates. 2019-01-24 13:45:29 -08:00
Brian Vaughn
d57ec69561 Added initial Chrome/Firefox shells 2019-01-23 18:06:21 -08:00
Brian Vaughn
f881c32304 Added Prettier (and formatted code) 2019-01-23 08:45:19 -08:00
Brian Vaughn
d02b4a2784 Throttle bridge traffic for Elements tree updates 2019-01-23 08:27:40 -08:00
Brian Vaughn
7b9a8e9843 Added a super basic README 2019-01-22 11:07:56 -08:00
Brian Vaughn
5e0dfdac54 Initial commit 2019-01-22 11:04:37 -08:00
840 changed files with 103710 additions and 9966 deletions

View File

@@ -22,6 +22,32 @@ aliases:
- &attach_workspace
at: build
- &process_artifacts
docker: *docker
environment: *environment
steps:
- checkout
- attach_workspace: *attach_workspace
- *restore_yarn_cache
- *run_yarn
- run: node ./scripts/rollup/consolidateBundleSizes.js
- run: ./scripts/circleci/upload_build.sh
- run: ./scripts/circleci/pack_and_store_artifact.sh
- store_artifacts:
path: ./node_modules.tgz
- store_artifacts:
path: ./build.tgz
- store_artifacts:
path: ./build/bundle-sizes.json
- store_artifacts:
# TODO: Update release script to use local file instead of pulling
# from artifacts.
path: ./scripts/error-codes/codes.json
- persist_to_workspace:
root: build
paths:
- bundle-sizes.json
jobs:
setup:
docker: *docker
@@ -72,7 +98,22 @@ jobs:
- checkout
- *restore_yarn_cache
- *run_yarn
- run: yarn test --maxWorkers=2
- run:
environment:
RELEASE_CHANNEL: stable
command: yarn test --maxWorkers=2
test_source_experimental:
docker: *docker
environment: *environment
steps:
- checkout
- *restore_yarn_cache
- *run_yarn
- run:
environment:
RELEASE_CHANNEL: experimental
command: yarn test --maxWorkers=2
test_source_persistent:
docker: *docker
@@ -82,7 +123,10 @@ jobs:
- checkout
- *restore_yarn_cache
- *run_yarn
- run: yarn test-persistent --maxWorkers=2
- run:
environment:
RELEASE_CHANNEL: stable
command: yarn test-persistent --maxWorkers=2
test_source_prod:
docker: *docker
@@ -92,7 +136,10 @@ jobs:
- checkout
- *restore_yarn_cache
- *run_yarn
- run: yarn test-prod --maxWorkers=2
- run:
environment:
RELEASE_CHANNEL: stable
command: yarn test-prod --maxWorkers=2
build:
docker: *docker
@@ -102,19 +149,56 @@ jobs:
- checkout
- *restore_yarn_cache
- *run_yarn
- run: ./scripts/circleci/add_build_info_json.sh
- run: ./scripts/circleci/update_package_versions.sh
- run: yarn build
- run:
environment:
RELEASE_CHANNEL: stable
command: |
./scripts/circleci/add_build_info_json.sh
./scripts/circleci/update_package_versions.sh
yarn build
- run: echo "stable" >> build/RELEASE_CHANNEL
- persist_to_workspace:
root: build
paths:
- RELEASE_CHANNEL
- facebook-www
- node_modules
- react-native
- dist
- sizes/*.json
process_artifacts:
build_experimental:
docker: *docker
environment: *environment
parallelism: 20
steps:
- checkout
- *restore_yarn_cache
- *run_yarn
- run:
environment:
RELEASE_CHANNEL: experimental
command: |
./scripts/circleci/add_build_info_json.sh
./scripts/circleci/update_package_versions.sh
yarn build
- run: echo "experimental" >> build/RELEASE_CHANNEL
- persist_to_workspace:
root: build
paths:
- RELEASE_CHANNEL
- facebook-www
- node_modules
- react-native
- dist
- sizes/*.json
# These jobs are named differently so we can distinguish the stable and
# and experimental artifacts
process_artifacts: *process_artifacts
process_artifacts_experimental: *process_artifacts
sizebot:
docker: *docker
environment: *environment
steps:
@@ -122,20 +206,29 @@ jobs:
- attach_workspace: *attach_workspace
- *restore_yarn_cache
- *run_yarn
# This runs in the process_artifacts job, too, but it's faster to run
# this step in both jobs instead of running the jobs sequentially
- run: node ./scripts/rollup/consolidateBundleSizes.js
- run: node ./scripts/tasks/danger
- run: ./scripts/circleci/upload_build.sh
- run: ./scripts/circleci/pack_and_store_artifact.sh
- store_artifacts:
path: ./node_modules.tgz
- store_artifacts:
path: ./build.tgz
- store_artifacts:
path: ./build/bundle-sizes.json
- store_artifacts:
# TODO: Update release script to use local file instead of pulling
# from artifacts.
path: ./scripts/error-codes/codes.json
- run:
environment:
RELEASE_CHANNEL: stable
command: node ./scripts/tasks/danger
sizebot_experimental:
docker: *docker
environment: *environment
steps:
- checkout
- attach_workspace: *attach_workspace
- *restore_yarn_cache
- *run_yarn
# This runs in the process_artifacts job, too, but it's faster to run
# this step in both jobs instead of running the jobs sequentially
- run: node ./scripts/rollup/consolidateBundleSizes.js
- run:
environment:
RELEASE_CHANNEL: experimental
command: node ./scripts/tasks/danger
lint_build:
docker: *docker
@@ -156,7 +249,36 @@ jobs:
- attach_workspace: *attach_workspace
- *restore_yarn_cache
- *run_yarn
- run: yarn test-build --maxWorkers=2
- run:
environment:
RELEASE_CHANNEL: stable
command: yarn test-build --maxWorkers=2
test_build_experimental:
docker: *docker
environment: *environment
steps:
- checkout
- attach_workspace: *attach_workspace
- *restore_yarn_cache
- *run_yarn
- run:
environment:
RELEASE_CHANNEL: experimental
command: yarn test-build --maxWorkers=2
test_build_devtools:
docker: *docker
environment: *environment
steps:
- checkout
- attach_workspace: *attach_workspace
- *restore_yarn_cache
- *run_yarn
- run:
environment:
RELEASE_CHANNEL: stable
command: yarn test-build --maxWorkers=2
test_dom_fixtures:
docker: *docker
@@ -167,6 +289,8 @@ jobs:
- *restore_yarn_cache
- run:
name: Run DOM fixture tests
environment:
RELEASE_CHANNEL: stable
command: |
cd fixtures/dom
yarn --frozen-lockfile
@@ -194,11 +318,27 @@ jobs:
- attach_workspace: *attach_workspace
- *restore_yarn_cache
- *run_yarn
- run: yarn test-build-prod --maxWorkers=2
- run:
environment:
RELEASE_CHANNEL: stable
command: yarn test-build-prod --maxWorkers=2
test_build_prod_experimental:
docker: *docker
environment: *environment
steps:
- checkout
- attach_workspace: *attach_workspace
- *restore_yarn_cache
- *run_yarn
- run:
environment:
RELEASE_CHANNEL: experimental
command: yarn test-build-prod --maxWorkers=2
workflows:
version: 2
commit:
stable:
jobs:
- setup
- lint:
@@ -222,6 +362,9 @@ workflows:
- process_artifacts:
requires:
- build
- sizebot:
requires:
- build
- lint_build:
requires:
- build
@@ -231,12 +374,42 @@ workflows:
- test_build_prod:
requires:
- build
- test_build_devtools:
requires:
- build
- test_dom_fixtures:
requires:
- build
hourly:
experimental:
jobs:
- setup
- test_source_experimental:
requires:
- setup
- build_experimental:
requires:
- setup
- process_artifacts_experimental:
requires:
- build_experimental
- sizebot_experimental:
requires:
- build_experimental
- test_build_experimental:
requires:
- build_experimental
- test_build_prod_experimental:
requires:
- build_experimental
- lint_build:
requires:
- build_experimental
fuzz_tests:
triggers:
- schedule:
# Fuzz tests run hourly
cron: "0 * * * *"
filters:
branches:

10
.codesandbox/ci.json Normal file
View File

@@ -0,0 +1,10 @@
{
"packages": ["packages/react", "packages/react-dom", "packages/scheduler"],
"buildCommand": "build --type=NODE react/index,react-dom/index,scheduler/index,scheduler/tracing",
"publishDirectory": {
"react": "build/node_modules/react",
"react-dom": "build/node_modules/react-dom",
"scheduler": "build/node_modules/scheduler"
},
"sandboxes": ["new"]
}

View File

@@ -12,3 +12,10 @@ scripts/bench/benchmarks/**/*.js
# React repository clone
scripts/bench/remote-repo/
packages/react-devtools-core/dist
packages/react-devtools-extensions/chrome/build
packages/react-devtools-extensions/firefox/build
packages/react-devtools-extensions/shared/build
packages/react-devtools-inline/dist
packages/react-devtools-shell/dist

View File

@@ -93,6 +93,7 @@ module.exports = {
'react-internal/no-primitive-constructors': ERROR,
'react-internal/no-to-warn-dev-within-to-throw': ERROR,
'react-internal/warning-and-invariant-args': ERROR,
'react-internal/no-production-logging': ERROR,
},
overrides: [
@@ -142,10 +143,14 @@ module.exports = {
],
globals: {
SharedArrayBuffer: true,
spyOnDev: true,
spyOnDevAndProd: true,
spyOnProd: true,
__PROFILE__: true,
__UMD__: true,
__EXPERIMENTAL__: true,
trustedTypes: true,
},
};

11
.gitignore vendored
View File

@@ -22,3 +22,14 @@ chrome-user-data
.vscode
*.swp
*.swo
packages/react-devtools-core/dist
packages/react-devtools-extensions/chrome/build
packages/react-devtools-extensions/chrome/*.crx
packages/react-devtools-extensions/chrome/*.pem
packages/react-devtools-extensions/firefox/build
packages/react-devtools-extensions/firefox/*.xpi
packages/react-devtools-extensions/firefox/*.pem
packages/react-devtools-extensions/shared/build
packages/react-devtools-inline/dist
packages/react-devtools-shell/dist

View File

@@ -88,6 +88,7 @@ Kevin Coughlin <kevintcoughlin@gmail.com> <kevincoughlin@tumblr.com>
Krystian Karczewski <karcz.k@gmail.com>
Kunal Mehta <k.mehta@berkeley.edu> <kunalm@fb.com>
Laurence Rowe <l@lrowe.co.uk> <laurence@lrowe.co.uk>
Lea Rosema <terabaud@gmail.com>
Marcin K. <katzoo@github.mail>
Mark Anderson <undernewmanagement@users.noreply.github.com>
Mark Funk <mfunk86@gmail.com> <mark@boomtownroi.com>

2
.nvmrc
View File

@@ -1 +1 @@
v8.4.0
v10.16.3

6
.prettierignore Normal file
View File

@@ -0,0 +1,6 @@
packages/react-devtools-core/dist
packages/react-devtools-extensions/chrome/build
packages/react-devtools-extensions/firefox/build
packages/react-devtools-extensions/shared/build
packages/react-devtools-inline/dist
packages/react-devtools-shell/dist

View File

@@ -6,6 +6,56 @@
</summary>
</details>
## 16.12.0 (November 14, 2019)
### React DOM
* Fix passive effects (`useEffect`) not being fired in a multi-root app. ([@acdlite](https://github.com/acdlite) in [#17347](https://github.com/facebook/react/pull/17347))
### React Is
* Fix `lazy` and `memo` types considered elements instead of components ([@bvaughn](https://github.com/bvaughn) in [#17278](https://github.com/facebook/react/pull/17278))
## 16.11.0 (October 22, 2019)
### React DOM
* Fix `mouseenter` handlers from firing twice inside nested React containers. [@yuanoook](https://github.com/yuanoook) in [#16928](https://github.com/facebook/react/pull/16928)
* Remove `unstable_createRoot` and `unstable_createSyncRoot` experimental APIs. (These are available in the Experimental channel as `createRoot` and `createSyncRoot`.) ([@acdlite](http://github.com/acdlite) in [#17088](https://github.com/facebook/react/pull/17088))
## 16.10.2 (October 3, 2019)
### React DOM
* Fix regression in react-native-web by restoring order of arguments in event plugin extractors ([@necolas](https://github.com/necolas) in [#16978](https://github.com/facebook/react/pull/16978))
## 16.10.1 (September 28, 2019)
### React DOM
* Fix regression in Next.js apps by allowing Suspense mismatch during hydration to silently proceed ([@sebmarkbage](https://github.com/sebmarkbage) in [#16943](https://github.com/facebook/react/pull/16943))
## 16.10.0 (September 27, 2019)
### React DOM
* Fix edge case where a hook update wasn't being memoized. ([@sebmarkbage](http://github.com/sebmarkbage) in [#16359](https://github.com/facebook/react/pull/16359))
* Fix heuristic for determining when to hydrate, so we don't incorrectly hydrate during an update. ([@sebmarkbage](http://github.com/sebmarkbage) in [#16739](https://github.com/facebook/react/pull/16739))
* Clear additional fiber fields during unmount to save memory. ([@trueadm](http://github.com/trueadm) in [#16807](https://github.com/facebook/react/pull/16807))
* Fix bug with required text fields in Firefox. ([@halvves](http://github.com/halvves) in [#16578](https://github.com/facebook/react/pull/16578))
* Prefer `Object.is` instead of inline polyfill, when available. ([@ku8ar](http://github.com/ku8ar) in [#16212](https://github.com/facebook/react/pull/16212))
* Fix bug when mixing Suspense and error handling. ([@acdlite](http://github.com/acdlite) in [#16801](https://github.com/facebook/react/pull/16801))
### Scheduler (Experimental)
* Improve queue performance by switching its internal data structure to a min binary heap. ([@acdlite](http://github.com/acdlite) in [#16245](https://github.com/facebook/react/pull/16245))
* Use `postMessage` loop with short intervals instead of attempting to align to frame boundaries with `requestAnimationFrame`. ([@acdlite](http://github.com/acdlite) in [#16214](https://github.com/facebook/react/pull/16214))
### useSubscription
* Avoid tearing issue when a mutation happens and the previous update is still in progress. ([@bvaughn](http://github.com/bvaughn) in [#16623](https://github.com/facebook/react/pull/16623))
## 16.9.0 (August 8, 2019)
### React
@@ -41,6 +91,10 @@
* Warn in Strict Mode if effects are scheduled outside an `act()` call. ([@threepointone](https://github.com/threepointone) in [#15763](https://github.com/facebook/react/pull/15763) and [#16041](https://github.com/facebook/react/pull/16041))
* Warn when using `act` from the wrong renderer. ([@threepointone](https://github.com/threepointone) in [#15756](https://github.com/facebook/react/pull/15756))
### ESLint Plugin: React Hooks
* Report Hook calls at the top level as a violation. ([gaearon](https://github.com/gaearon) in [#16455](https://github.com/facebook/react/pull/16455))
## 16.8.6 (March 27, 2019)
### React DOM
@@ -480,7 +534,7 @@ This release was published in a broken state and should be skipped.
* Fix an issue with `this.state` of different components getting mixed up. ([@sophiebits](https://github.com/sophiebits) in [#12323](https://github.com/facebook/react/pull/12323))
* Provide a better message when component type is undefined. ([@HeroProtagonist](https://github.com/HeroProtagonist) in [#11966](https://github.com/facebook/react/pull/11966))
## React Test Renderer
### React Test Renderer
* Fix handling of fragments in `toTree()`. ([@maciej-ka](https://github.com/maciej-ka) in [#12107](https://github.com/facebook/react/pull/12107) and [@gaearon](https://github.com/gaearon) in [#12154](https://github.com/facebook/react/pull/12154))
* Shallow renderer should assign state to `null` for components that don't set it. ([@jwbay](https://github.com/jwbay) in [#11965](https://github.com/facebook/react/pull/11965))

View File

@@ -1,3 +1,76 @@
# Code of Conduct
Facebook has adopted a Code of Conduct that we expect project participants to adhere to. Please [read the full text](https://code.fb.com/codeofconduct/) so that you can understand what actions will and will not be tolerated.
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to make participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies within all project spaces, and it also applies when
an individual is representing the project or its community in public spaces.
Examples of representing a project or community include using an official
project e-mail address, posting via an official social media account, or acting
as an appointed representative at an online or offline event. Representation of
a project may be further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at <opensource-conduct@fb.com>. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq

View File

@@ -32,6 +32,14 @@ const {generateResultsArray} = require('./scripts/rollup/stats');
const {existsSync, readFileSync} = require('fs');
const {exec} = require('child_process');
// This must match the name of the CI job that creates the build artifacts
const RELEASE_CHANNEL =
process.env.RELEASE_CHANNEL === 'experimental' ? 'experimental' : 'stable';
const artifactsJobName =
process.env.RELEASE_CHANNEL === 'experimental'
? 'process_artifacts_experimental'
: 'process_artifacts';
if (!existsSync('./build/bundle-sizes.json')) {
// This indicates the build failed previously.
// In that case, there's nothing for the Dangerfile to do.
@@ -117,6 +125,8 @@ function git(args) {
return;
}
markdown(`## Size changes (${RELEASE_CHANNEL})`);
const upstreamRef = danger.github.pr.base.ref;
await git(`remote add upstream https://github.com/facebook/react.git`);
await git('fetch upstream');
@@ -135,8 +145,7 @@ function git(args) {
}
for (let i = 0; i < statuses.length; i++) {
const status = statuses[i];
// This must match the name of the CI job that creates the build artifacts
if (status.context === 'ci/circleci: process_artifacts') {
if (status.context === `ci/circleci: ${artifactsJobName}`) {
if (status.state === 'success') {
baseCIBuildId = /\/facebook\/react\/([0-9]+)/.exec(
status.target_url

View File

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -1,5 +1,5 @@
import React, {PureComponent} from 'react';
import {flushSync, unstable_createRoot} from 'react-dom';
import {flushSync, createRoot} from 'react-dom';
import Scheduler from 'scheduler';
import _ from 'lodash';
import Charts from './Charts';
@@ -107,9 +107,10 @@ class App extends PureComponent {
this.debouncedHandleChange(value);
break;
case 'async':
unstable_scheduleCallback(() => {
// TODO: useTransition hook instead.
setTimeout(() => {
this.setState({value});
});
}, 0);
break;
default:
break;
@@ -146,5 +147,5 @@ class App extends PureComponent {
}
const container = document.getElementById('root');
const root = ReactDOM.unstable_createRoot(container);
root.render(<App />, container);
const root = createRoot(container);
root.render(<App />);

View File

@@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>React 14.9</title>
<link rel="stylesheet" href="styles.css" />
<script type="text/javascript">
// Enable DevTools to inspect React inside of an <iframe>
// This must run before React is loaded
__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
</script>
<script src="https://unpkg.com/react@0.14.9/dist/react.js"></script>
<script src="https://unpkg.com/react-dom@0.14.9/dist/react-dom.js"></script>
<!-- Don't use this in production: -->
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
<div id="root">
If you are seeing this message, you are likely viewing this file using the <code>file</code> protocol which does not support cross origin requests.
<br/><br/>
Use the <code>server</code> script instead:
<br/><br/>
<code>node ./fixtures/devtools/regression/server.js</code><br/>
<code>open <a href="http://localhost:3000/14.9.html">http://localhost:3000/14.9.html</a></code>
</div>
<script src="shared.js" type="text/babel"></script>
<!--
This is a great way to try React but it's not suitable for production.
It slowly compiles JSX with Babel in the browser and uses a large development build of React.
Learn more at https://reactjs.org/docs/getting-started.html
-->
</body>
</html>

View File

@@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>React 15.0</title>
<link rel="stylesheet" href="styles.css" />
<script type="text/javascript">
// Enable DevTools to inspect React inside of an <iframe>
// This must run before React is loaded
__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
</script>
<script src="https://unpkg.com/react@15.0/dist/react.js"></script>
<script src="https://unpkg.com/react-dom@15.0/dist/react-dom.js"></script>
<!-- Don't use this in production: -->
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
<div id="root">
If you are seeing this message, you are likely viewing this file using the <code>file</code> protocol which does not support cross origin requests.
<br/><br/>
Use the <code>server</code> script instead:
<br/><br/>
<code>node ./fixtures/devtools/regression/server.js</code><br/>
<code>open <a href="http://localhost:3000/15.0.html">http://localhost:3000/15.0.html</a></code>
</div>
<script src="shared.js" type="text/babel"></script>
<!--
This is a great way to try React but it's not suitable for production.
It slowly compiles JSX with Babel in the browser and uses a large development build of React.
Learn more at https://reactjs.org/docs/getting-started.html
-->
</body>
</html>

View File

@@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>React 15.1</title>
<link rel="stylesheet" href="styles.css" />
<script type="text/javascript">
// Enable DevTools to inspect React inside of an <iframe>
// This must run before React is loaded
__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
</script>
<script src="https://unpkg.com/react@15.1/dist/react.js"></script>
<script src="https://unpkg.com/react-dom@15.1/dist/react-dom.js"></script>
<!-- Don't use this in production: -->
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
<div id="root">
If you are seeing this message, you are likely viewing this file using the <code>file</code> protocol which does not support cross origin requests.
<br/><br/>
Use the <code>server</code> script instead:
<br/><br/>
<code>node ./fixtures/devtools/regression/server.js</code><br/>
<code>open <a href="http://localhost:3000/15.1.html">http://localhost:3000/15.1.html</a></code>
</div>
<script src="shared.js" type="text/babel"></script>
<!--
This is a great way to try React but it's not suitable for production.
It slowly compiles JSX with Babel in the browser and uses a large development build of React.
Learn more at https://reactjs.org/docs/getting-started.html
-->
</body>
</html>

View File

@@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>React 15.2</title>
<link rel="stylesheet" href="styles.css" />
<script type="text/javascript">
// Enable DevTools to inspect React inside of an <iframe>
// This must run before React is loaded
__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
</script>
<script src="https://unpkg.com/react@15.2/dist/react.js"></script>
<script src="https://unpkg.com/react-dom@15.2/dist/react-dom.js"></script>
<!-- Don't use this in production: -->
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
<div id="root">
If you are seeing this message, you are likely viewing this file using the <code>file</code> protocol which does not support cross origin requests.
<br/><br/>
Use the <code>server</code> script instead:
<br/><br/>
<code>node ./fixtures/devtools/regression/server.js</code><br/>
<code>open <a href="http://localhost:3000/15.2.html">http://localhost:3000/15.2.html</a></code>
</div>
<script src="shared.js" type="text/babel"></script>
<!--
This is a great way to try React but it's not suitable for production.
It slowly compiles JSX with Babel in the browser and uses a large development build of React.
Learn more at https://reactjs.org/docs/getting-started.html
-->
</body>
</html>

View File

@@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>React 15.3</title>
<link rel="stylesheet" href="styles.css" />
<script type="text/javascript">
// Enable DevTools to inspect React inside of an <iframe>
// This must run before React is loaded
__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
</script>
<script src="https://unpkg.com/react@15.3/dist/react.js"></script>
<script src="https://unpkg.com/react-dom@15.3/dist/react-dom.js"></script>
<!-- Don't use this in production: -->
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
<div id="root">
If you are seeing this message, you are likely viewing this file using the <code>file</code> protocol which does not support cross origin requests.
<br/><br/>
Use the <code>server</code> script instead:
<br/><br/>
<code>node ./fixtures/devtools/regression/server.js</code><br/>
<code>open <a href="http://localhost:3000/15.3.html">http://localhost:3000/15.3.html</a></code>
</div>
<script src="shared.js" type="text/babel"></script>
<!--
This is a great way to try React but it's not suitable for production.
It slowly compiles JSX with Babel in the browser and uses a large development build of React.
Learn more at https://reactjs.org/docs/getting-started.html
-->
</body>
</html>

View File

@@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>React 15.4</title>
<link rel="stylesheet" href="styles.css" />
<script type="text/javascript">
// Enable DevTools to inspect React inside of an <iframe>
// This must run before React is loaded
__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
</script>
<script src="https://unpkg.com/react@15.4/dist/react.js"></script>
<script src="https://unpkg.com/react-dom@15.4/dist/react-dom.js"></script>
<!-- Don't use this in production: -->
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
<div id="root">
If you are seeing this message, you are likely viewing this file using the <code>file</code> protocol which does not support cross origin requests.
<br/><br/>
Use the <code>server</code> script instead:
<br/><br/>
<code>node ./fixtures/devtools/regression/server.js</code><br/>
<code>open <a href="http://localhost:3000/15.4.html">http://localhost:3000/15.4.html</a></code>
</div>
<script src="shared.js" type="text/babel"></script>
<!--
This is a great way to try React but it's not suitable for production.
It slowly compiles JSX with Babel in the browser and uses a large development build of React.
Learn more at https://reactjs.org/docs/getting-started.html
-->
</body>
</html>

View File

@@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>React 15.5</title>
<link rel="stylesheet" href="styles.css" />
<script type="text/javascript">
// Enable DevTools to inspect React inside of an <iframe>
// This must run before React is loaded
__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
</script>
<script src="https://unpkg.com/react@15.5/dist/react.js"></script>
<script src="https://unpkg.com/react-dom@15.5/dist/react-dom.js"></script>
<!-- Don't use this in production: -->
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
<div id="root">
If you are seeing this message, you are likely viewing this file using the <code>file</code> protocol which does not support cross origin requests.
<br/><br/>
Use the <code>server</code> script instead:
<br/><br/>
<code>node ./fixtures/devtools/regression/server.js</code><br/>
<code>open <a href="http://localhost:3000/15.5.html">http://localhost:3000/15.5.html</a></code>
</div>
<script src="shared.js" type="text/babel"></script>
<!--
This is a great way to try React but it's not suitable for production.
It slowly compiles JSX with Babel in the browser and uses a large development build of React.
Learn more at https://reactjs.org/docs/getting-started.html
-->
</body>
</html>

View File

@@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>React 15.6</title>
<link rel="stylesheet" href="styles.css" />
<script type="text/javascript">
// Enable DevTools to inspect React inside of an <iframe>
// This must run before React is loaded
__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
</script>
<script src="https://unpkg.com/react@15.6/dist/react.js"></script>
<script src="https://unpkg.com/react-dom@15.6/dist/react-dom.js"></script>
<!-- Don't use this in production: -->
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
<div id="root">
If you are seeing this message, you are likely viewing this file using the <code>file</code> protocol which does not support cross origin requests.
<br/><br/>
Use the <code>server</code> script instead:
<br/><br/>
<code>node ./fixtures/devtools/regression/server.js</code><br/>
<code>open <a href="http://localhost:3000/15.6.html">http://localhost:3000/15.6.html</a></code>
</div>
<script src="shared.js" type="text/babel"></script>
<!--
This is a great way to try React but it's not suitable for production.
It slowly compiles JSX with Babel in the browser and uses a large development build of React.
Learn more at https://reactjs.org/docs/getting-started.html
-->
</body>
</html>

View File

@@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>React 16.0</title>
<link rel="stylesheet" href="styles.css" />
<script type="text/javascript">
// Enable DevTools to inspect React inside of an <iframe>
// This must run before React is loaded
__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
</script>
<script src="https://unpkg.com/react@16.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.0/umd/react-dom.development.js"></script>
<!-- Don't use this in production: -->
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
<div id="root">
If you are seeing this message, you are likely viewing this file using the <code>file</code> protocol which does not support cross origin requests.
<br/><br/>
Use the <code>server</code> script instead:
<br/><br/>
<code>node ./fixtures/devtools/regression/server.js</code><br/>
<code>open <a href="http://localhost:3000/16.0.html">http://localhost:3000/16.0.html</a></code>
</div>
<script src="shared.js" type="text/babel"></script>
<!--
This is a great way to try React but it's not suitable for production.
It slowly compiles JSX with Babel in the browser and uses a large development build of React.
Learn more at https://reactjs.org/docs/getting-started.html
-->
</body>
</html>

View File

@@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>React 16.1</title>
<link rel="stylesheet" href="styles.css" />
<script type="text/javascript">
// Enable DevTools to inspect React inside of an <iframe>
// This must run before React is loaded
__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
</script>
<script src="https://unpkg.com/react@16.1/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.1/umd/react-dom.development.js"></script>
<!-- Don't use this in production: -->
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
<div id="root">
If you are seeing this message, you are likely viewing this file using the <code>file</code> protocol which does not support cross origin requests.
<br/><br/>
Use the <code>server</code> script instead:
<br/><br/>
<code>node ./fixtures/devtools/regression/server.js</code><br/>
<code>open <a href="http://localhost:3000/16.1.html">http://localhost:3000/16.1.html</a></code>
</div>
<script src="shared.js" type="text/babel"></script>
<!--
This is a great way to try React but it's not suitable for production.
It slowly compiles JSX with Babel in the browser and uses a large development build of React.
Learn more at https://reactjs.org/docs/getting-started.html
-->
</body>
</html>

View File

@@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>React 16.2</title>
<link rel="stylesheet" href="styles.css" />
<script type="text/javascript">
// Enable DevTools to inspect React inside of an <iframe>
// This must run before React is loaded
__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
</script>
<script src="https://unpkg.com/react@16.2/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.2/umd/react-dom.development.js"></script>
<!-- Don't use this in production: -->
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
<div id="root">
If you are seeing this message, you are likely viewing this file using the <code>file</code> protocol which does not support cross origin requests.
<br/><br/>
Use the <code>server</code> script instead:
<br/><br/>
<code>node ./fixtures/devtools/regression/server.js</code><br/>
<code>open <a href="http://localhost:3000/16.2.html">http://localhost:3000/16.2.html</a></code>
</div>
<script src="shared.js" type="text/babel"></script>
<!--
This is a great way to try React but it's not suitable for production.
It slowly compiles JSX with Babel in the browser and uses a large development build of React.
Learn more at https://reactjs.org/docs/getting-started.html
-->
</body>
</html>

View File

@@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>React 16.3</title>
<link rel="stylesheet" href="styles.css" />
<script type="text/javascript">
// Enable DevTools to inspect React inside of an <iframe>
// This must run before React is loaded
__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
</script>
<script src="https://unpkg.com/react@16.3/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.3/umd/react-dom.development.js"></script>
<!-- Don't use this in production: -->
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
<div id="root">
If you are seeing this message, you are likely viewing this file using the <code>file</code> protocol which does not support cross origin requests.
<br/><br/>
Use the <code>server</code> script instead:
<br/><br/>
<code>node ./fixtures/devtools/regression/server.js</code><br/>
<code>open <a href="http://localhost:3000/16.3.html">http://localhost:3000/16.3.html</a></code>
</div>
<script src="shared.js" type="text/babel"></script>
<!--
This is a great way to try React but it's not suitable for production.
It slowly compiles JSX with Babel in the browser and uses a large development build of React.
Learn more at https://reactjs.org/docs/getting-started.html
-->
</body>
</html>

View File

@@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>React 16.4</title>
<link rel="stylesheet" href="styles.css" />
<script type="text/javascript">
// Enable DevTools to inspect React inside of an <iframe>
// This must run before React is loaded
__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
</script>
<script src="https://unpkg.com/react@16.4/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.4/umd/react-dom.development.js"></script>
<!-- Don't use this in production: -->
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
<div id="root">
If you are seeing this message, you are likely viewing this file using the <code>file</code> protocol which does not support cross origin requests.
<br/><br/>
Use the <code>server</code> script instead:
<br/><br/>
<code>node ./fixtures/devtools/regression/server.js</code><br/>
<code>open <a href="http://localhost:3000/16.4.html">http://localhost:3000/16.4.html</a></code>
</div>
<script src="shared.js" type="text/babel"></script>
<!--
This is a great way to try React but it's not suitable for production.
It slowly compiles JSX with Babel in the browser and uses a large development build of React.
Learn more at https://reactjs.org/docs/getting-started.html
-->
</body>
</html>

View File

@@ -0,0 +1,40 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>React 16.5</title>
<link rel="stylesheet" href="styles.css" />
<script type="text/javascript">
// Enable DevTools to inspect React inside of an <iframe>
// This must run before React is loaded
__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
</script>
<script src="https://unpkg.com/schedule@0.5.0/umd/schedule.development.js"></script>
<script src="https://unpkg.com/schedule@0.5.0/umd/schedule-tracing.development.js"></script>
<script src="https://unpkg.com/react@16.5/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.5/umd/react-dom.development.js"></script>
<!-- Don't use this in production: -->
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
<div id="root">
If you are seeing this message, you are likely viewing this file using the <code>file</code> protocol which does not support cross origin requests.
<br/><br/>
Use the <code>server</code> script instead:
<br/><br/>
<code>node ./fixtures/devtools/regression/server.js</code><br/>
<code>open <a href="http://localhost:3000/16.5.html">http://localhost:3000/16.5.html</a></code>
</div>
<script src="shared.js" type="text/babel"></script>
<!--
This is a great way to try React but it's not suitable for production.
It slowly compiles JSX with Babel in the browser and uses a large development build of React.
Learn more at https://reactjs.org/docs/getting-started.html
-->
</body>
</html>

View File

@@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>React 16.6</title>
<link rel="stylesheet" href="styles.css" />
<script type="text/javascript">
// Enable DevTools to inspect React inside of an <iframe>
// This must run before React is loaded
__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
</script>
<script src="https://unpkg.com/scheduler@0.10.0/umd/scheduler.development.js"></script>
<script src="https://unpkg.com/scheduler@0.10.0/umd/scheduler-tracing.development.js"></script>
<script src="https://unpkg.com/react@16.6/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.6/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/react-cache@2.0.0-alpha.1/umd/react-cache.development.js"></script>
<!-- Don't use this in production: -->
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
<div id="root">
If you are seeing this message, you are likely viewing this file using the <code>file</code> protocol which does not support cross origin requests.
<br/><br/>
Use the <code>server</code> script instead:
<br/><br/>
<code>node ./fixtures/devtools/regression/server.js</code><br/>
<code>open <a href="http://localhost:3000/16.6.html">http://localhost:3000/16.6.html</a></code>
</div>
<script src="shared.js" type="text/babel"></script>
<!--
This is a great way to try React but it's not suitable for production.
It slowly compiles JSX with Babel in the browser and uses a large development build of React.
Learn more at https://reactjs.org/docs/getting-started.html
-->
</body>
</html>

View File

@@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>React 16.7</title>
<link rel="stylesheet" href="styles.css" />
<script type="text/javascript">
// Enable DevTools to inspect React inside of an <iframe>
// This must run before React is loaded
__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
</script>
<script src="https://unpkg.com/scheduler@0.12.0/umd/scheduler.development.js"></script>
<script src="https://unpkg.com/scheduler@0.12.0/umd/scheduler-tracing.development.js"></script>
<script src="https://unpkg.com/react@16.7/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/react-cache@2.0.0-alpha.1/umd/react-cache.development.js"></script>
<!-- Don't use this in production: -->
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
<div id="root">
If you are seeing this message, you are likely viewing this file using the <code>file</code> protocol which does not support cross origin requests.
<br/><br/>
Use the <code>server</code> script instead:
<br/><br/>
<code>node ./fixtures/devtools/regression/server.js</code><br/>
<code>open <a href="http://localhost:3000/16.7.html">http://localhost:3000/16.7.html</a></code>
</div>
<script src="shared.js" type="text/babel"></script>
<!--
This is a great way to try React but it's not suitable for production.
It slowly compiles JSX with Babel in the browser and uses a large development build of React.
Learn more at https://reactjs.org/docs/getting-started.html
-->
</body>
</html>

View File

@@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>React canary</title>
<link rel="stylesheet" href="styles.css" />
<script type="text/javascript">
// Enable DevTools to inspect React inside of an <iframe>
// This must run before React is loaded
__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
</script>
<script src="https://unpkg.com/scheduler@canary/umd/scheduler.development.js"></script>
<script src="https://unpkg.com/scheduler@canary/umd/scheduler-tracing.development.js"></script>
<script src="https://unpkg.com/react@canary/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@canary/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/react-cache@next/umd/react-cache.development.js"></script>
<!-- Don't use this in production: -->
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
<div id="root">
If you are seeing this message, you are likely viewing this file using the <code>file</code> protocol which does not support cross origin requests.
<br/><br/>
Use the <code>server</code> script instead:
<br/><br/>
<code>node ./fixtures/devtools/regression/server.js</code><br/>
<code>open <a href="http://localhost:3000/canary.html">http://localhost:3000/canary.html</a></code>
</div>
<script src="shared.js" type="text/babel"></script>
<!--
This is a great way to try React but it's not suitable for production.
It slowly compiles JSX with Babel in the browser and uses a large development build of React.
Learn more at https://reactjs.org/docs/getting-started.html
-->
</body>
</html>

View File

@@ -0,0 +1,28 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>React DevTools regression test</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<iframe src="canary.html"></iframe>
<iframe src="next.html"></iframe>
<iframe src="16.7.html"></iframe>
<iframe src="16.6.html"></iframe>
<iframe src="16.5.html"></iframe>
<iframe src="16.4.html"></iframe>
<iframe src="16.3.html"></iframe>
<iframe src="16.2.html"></iframe>
<iframe src="16.1.html"></iframe>
<iframe src="16.0.html"></iframe>
<iframe src="15.6.html"></iframe>
<iframe src="15.5.html"></iframe>
<iframe src="15.4.html"></iframe>
<iframe src="15.3.html"></iframe>
<iframe src="15.2.html"></iframe>
<iframe src="15.1.html"></iframe>
<iframe src="15.0.html"></iframe>
<iframe src="14.9.html"></iframe>
</body>
</html>

View File

@@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>React next</title>
<link rel="stylesheet" href="styles.css" />
<script type="text/javascript">
// Enable DevTools to inspect React inside of an <iframe>
// This must run before React is loaded
__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
</script>
<script src="https://unpkg.com/scheduler@next/umd/scheduler.development.js"></script>
<script src="https://unpkg.com/scheduler@next/umd/scheduler-tracing.development.js"></script>
<script src="https://unpkg.com/react@next/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@next/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/react-cache@next/umd/react-cache.development.js"></script>
<!-- Don't use this in production: -->
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
<div id="root">
If you are seeing this message, you are likely viewing this file using the <code>file</code> protocol which does not support cross origin requests.
<br/><br/>
Use the <code>server</code> script instead:
<br/><br/>
<code>node ./fixtures/devtools/regression/server.js</code><br/>
<code>open <a href="http://localhost:3000/next.html">http://localhost:3000/next.html</a></code>
</div>
<script src="shared.js" type="text/babel"></script>
<!--
This is a great way to try React but it's not suitable for production.
It slowly compiles JSX with Babel in the browser and uses a large development build of React.
Learn more at https://reactjs.org/docs/getting-started.html
-->
</body>
</html>

View File

@@ -0,0 +1,16 @@
#!/usr/bin/env node
const finalhandler = require('finalhandler');
const http = require('http');
const serveStatic = require('serve-static');
// Serve fixtures folder
const serve = serveStatic(__dirname, {index: 'index.html'});
// Create server
const server = http.createServer(function onRequest(req, res) {
serve(req, res, finalhandler(req, res));
});
// Listen
server.listen(3000);

View File

@@ -0,0 +1,328 @@
/* eslint-disable no-fallthrough, react/react-in-jsx-scope, react/jsx-no-undef */
/* global React ReactCache ReactDOM SchedulerTracing ScheduleTracing */
const apps = [];
const pieces = React.version.split('.');
const major =
pieces[0] === '0' ? parseInt(pieces[1], 10) : parseInt(pieces[0], 10);
const minor =
pieces[0] === '0' ? parseInt(pieces[2], 10) : parseInt(pieces[1], 10);
// Convenience wrapper to organize API features in DevTools.
function Feature({children, label, version}) {
return (
<div className="Feature">
<div className="FeatureHeader">
<code className="FeatureCode">{label}</code>
<small>{version}</small>
</div>
{children}
</div>
);
}
// Simplify interaction tracing for tests below.
let trace = null;
if (typeof SchedulerTracing !== 'undefined') {
trace = SchedulerTracing.unstable_trace;
} else if (typeof ScheduleTracing !== 'undefined') {
trace = ScheduleTracing.unstable_trace;
} else {
trace = (_, __, callback) => callback();
}
// https://github.com/facebook/react/blob/master/CHANGELOG.md
switch (major) {
case 16:
switch (minor) {
case 7:
if (typeof React.useState === 'function') {
// Hooks
function Hooks() {
const [count, setCount] = React.useState(0);
const incrementCount = React.useCallback(
() => setCount(count + 1),
[count]
);
return (
<div>
count: {count}{' '}
<button onClick={incrementCount}>increment</button>
</div>
);
}
apps.push(
<Feature key="Hooks" label="Hooks" version="16.7+">
<Hooks />
</Feature>
);
}
case 6:
// memo
function LabelComponent({label}) {
return <label>{label}</label>;
}
const AnonymousMemoized = React.memo(({label}) => (
<label>{label}</label>
));
const Memoized = React.memo(LabelComponent);
const CustomMemoized = React.memo(LabelComponent);
CustomMemoized.displayName = 'MemoizedLabelFunction';
apps.push(
<Feature key="memo" label="memo" version="16.6+">
<AnonymousMemoized label="AnonymousMemoized" />
<Memoized label="Memoized" />
<CustomMemoized label="CustomMemoized" />
</Feature>
);
// Suspense
const loadResource = ([text, ms]) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(text);
}, ms);
});
};
const getResourceKey = ([text, ms]) => text;
const Resource = ReactCache.unstable_createResource(
loadResource,
getResourceKey
);
class Suspending extends React.Component {
state = {useSuspense: false};
useSuspense = () => this.setState({useSuspense: true});
render() {
if (this.state.useSuspense) {
const text = Resource.read(['loaded', 2000]);
return text;
} else {
return <button onClick={this.useSuspense}>load data</button>;
}
}
}
apps.push(
<Feature key="Suspense" label="Suspense" version="16.6+">
<React.Suspense fallback={<div>loading...</div>}>
<Suspending />
</React.Suspense>
</Feature>
);
// lazy
const LazyWithDefaultProps = React.lazy(
() =>
new Promise(resolve => {
function FooWithDefaultProps(props) {
return (
<h1>
{props.greeting}, {props.name}
</h1>
);
}
FooWithDefaultProps.defaultProps = {
name: 'World',
greeting: 'Bonjour',
};
resolve({
default: FooWithDefaultProps,
});
})
);
apps.push(
<Feature key="lazy" label="lazy" version="16.6+">
<React.Suspense fallback={<div>loading...</div>}>
<LazyWithDefaultProps greeting="Hello" />
</React.Suspense>
</Feature>
);
case 5:
case 4:
// unstable_Profiler
class ProfilerChild extends React.Component {
state = {count: 0};
incrementCount = () =>
this.setState(prevState => ({count: prevState.count + 1}));
render() {
return (
<div>
count: {this.state.count}{' '}
<button onClick={this.incrementCount}>increment</button>
</div>
);
}
}
const onRender = (...args) => {};
const Profiler = React.unstable_Profiler || React.Profiler;
apps.push(
<Feature
key="unstable_Profiler"
label="unstable_Profiler"
version="16.4+">
<Profiler id="count" onRender={onRender}>
<div>
<ProfilerChild />
</div>
</Profiler>
</Feature>
);
case 3:
// createContext()
const LocaleContext = React.createContext();
LocaleContext.displayName = 'LocaleContext';
const ThemeContext = React.createContext();
apps.push(
<Feature key="createContext" label="createContext" version="16.3+">
<ThemeContext.Provider value="blue">
<ThemeContext.Consumer>
{theme => <div>theme: {theme}</div>}
</ThemeContext.Consumer>
</ThemeContext.Provider>
<LocaleContext.Provider value="en-US">
<LocaleContext.Consumer>
{locale => <div>locale: {locale}</div>}
</LocaleContext.Consumer>
</LocaleContext.Provider>
</Feature>
);
// forwardRef()
const AnonymousFunction = React.forwardRef((props, ref) => (
<div ref={ref}>{props.children}</div>
));
const NamedFunction = React.forwardRef(function named(props, ref) {
return <div ref={ref}>{props.children}</div>;
});
const CustomName = React.forwardRef((props, ref) => (
<div ref={ref}>{props.children}</div>
));
CustomName.displayName = 'CustomNameForwardRef';
apps.push(
<Feature key="forwardRef" label="forwardRef" version="16.3+">
<AnonymousFunction>AnonymousFunction</AnonymousFunction>
<NamedFunction>NamedFunction</NamedFunction>
<CustomName>CustomName</CustomName>
</Feature>
);
// StrictMode
class StrictModeChild extends React.Component {
render() {
return 'StrictModeChild';
}
}
apps.push(
<Feature key="StrictMode" label="StrictMode" version="16.3+">
<React.StrictMode>
<StrictModeChild />
</React.StrictMode>
</Feature>
);
// unstable_AsyncMode (later renamed to unstable_ConcurrentMode, then ConcurrentMode)
const ConcurrentMode =
React.ConcurrentMode ||
React.unstable_ConcurrentMode ||
React.unstable_AsyncMode;
apps.push(
<Feature
key="AsyncMode/ConcurrentMode"
label="AsyncMode/ConcurrentMode"
version="16.3+">
<ConcurrentMode>
<div>
unstable_AsyncMode was added in 16.3, renamed to
unstable_ConcurrentMode in 16.5, and then renamed to
ConcurrentMode in 16.7
</div>
</ConcurrentMode>
</Feature>
);
case 2:
// Fragment
apps.push(
<Feature key="Fragment" label="Fragment" version="16.4+">
<React.Fragment>
<div>one</div>
<div>two</div>
</React.Fragment>
</Feature>
);
case 1:
case 0:
default:
break;
}
break;
case 15:
break;
case 14:
break;
default:
break;
}
function Even() {
return <small>(even)</small>;
}
// Simple stateful app shared by all React versions
class SimpleApp extends React.Component {
state = {count: 0};
incrementCount = () => {
const updaterFn = prevState => ({count: prevState.count + 1});
trace('Updating count', performance.now(), () => this.setState(updaterFn));
};
render() {
const {count} = this.state;
return (
<div>
{count % 2 === 0 ? (
<span>
count: {count} <Even />
</span>
) : (
<span>count: {count}</span>
)}{' '}
<button onClick={this.incrementCount}>increment</button>
</div>
);
}
}
apps.push(
<Feature key="Simple stateful app" label="Simple stateful app" version="any">
<SimpleApp />
</Feature>
);
// This component, with the version prop, helps organize DevTools at a glance.
function TopLevelWrapperForDevTools({version}) {
let header = <h1>React {version}</h1>;
if (version.includes('canary')) {
const commitSha = version.match(/.+canary-(.+)/)[1];
header = (
<h1>
React canary{' '}
<a href={`https://github.com/facebook/react/commit/${commitSha}`}>
{commitSha}
</a>
</h1>
);
} else if (version.includes('alpha')) {
header = <h1>React next</h1>;
}
return (
<div>
{header}
{apps}
</div>
);
}
TopLevelWrapperForDevTools.displayName = 'React';
ReactDOM.render(
<TopLevelWrapperForDevTools version={React.version} />,
document.getElementById('root')
);

View File

@@ -0,0 +1,37 @@
body {
font-family: sans-serif;
font-size: 12px;
}
h1 {
margin: 0;
font-size: 20px;
}
h2 {
margin: 1rem 0 0;
}
iframe {
border: 1px solid #ddd;
border-radius: 0.5rem;
}
code {
white-space: nowrap;
}
.Feature {
margin: 1rem 0;
border-bottom: 1px solid #eee;
padding-bottom: 1rem;
}
.FeatureHeader {
font-size: 16px;
margin-bottom: 0.5rem;
}
.FeatureCode {
background-color: #eee;
padding: 0.25rem;
border-radius: 0.25rem;
}

View File

@@ -0,0 +1,313 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>TODO List</title>
<!-- DevTools -->
<script src="http://localhost:8097"></script>
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/immutable@4.0.0-rc.12/dist/immutable.js"></script>
<!-- Don't use this in production: -->
<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
<style type="text/css">
.Input {
font-size: 1rem;
padding: 0.25rem;
}
.IconButton {
padding: 0.25rem;
border: none;
background: none;
cursor: pointer;
}
.List {
margin: 0.5rem 0 0;
padding: 0;
}
.ListItem {
list-style-type: none;
}
.Label {
cursor: pointer;
padding: 0.25rem;
color: #555;
}
.Label:hover {
color: #000;
}
.IconButton {
padding: 0.25rem;
border: none;
background: none;
cursor: pointer;
}
</style>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
const { Fragment, useCallback, useState } = React;
function List(props) {
const [newItemText, setNewItemText] = useState("");
const [items, setItems] = useState([
{ id: 1, isComplete: true, text: "First" },
{ id: 2, isComplete: true, text: "Second" },
{ id: 3, isComplete: false, text: "Third" }
]);
const [uid, setUID] = useState(4);
const handleClick = useCallback(() => {
if (newItemText !== "") {
setItems([
...items,
{
id: uid,
isComplete: false,
text: newItemText
}
]);
setUID(uid + 1);
setNewItemText("");
}
}, [newItemText, items, uid]);
const handleKeyPress = useCallback(
event => {
if (event.key === "Enter") {
handleClick();
}
},
[handleClick]
);
const handleChange = useCallback(
event => {
setNewItemText(event.currentTarget.value);
},
[setNewItemText]
);
const removeItem = useCallback(
itemToRemove => setItems(items.filter(item => item !== itemToRemove)),
[items]
);
const toggleItem = useCallback(
itemToToggle => {
const index = items.indexOf(itemToToggle);
setItems(
items
.slice(0, index)
.concat({
...itemToToggle,
isComplete: !itemToToggle.isComplete
})
.concat(items.slice(index + 1))
);
},
[items]
);
return (
<Fragment>
<h1>List</h1>
<input
type="text"
placeholder="New list item..."
className="Input"
value={newItemText}
onChange={handleChange}
onKeyPress={handleKeyPress}
/>
<button
className="IconButton"
disabled={newItemText === ""}
onClick={handleClick}
>
<span role="img" aria-label="Add item">
</span>
</button>
<ul className="List">
{items.map(item => (
<ListItem
key={item.id}
item={item}
removeItem={removeItem}
toggleItem={toggleItem}
/>
))}
</ul>
</Fragment>
);
}
function ListItem({ item, removeItem, toggleItem }) {
const handleDelete = useCallback(() => {
removeItem(item);
}, [item, removeItem]);
const handleToggle = useCallback(() => {
toggleItem(item);
}, [item, toggleItem]);
return (
<li className="ListItem">
<button className="IconButton" onClick={handleDelete}>
🗑
</button>
<label className="Label">
<input
className="Input"
checked={item.isComplete}
onChange={handleToggle}
type="checkbox"
/>{" "}
{item.text}
</label>
</li>
);
}
function SimpleValues() {
return (
<ChildComponent
string="abc"
emptyString=""
number={123}
undefined={undefined}
null={null}
nan={NaN}
infinity={Infinity}
true={true}
false={false}
/>
);
}
class Custom {
_number = 42;
get number() {
return this._number;
}
}
function CustomObject() {
return <ChildComponent customObject={new Custom()} />;
}
const object = {
string: "abc",
longString: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKJLMNOPQRSTUVWXYZ1234567890",
emptyString: "",
number: 123,
boolean: true,
undefined: undefined,
null: null
};
function ObjectProps() {
return (
<ChildComponent
object={{
outer: {
inner: object
}
}}
array={["first", "second", "third"]}
objectInArray={[object]}
arrayInObject={{ array: ["first", "second", "third"] }}
deepObject={{
// Known limitation: we won't go deeper than several levels.
// In the future, we might offer a way to request deeper access on demand.
a: {
b: {
c: {
d: {
e: {
f: {
g: {
h: {
i: {
j: 10
}
}
}
}
}
}
}
}
}
}}
/>
);
}
const set = new Set(['abc', 123]);
const map = new Map([['name', 'Brian'], ['food', 'sushi']]);
const setOfSets = new Set([new Set(['a', 'b', 'c']), new Set([1, 2, 3])]);
const mapOfMaps = new Map([['first', map], ['second', map]]);
const typedArray = Int8Array.from([100, -100, 0]);
const immutable = Immutable.fromJS({
a: [{ hello: 'there' }, 'fixed', true],
b: 123,
c: {
'1': 'xyz',
xyz: 1,
},
});
function UnserializableProps() {
return (
<ChildComponent
map={map}
set={set}
mapOfMaps={mapOfMaps}
setOfSets={setOfSets}
typedArray={typedArray}
immutable={immutable}
/>
);
}
function ChildComponent(props: any) {
return null;
}
function InspectableElements() {
return (
<Fragment>
<SimpleValues />
<ObjectProps />
<UnserializableProps />
<CustomObject />
</Fragment>
);
}
function App() {
return (
<Fragment>
<List />
<InspectableElements />
</Fragment>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
</script>
</body>
</html>

View File

@@ -17,6 +17,7 @@ let TestRenderer;
let ARTTest;
global.__DEV__ = process.env.NODE_ENV !== 'production';
global.__EXPERIMENTAL__ = process.env.RELEASE_CHANNEL === 'experimental';
expect.extend(require('../toWarnDev'));
@@ -176,19 +177,21 @@ it("doesn't warn if you use nested acts from different renderers", () => {
});
});
it('warns when using createRoot() + .render', () => {
const root = ReactDOM.unstable_createRoot(document.createElement('div'));
expect(() => {
TestRenderer.act(() => {
root.render(<App />);
});
}).toWarnDev(
[
'In Concurrent or Sync modes, the "scheduler" module needs to be mocked',
"It looks like you're using the wrong act()",
],
{
withoutStack: true,
}
);
});
if (__EXPERIMENTAL__) {
it('warns when using createRoot() + .render', () => {
const root = ReactDOM.createRoot(document.createElement('div'));
expect(() => {
TestRenderer.act(() => {
root.render(<App />);
});
}).toWarnDev(
[
'In Concurrent or Sync modes, the "scheduler" module needs to be mocked',
"It looks like you're using the wrong act()",
],
{
withoutStack: true,
}
);
});
}

View File

@@ -1,5 +1,6 @@
import FixtureSet from '../../FixtureSet';
import MouseMovement from './mouse-movement';
import MouseEnter from './mouse-enter';
const React = window.React;
@@ -8,6 +9,7 @@ class MouseEvents extends React.Component {
return (
<FixtureSet title="Mouse Events">
<MouseMovement />
<MouseEnter />
</FixtureSet>
);
}

View File

@@ -0,0 +1,73 @@
import TestCase from '../../TestCase';
const React = window.React;
const ReactDOM = window.ReactDOM;
const MouseEnter = () => {
const containerRef = React.useRef();
React.useEffect(function() {
const hostEl = containerRef.current;
ReactDOM.render(<MouseEnterDetect />, hostEl, () => {
ReactDOM.render(<MouseEnterDetect />, hostEl.childNodes[1]);
});
}, []);
return (
<TestCase
title="Mouse Enter"
description=""
affectedBrowsers="Chrome, Safari, Firefox">
<TestCase.Steps>
<li>Mouse enter the boxes below, from different borders</li>
</TestCase.Steps>
<TestCase.ExpectedResult>
Mouse enter call count should equal to 1; <br />
Issue{' '}
<a
rel="noopener noreferrer"
target="_blank"
href="https://github.com/facebook/react/issues/16763">
#16763
</a>{' '}
should not happen.
<br />
</TestCase.ExpectedResult>
<div ref={containerRef} />
</TestCase>
);
};
const MouseEnterDetect = () => {
const [log, setLog] = React.useState({});
const firstEl = React.useRef();
const siblingEl = React.useRef();
const onMouseEnter = e => {
const timeStamp = e.timeStamp;
setLog(log => {
const callCount = 1 + (log.timeStamp === timeStamp ? log.callCount : 0);
return {
timeStamp,
callCount,
};
});
};
return (
<React.Fragment>
<div
ref={firstEl}
onMouseEnter={onMouseEnter}
style={{
border: '1px solid #d9d9d9',
padding: '20px 20px',
}}>
Mouse enter call count: {log.callCount || ''}
</div>
<div ref={siblingEl} />
</React.Fragment>
);
};
export default MouseEnter;

View File

@@ -1,3 +1,4 @@
import Fixture from '../../Fixture';
import FixtureSet from '../../FixtureSet';
import TestCase from '../../TestCase';
@@ -39,6 +40,44 @@ export default class TextAreaFixtures extends React.Component {
<textarea placeholder="Hello, world" />
</div>
</TestCase>
<TestCase
title="Required Textareas"
affectedBrowsers="Firefox"
relatedIssues="16402">
<TestCase.Steps>
<li>View this test in Firefox</li>
</TestCase.Steps>
<TestCase.ExpectedResult>
You should{' '}
<b>
<i>not</i>
</b>{' '}
see a red aura on initial page load, indicating the textarea is
invalid.
<br />
This aura looks roughly like:
<textarea style={{boxShadow: '0 0 1px 1px red', marginLeft: 8}} />
</TestCase.ExpectedResult>
<Fixture>
<form className="control-box">
<fieldset>
<legend>Empty value prop string</legend>
<textarea value="" required={true} />
</fieldset>
<fieldset>
<legend>No value prop</legend>
<textarea required={true} />
</fieldset>
<fieldset>
<legend>Empty defaultValue prop string</legend>
<textarea required={true} defaultValue="" />
</fieldset>
</form>
</Fixture>
</TestCase>
</FixtureSet>
);
}

View File

@@ -0,0 +1,108 @@
<!DOCTYPE html>
<html style="width: 100%; height: 100%; overflow: hidden">
<head>
<meta charset="utf-8">
<title>Flight Example</title>
</head>
<body>
<h1>Flight Example</h1>
<div id="container">
<p>
To install React, follow the instructions on
<a href="https://github.com/facebook/react/">GitHub</a>.
</p>
<p>
If you can see this, React is <strong>not</strong> working right.
If you checked out the source from GitHub make sure to run <code>npm run build</code>.
</p>
</div>
<script src="../../build/dist/react.development.js"></script>
<script src="../../build/dist/react-dom.development.js"></script>
<script src="../../build/dist/react-dom-server.browser.development.js"></script>
<script src="../../build/dist/react-flight-dom-webpack-server.browser.development.js"></script>
<script src="../../build/dist/react-flight-dom-webpack.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.js"></script>
<script type="text/babel">
let Suspense = React.Suspense;
function Text({children}) {
return <span>{children}</span>;
}
function HTML() {
return (
<div>
<Text>hello</Text>
<Text>world</Text>
</div>
);
}
let resolved = false;
let promise = new Promise(resolve => {
setTimeout(() => {
resolved = true;
resolve();
}, 100);
});
function read() {
if (!resolved) {
throw promise;
}
}
function Title() {
read();
return 'Title';
}
let model = {
title: <Title />,
content: {
__html: <HTML />,
}
};
let stream = ReactFlightDOMServer.renderToReadableStream(model);
let response = new Response(stream, {
headers: {'Content-Type': 'text/html'},
});
display(response);
async function display(responseToDisplay) {
let blob = await responseToDisplay.blob();
let url = URL.createObjectURL(blob);
let data = ReactFlightDOMClient.readFromFetch(
fetch(url)
);
// The client also supports XHR streaming.
// var xhr = new XMLHttpRequest();
// xhr.open('GET', url);
// let data = ReactFlightDOMClient.readFromXHR(xhr);
// xhr.send();
renderResult(data);
}
function Shell({ data }) {
let model = data.model;
return <div>
<Suspense fallback="...">
<h1>{model.title}</h1>
</Suspense>
<div dangerouslySetInnerHTML={model.content} />
</div>;
}
function renderResult(data) {
let container = document.getElementById('container');
ReactDOM.render(
<Suspense fallback="Loading...">
<Shell data={data} />
</Suspense>,
container
);
}
</script>
</body>
</html>

1
fixtures/flight/.env Normal file
View File

@@ -0,0 +1 @@
SKIP_PREFLIGHT_CHECK=true

23
fixtures/flight/.gitignore vendored Normal file
View File

@@ -0,0 +1,23 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

View File

@@ -0,0 +1,37 @@
{
"name": "flight",
"version": "0.1.0",
"private": true,
"dependencies": {
"@babel/register": "^7.7.0",
"concurrently": "^5.0.0",
"express": "^4.17.1",
"react-scripts": "3.2.0"
},
"scripts": {
"prestart": "cp -r ../../build/node_modules/* ./node_modules/",
"prebuild": "cp -r ../../build/node_modules/* ./node_modules/",
"start": "concurrently \"npm run start:server\" \"npm run start:client\"",
"start:client": "react-scripts start",
"start:server": "NODE_ENV=development node server",
"start:prod": "react-scripts build && NODE_ENV=production node server",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}

View File

@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Flight</title>
</head>
<body>
<div id="root"></div>
</body>
</html>

View File

@@ -0,0 +1,28 @@
'use strict';
const ReactFlightDOMServer = require('react-flight-dom-webpack/server');
const React = require('react');
const Stream = require('stream');
function Text({children}) {
return <span>{children}</span>;
}
function HTML() {
return (
<div>
<Text>Hello</Text>
<Text>world</Text>
</div>
);
}
module.exports = function(req, res) {
res.setHeader('Access-Control-Allow-Origin', '*');
let model = {
content: {
__html: <HTML />,
},
};
ReactFlightDOMServer.pipeToNodeWritable(model, res);
};

View File

@@ -0,0 +1,46 @@
'use strict';
const babelRegister = require('@babel/register');
babelRegister({
ignore: [/\/(build|node_modules)\//],
presets: ['react-app'],
});
const express = require('express');
const app = express();
// Application
app.get('/', function(req, res) {
if (process.env.NODE_ENV === 'development') {
for (var key in require.cache) {
delete require.cache[key];
}
}
require('./handler')(req, res);
});
app.listen(3001, () => {
console.log('Flight Server listening on port 3001...');
});
app.on('error', function(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port;
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
});

View File

@@ -0,0 +1,15 @@
import React, {Suspense} from 'react';
function Content({data}) {
return <p dangerouslySetInnerHTML={data.model.content} />;
}
function App({data}) {
return (
<Suspense fallback={<h1>Loading...</h1>}>
<Content data={data} />
</Suspense>
);
}
export default App;

View File

@@ -0,0 +1,7 @@
import React from 'react';
import ReactDOM from 'react-dom';
import ReactFlightDOMClient from 'react-flight-dom-webpack';
import App from './App';
let data = ReactFlightDOMClient.readFromFetch(fetch('http://localhost:3001'));
ReactDOM.render(<App data={data} />, document.getElementById('root'));

9863
fixtures/flight/yarn.lock Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
import React from 'react';
import {unstable_createRoot} from 'react-dom';
import {createRoot} from 'react-dom';
import App from './components/App';
let root = unstable_createRoot(document, {hydrate: true});
let root = createRoot(document, {hydrate: true});
root.render(<App assets={window.assetManifest} />);

View File

@@ -2999,6 +2999,11 @@ js-tokens@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.1.tgz#08e9f132484a2c45a30907e9dc4d5567b7f114d7"
"js-tokens@^3.0.0 || ^4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
js-yaml@^3.4.3, js-yaml@^3.5.1, js-yaml@^3.7.0, js-yaml@~3.7.0:
version "3.7.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.7.0.tgz#5c967ddd837a9bfdca5f2de84253abe8a1c03b80"
@@ -3248,6 +3253,13 @@ loose-envify@^1.0.0:
dependencies:
js-tokens "^3.0.0"
loose-envify@^1.1.0, loose-envify@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
dependencies:
js-tokens "^3.0.0 || ^4.0.0"
lower-case@^1.1.1:
version "1.1.4"
resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac"
@@ -3558,9 +3570,10 @@ oauth-sign@~0.8.1:
version "0.8.2"
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
object-assign@4.1.1, object-assign@^4.0.1, object-assign@^4.1.0:
object-assign@4.1.1, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
object.omit@^2.0.0:
version "2.0.1"
@@ -4071,6 +4084,15 @@ promise@7.1.1:
dependencies:
asap "~2.0.3"
prop-types@^15.6.2:
version "15.7.2"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
dependencies:
loose-envify "^1.4.0"
object-assign "^4.1.1"
react-is "^16.8.1"
proxy-addr@~1.1.3:
version "1.1.4"
resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-1.1.4.tgz#27e545f6960a44a627d9b44467e35c1b6b4ce2f3"
@@ -4160,6 +4182,11 @@ react-dev-utils@^0.5.2:
version "0.0.0"
uid ""
react-is@^16.8.1:
version "16.12.0"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.12.0.tgz#2cc0fe0fba742d97fd527c42a13bec4eeb06241c"
integrity sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==
react-scripts@0.9.5:
version "0.9.5"
resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-0.9.5.tgz#e9f05c8427e27131662a9b9d7a9786d1ff16bb3f"
@@ -4495,6 +4522,14 @@ sax@^1.2.1, sax@~1.2.1:
version "1.2.2"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.2.tgz#fd8631a23bc7826bef5d871bdb87378c95647828"
scheduler@^0.18.0:
version "0.18.0"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.18.0.tgz#5901ad6659bc1d8f3fdaf36eb7a67b0d6746b1c4"
integrity sha512-agTSHR1Nbfi6ulI0kYNK0203joW2Y5W4po4l+v03tOoiJKpTBbxpNhWDvqc/4IcOw+KLmSiQLTasZ4cab2/UWQ==
dependencies:
loose-envify "^1.1.0"
object-assign "^4.1.1"
"semver@2 || 3 || 4 || 5", semver@^5.1.0, semver@^5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"

View File

@@ -1,5 +1,5 @@
const {createElement, Component, Placeholder} = React;
const {unstable_createRoot: createRoot} = ReactDOM;
const {createElement, Component, Suspense} = React;
const {createRoot} = ReactDOM;
const {
unstable_subscribe: subscribe,
unstable_trace: trace,
@@ -56,8 +56,8 @@ const read = key => {
const TestApp = () =>
createElement(
Placeholder,
{delayMs: 100, fallback: createElement(PlaceholderText)},
Suspense,
{fallback: createElement(PlaceholderText)},
createElement(SuspendingChild, {text: 'foo'}),
createElement(SuspendingChild, {text: 'bar'}),
createElement(SuspendingChild, {text: 'baz'})
@@ -91,13 +91,11 @@ subscribe({
const element = document.getElementById('root');
trace('initial_render', performance.now(), () => {
const root = createRoot(element);
const batch = root.createBatch();
log.app('batch.render()');
batch.render(createElement(TestApp));
batch.then(
log.app('render()');
root.render(
createElement(TestApp),
wrap(() => {
log.app('batch.commit()');
batch.commit();
log.app('commited');
})
);
});

View File

@@ -12,6 +12,7 @@
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/plugin-proposal-object-rest-spread": "^7.0.0",
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
"@babel/plugin-syntax-jsx": "^7.2.0",
"@babel/plugin-transform-arrow-functions": "^7.0.0",
"@babel/plugin-transform-async-to-generator": "^7.0.0",
"@babel/plugin-transform-block-scoped-functions": "^7.0.0",
@@ -43,14 +44,14 @@
"coveralls": "^2.11.6",
"create-react-class": "^15.6.3",
"cross-env": "^5.1.1",
"danger": "^3.0.4",
"danger": "^9.1.8",
"error-stack-parser": "^2.0.2",
"eslint": "^6.1.0",
"eslint-config-fbjs": "^1.1.1",
"eslint-plugin-babel": "^5.3.0",
"eslint-plugin-flowtype": "^2.25.0",
"eslint-plugin-jest": "^22.15.0",
"eslint-plugin-no-for-of-loops": "^1.0.0",
"eslint-plugin-babel": "^5.3.0",
"eslint-plugin-react": "^6.7.1",
"eslint-plugin-react-internal": "link:./scripts/eslint-rules",
"fbjs-scripts": "^0.8.3",
@@ -61,14 +62,15 @@
"google-closure-compiler": "20190301.0.0",
"gzip-size": "^3.0.0",
"jasmine-check": "^1.0.0-rc.0",
"jest": "^23.1.0",
"jest-diff": "^23.0.1",
"jest": "^24.9.0",
"jest-diff": "^24.9.0",
"jest-snapshot-serializer-raw": "^1.1.0",
"minimatch": "^3.0.4",
"minimist": "^1.2.0",
"mkdirp": "^0.5.1",
"ncp": "^2.0.0",
"object-assign": "^4.1.1",
"pacote": "^9.5.6",
"prettier": "1.13.7",
"prop-types": "^15.6.2",
"random-seed": "^0.3.0",
@@ -85,7 +87,8 @@
"targz": "^1.0.1",
"through2": "^2.0.0",
"tmp": "~0.0.28",
"typescript": "~1.8.10"
"typescript": "~1.8.10",
"webpack": "^4.41.2"
},
"devEngines": {
"node": "8.x || 9.x || 10.x || 11.x || 12.x"
@@ -99,7 +102,7 @@
"lint": "node ./scripts/tasks/eslint.js",
"lint-build": "node ./scripts/rollup/validate/index.js",
"extract-errors": "yarn build --type=dev --extract-errors",
"postinstall": "node node_modules/fbjs-scripts/node/check-dev-engines.js package.json && node ./scripts/flow/createFlowConfigs.js",
"postinstall": "node node_modules/fbjs-scripts/node/check-dev-engines.js package.json && node ./scripts/flow/createFlowConfigs.js && node ./scripts/yarn/downloadReactIsForPrettyFormat.js",
"debug-test": "cross-env NODE_ENV=development node --inspect-brk node_modules/.bin/jest --config ./scripts/jest/config.source.js --runInBand",
"test": "cross-env NODE_ENV=development jest --config ./scripts/jest/config.source.js",
"test-persistent": "cross-env NODE_ENV=development jest --config ./scripts/jest/config.source-persistent.js",
@@ -108,6 +111,8 @@
"test-prod-build": "yarn test-build-prod",
"test-build": "cross-env NODE_ENV=development jest --config ./scripts/jest/config.build.js",
"test-build-prod": "cross-env NODE_ENV=production jest --config ./scripts/jest/config.build.js",
"test-build-devtools": "cross-env NODE_ENV=development jest --config ./scripts/jest/config.build-devtools.js",
"debug-test-build-devtools": "cross-env NODE_ENV=development node --inspect-brk node_modules/.bin/jest --config ./scripts/jest/config.build-devtools.js",
"test-dom-fixture": "cd fixtures/dom && yarn && yarn prestart && yarn test",
"flow": "node ./scripts/tasks/flow.js",
"flow-ci": "node ./scripts/tasks/flow-ci.js",

View File

@@ -0,0 +1,5 @@
This package is intended to eventually replace the current `@babel/plugin-transform-react-jsx`, changing the JSX transform from targeting `React.createElement(type, props, children)` to `React.jsx(types, props, key)`.
https://github.com/reactjs/rfcs/blob/createlement-rfc/text/0000-create-element-changes.md
**This is experimental and not intended to be used directly.**

View File

@@ -0,0 +1,392 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/* eslint-disable quotes */
'use strict';
const babel = require('@babel/core');
const codeFrame = require('@babel/code-frame');
const {wrap} = require('jest-snapshot-serializer-raw');
function transform(input, options) {
return wrap(
babel.transform(input, {
configFile: false,
plugins: [
'@babel/plugin-syntax-jsx',
'@babel/plugin-transform-arrow-functions',
...(options && options.development
? [
'@babel/plugin-transform-react-jsx-source',
'@babel/plugin-transform-react-jsx-self',
]
: []),
[
'./packages/babel-plugin-react-jsx',
{
development: __DEV__,
useBuiltIns: true,
useCreateElement: true,
...options,
},
],
],
}).code
);
}
describe('transform react to jsx', () => {
it('fragment with no children', () => {
expect(transform(`var x = <></>`)).toMatchSnapshot();
});
it('React.Fragment to set keys and source', () => {
expect(
transform(`var x = <React.Fragment key='foo'><div /></React.Fragment>`, {
development: true,
})
).toMatchSnapshot();
});
it('normal fragments not to set key and source', () => {
expect(
transform(`var x = <><div /></>`, {
development: true,
})
).toMatchSnapshot();
});
it('should properly handle comments adjacent to children', () => {
expect(
transform(`
var x = (
<div>
{/* A comment at the beginning */}
{/* A second comment at the beginning */}
<span>
{/* A nested comment */}
</span>
{/* A sandwiched comment */}
<br />
{/* A comment at the end */}
{/* A second comment at the end */}
</div>
);
`)
).toMatchSnapshot();
});
it('adds appropriate new lines when using spread attribute', () => {
expect(transform(`<Component {...props} sound="moo" />`)).toMatchSnapshot();
});
it('arrow functions', () => {
expect(
transform(`
var foo = function () {
return () => <this />;
};
var bar = function () {
return () => <this.foo />;
};
`)
).toMatchSnapshot();
});
it('assignment', () => {
expect(
transform(`var div = <Component {...props} foo="bar" />`)
).toMatchSnapshot();
});
it('concatenates adjacent string literals', () => {
expect(
transform(`
var x =
<div>
foo
{"bar"}
baz
<div>
buz
bang
</div>
qux
{null}
quack
</div>
`)
).toMatchSnapshot();
});
it('should allow constructor as prop', () => {
expect(transform(`<Component constructor="foo" />;`)).toMatchSnapshot();
});
it('should allow deeper js namespacing', () => {
expect(
transform(`<Namespace.DeepNamespace.Component />;`)
).toMatchSnapshot();
});
it('should allow elements as attributes', () => {
expect(transform(`<div attr=<div /> />`)).toMatchSnapshot();
});
it('should allow js namespacing', () => {
expect(transform(`<Namespace.Component />;`)).toMatchSnapshot();
});
it('should allow nested fragments', () => {
expect(
transform(`
<div>
< >
<>
<span>Hello</span>
<span>world</span>
</>
<>
<span>Goodbye</span>
<span>world</span>
</>
</>
</div>
`)
).toMatchSnapshot();
});
it('should avoid wrapping in extra parens if not needed', () => {
expect(
transform(`
var x = <div>
<Component />
</div>;
var x = <div>
{props.children}
</div>;
var x = <Composite>
{props.children}
</Composite>;
var x = <Composite>
<Composite2 />
</Composite>;
`)
).toMatchSnapshot();
});
it('should convert simple tags', () => {
expect(transform(`var x = <div></div>;`)).toMatchSnapshot();
});
it('should convert simple text', () => {
expect(transform(`var x = <div>text</div>;`)).toMatchSnapshot();
});
it('should disallow spread children', () => {
let _error;
const code = `<div>{...children}</div>;`;
try {
transform(code);
} catch (error) {
_error = error;
}
expect(_error).toEqual(
new SyntaxError(
'undefined: Spread children are not supported in React.' +
'\n' +
codeFrame.codeFrameColumns(
code,
{start: {line: 1, column: 6}},
{highlightCode: true}
)
)
);
});
it('should escape xhtml jsxattribute', () => {
expect(
transform(`
<div id="wôw" />;
<div id="\w" />;
<div id="w &lt; w" />;
`)
).toMatchSnapshot();
});
it('should escape xhtml jsxtext', () => {
/* eslint-disable no-irregular-whitespace */
expect(
transform(`
<div>wow</div>;
<div>wôw</div>;
<div>w & w</div>;
<div>w &amp; w</div>;
<div>w &nbsp; w</div>;
<div>this should not parse as unicode: \u00a0</div>;
<div>this should parse as nbsp:   </div>;
<div>this should parse as unicode: {'\u00a0 '}</div>;
<div>w &lt; w</div>;
`)
).toMatchSnapshot();
/*eslint-enable */
});
it('should handle attributed elements', () => {
expect(
transform(`
var HelloMessage = React.createClass({
render: function() {
return <div>Hello {this.props.name}</div>;
}
});
React.render(<HelloMessage name={
<span>
Sebastian
</span>
} />, mountNode);
`)
).toMatchSnapshot();
});
it('should handle has own property correctly', () => {
expect(
transform(`<hasOwnProperty>testing</hasOwnProperty>;`)
).toMatchSnapshot();
});
it('should have correct comma in nested children', () => {
expect(
transform(`
var x = <div>
<div><br /></div>
<Component>{foo}<br />{bar}</Component>
<br />
</div>;
`)
).toMatchSnapshot();
});
it('should insert commas after expressions before whitespace', () => {
expect(
transform(`
var x =
<div
attr1={
"foo" + "bar"
}
attr2={
"foo" + "bar" +
"baz" + "bug"
}
attr3={
"foo" + "bar" +
"baz" + "bug"
}
attr4="baz">
</div>
`)
).toMatchSnapshot();
});
it('should not add quotes to identifier names', () => {
expect(
transform(`var e = <F aaa new const var default foo-bar/>;`)
).toMatchSnapshot();
});
it('should not strip nbsp even couple with other whitespace', () => {
expect(transform(`<div>&nbsp; </div>;`)).toMatchSnapshot();
});
it('should not strip tags with a single child of nbsp', () => {
expect(transform(`<div>&nbsp;</div>;`)).toMatchSnapshot();
});
it('should properly handle comments between props', () => {
expect(
transform(`
var x = (
<div
/* a multi-line
comment */
attr1="foo">
<span // a double-slash comment
attr2="bar"
/>
</div>
);
`)
).toMatchSnapshot();
});
it('should quote jsx attributes', () => {
expect(
transform(`<button data-value='a value'>Button</button>`)
).toMatchSnapshot();
});
it('should support xml namespaces if flag', () => {
expect(
transform('<f:image n:attr />', {throwIfNamespace: false})
).toMatchSnapshot();
});
it('should throw error namespaces if not flag', () => {
let _error;
const code = `<f:image />`;
try {
transform(code);
} catch (error) {
_error = error;
}
expect(_error).toEqual(
new SyntaxError(
"undefined: Namespace tags are not supported by default. React's " +
"JSX doesn't support namespace tags. You can turn on the " +
"'throwIfNamespace' flag to bypass this warning." +
'\n' +
codeFrame.codeFrameColumns(
code,
{start: {line: 1, column: 2}},
{highlightCode: true}
)
)
);
});
it('should transform known hyphenated tags', () => {
expect(transform(`<font-face />`)).toMatchSnapshot();
});
it('wraps props in react spread for first spread attributes', () => {
expect(transform(`<Component {...x} y={2} z />`)).toMatchSnapshot();
});
it('wraps props in react spread for last spread attributes', () => {
expect(transform(`<Component y={2} z { ... x } />`)).toMatchSnapshot();
});
it('wraps props in react spread for middle spread attributes', () => {
expect(transform(`<Component y={2} { ... x } z />`)).toMatchSnapshot();
});
it('useBuiltIns false uses extend instead of Object.assign', () => {
expect(
transform(`<Component y={2} {...x} />`, {useBuiltIns: false})
).toMatchSnapshot();
});
});

View File

@@ -0,0 +1,504 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/* eslint-disable quotes */
'use strict';
const babel = require('@babel/core');
const codeFrame = require('@babel/code-frame');
const {wrap} = require('jest-snapshot-serializer-raw');
function transform(input, options) {
return wrap(
babel.transform(input, {
configFile: false,
plugins: [
'@babel/plugin-syntax-jsx',
'@babel/plugin-transform-arrow-functions',
...(options && options.development
? [
'@babel/plugin-transform-react-jsx-source',
'@babel/plugin-transform-react-jsx-self',
]
: []),
[
'./packages/babel-plugin-react-jsx',
{
useBuiltIns: true,
useCreateElement: false,
...options,
},
],
],
}).code
);
}
describe('transform react to jsx', () => {
it('fragment with no children', () => {
expect(transform(`var x = <></>`)).toMatchSnapshot();
});
it('fragments', () => {
expect(transform(`var x = <><div /></>`)).toMatchSnapshot();
});
it('fragments to set keys', () => {
expect(
transform(`var x = <React.Fragment key="foo"></React.Fragment>`)
).toMatchSnapshot();
});
it('React.fragment to set keys and source', () => {
expect(
transform(`var x = <React.Fragment key='foo'></React.Fragment>`, {
development: true,
})
).toMatchSnapshot();
});
it('fragments in dev mode (no key and source)', () => {
expect(
transform(`var x = <><div /></>`, {
development: true,
})
).toMatchSnapshot();
});
it('nonStatic children', () => {
expect(
transform(
`var x = (
<div>
{[<span key={'0'} />, <span key={'1'} />]}
</div>
);
`,
{
development: true,
}
)
).toMatchSnapshot();
});
it('static children', () => {
expect(
transform(
`var x = (
<div>
<span />
{[<span key={'0'} />, <span key={'1'} />]}
</div>
);
`,
{
development: true,
}
)
).toMatchSnapshot();
});
it('uses jsxDEV instead of jsx in dev mode', () => {
expect(
transform(`var x = <span propOne="one">Hi</span>`, {development: true})
).toMatchSnapshot();
});
it('properly passes in source and self', () => {
expect(
transform(`var x = <div />;`, {development: true})
).toMatchSnapshot();
});
it('should properly handle potentially null variables', () => {
expect(
transform(`
var foo = null;
var x = <div {...foo} />;
`)
).toMatchSnapshot();
});
it('properly handles keys', () => {
expect(
transform(`var x = (
<div>
<div key="1" />
<div key="2" meow="wolf" />
<div key="3" />
</div>
);`)
).toMatchSnapshot();
});
it('uses createElement when the key comes after a spread', () => {
expect(
transform(`var x = (
<div {...props} key="1" foo="bar" />
);`)
).toMatchSnapshot();
});
it('uses jsx when the key comes before a spread', () => {
expect(
transform(`var x = (
<div key="1" {...props} foo="bar" />
);`)
).toMatchSnapshot();
});
it('should properly handle comments adjacent to children', () => {
expect(
transform(`
var x = (
<div>
{/* A comment at the beginning */}
{/* A second comment at the beginning */}
<span>
{/* A nested comment */}
</span>
{/* A sandwiched comment */}
<br />
{/* A comment at the end */}
{/* A second comment at the end */}
</div>
);
`)
).toMatchSnapshot();
});
it('adds appropriate new lines when using spread attribute', () => {
expect(transform(`<Component {...props} sound="moo" />`)).toMatchSnapshot();
});
it('arrow functions', () => {
expect(
transform(`
var foo = function () {
return () => <this />;
};
var bar = function () {
return () => <this.foo />;
};
`)
).toMatchSnapshot();
});
it('assignment', () => {
expect(
transform(`var div = <Component {...props} foo="bar" />`)
).toMatchSnapshot();
});
it('concatenates adjacent string literals', () => {
expect(
transform(`
var x =
<div>
foo
{"bar"}
baz
<div>
buz
bang
</div>
qux
{null}
quack
</div>
`)
).toMatchSnapshot();
});
it('should allow constructor as prop', () => {
expect(transform(`<Component constructor="foo" />;`)).toMatchSnapshot();
});
it('should allow deeper js namespacing', () => {
expect(
transform(`<Namespace.DeepNamespace.Component />;`)
).toMatchSnapshot();
});
it('should allow elements as attributes', () => {
expect(transform(`<div attr=<div /> />`)).toMatchSnapshot();
});
it('should allow js namespacing', () => {
expect(transform(`<Namespace.Component />;`)).toMatchSnapshot();
});
it('should allow nested fragments', () => {
expect(
transform(`
<div>
< >
<>
<span>Hello</span>
<span>world</span>
</>
<>
<span>Goodbye</span>
<span>world</span>
</>
</>
</div>
`)
).toMatchSnapshot();
});
it('should avoid wrapping in extra parens if not needed', () => {
expect(
transform(`
var x = <div>
<Component />
</div>;
var x = <div>
{props.children}
</div>;
var x = <Composite>
{props.children}
</Composite>;
var x = <Composite>
<Composite2 />
</Composite>;
`)
).toMatchSnapshot();
});
it('should convert simple tags', () => {
expect(transform(`var x = <div></div>;`)).toMatchSnapshot();
});
it('should convert simple text', () => {
expect(transform(`var x = <div>text</div>;`)).toMatchSnapshot();
});
it('should disallow spread children', () => {
let _error;
const code = `<div>{...children}</div>;`;
try {
transform(code);
} catch (error) {
_error = error;
}
expect(_error).toEqual(
new SyntaxError(
'undefined: Spread children are not supported in React.' +
'\n' +
codeFrame.codeFrameColumns(
code,
{start: {line: 1, column: 6}},
{highlightCode: true}
)
)
);
});
it('should escape xhtml jsxattribute', () => {
expect(
transform(`
<div id="wôw" />;
<div id="\w" />;
<div id="w &lt; w" />;
`)
).toMatchSnapshot();
});
it('should escape xhtml jsxtext', () => {
/* eslint-disable no-irregular-whitespace */
expect(
transform(`
<div>wow</div>;
<div>wôw</div>;
<div>w & w</div>;
<div>w &amp; w</div>;
<div>w &nbsp; w</div>;
<div>this should not parse as unicode: \u00a0</div>;
<div>this should parse as nbsp:   </div>;
<div>this should parse as unicode: {'\u00a0 '}</div>;
<div>w &lt; w</div>;
`)
).toMatchSnapshot();
/*eslint-enable */
});
it('should handle attributed elements', () => {
expect(
transform(`
var HelloMessage = React.createClass({
render: function() {
return <div>Hello {this.props.name}</div>;
}
});
React.render(<HelloMessage name={
<span>
Sebastian
</span>
} />, mountNode);
`)
).toMatchSnapshot();
});
it('should handle has own property correctly', () => {
expect(
transform(`<hasOwnProperty>testing</hasOwnProperty>;`)
).toMatchSnapshot();
});
it('should have correct comma in nested children', () => {
expect(
transform(`
var x = <div>
<div><br /></div>
<Component>{foo}<br />{bar}</Component>
<br />
</div>;
`)
).toMatchSnapshot();
});
it('should insert commas after expressions before whitespace', () => {
expect(
transform(`
var x =
<div
attr1={
"foo" + "bar"
}
attr2={
"foo" + "bar" +
"baz" + "bug"
}
attr3={
"foo" + "bar" +
"baz" + "bug"
}
attr4="baz">
</div>
`)
).toMatchSnapshot();
});
it('should not add quotes to identifier names', () => {
expect(
transform(`var e = <F aaa new const var default foo-bar/>;`)
).toMatchSnapshot();
});
it('should not strip nbsp even couple with other whitespace', () => {
expect(transform(`<div>&nbsp; </div>;`)).toMatchSnapshot();
});
it('should not strip tags with a single child of nbsp', () => {
expect(transform(`<div>&nbsp;</div>;`)).toMatchSnapshot();
});
it('should properly handle comments between props', () => {
expect(
transform(`
var x = (
<div
/* a multi-line
comment */
attr1="foo">
<span // a double-slash comment
attr2="bar"
/>
</div>
);
`)
).toMatchSnapshot();
});
it('should quote jsx attributes', () => {
expect(
transform(`<button data-value='a value'>Button</button>`)
).toMatchSnapshot();
});
it('should support xml namespaces if flag', () => {
expect(
transform('<f:image n:attr />', {throwIfNamespace: false})
).toMatchSnapshot();
});
it('should throw error namespaces if not flag', () => {
let _error;
const code = `<f:image />`;
try {
transform(code);
} catch (error) {
_error = error;
}
expect(_error).toEqual(
new SyntaxError(
"undefined: Namespace tags are not supported by default. React's " +
"JSX doesn't support namespace tags. You can turn on the " +
"'throwIfNamespace' flag to bypass this warning." +
'\n' +
codeFrame.codeFrameColumns(
code,
{start: {line: 1, column: 2}},
{highlightCode: true}
)
)
);
});
it('should transform known hyphenated tags', () => {
expect(transform(`<font-face />`)).toMatchSnapshot();
});
it('wraps props in react spread for first spread attributes', () => {
expect(transform(`<Component {...x} y={2} z />`)).toMatchSnapshot();
});
it('wraps props in react spread for last spread attributes', () => {
expect(transform(`<Component y={2} z { ... x } />`)).toMatchSnapshot();
});
it('wraps props in react spread for middle spread attributes', () => {
expect(transform(`<Component y={2} { ... x } z />`)).toMatchSnapshot();
});
it('useBuiltIns false uses extend instead of Object.assign', () => {
expect(
transform(`<Component y={2} {...x} />`, {useBuiltIns: false})
).toMatchSnapshot();
});
it('duplicate children prop should transform into sequence expression with actual children', () => {
expect(
transform(`<Component children={1}>2</Component>`)
).toMatchSnapshot();
});
it('duplicate children prop should transform into sequence expression with next prop', () => {
expect(
transform(`<Component children={1} foo={3}>2</Component>`)
).toMatchSnapshot();
});
it('duplicate children props should transform into sequence expression with next prop', () => {
expect(
transform(`<Component children={1} children={4} foo={3}>2</Component>`)
).toMatchSnapshot();
});
it('duplicate children prop should transform into sequence expression with spread', () => {
expect(
transform(`<Component children={1} {...x}>2</Component>`)
).toMatchSnapshot();
});
});

View File

@@ -0,0 +1,213 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`transform react to jsx React.Fragment to set keys and source 1`] = `
var _jsxFileName = "";
var x = React.createElement(React.Fragment, {
key: "foo",
__source: {
fileName: _jsxFileName,
lineNumber: 1
},
__self: this
}, React.createElement("div", {
__source: {
fileName: _jsxFileName,
lineNumber: 1
},
__self: this
}));
`;
exports[`transform react to jsx adds appropriate new lines when using spread attribute 1`] = `
React.createElement(Component, Object.assign({}, props, {
sound: "moo"
}));
`;
exports[`transform react to jsx arrow functions 1`] = `
var foo = function () {
var _this = this;
return function () {
return React.createElement(_this, null);
};
};
var bar = function () {
var _this2 = this;
return function () {
return React.createElement(_this2.foo, null);
};
};
`;
exports[`transform react to jsx assignment 1`] = `
var div = React.createElement(Component, Object.assign({}, props, {
foo: "bar"
}));
`;
exports[`transform react to jsx concatenates adjacent string literals 1`] = `var x = React.createElement("div", null, "foo", "bar", "baz", React.createElement("div", null, "buz bang"), "qux", null, "quack");`;
exports[`transform react to jsx fragment with no children 1`] = `var x = React.createElement(React.Fragment, null);`;
exports[`transform react to jsx normal fragments not to set key and source 1`] = `
var _jsxFileName = "";
var x = React.createElement(React.Fragment, null, React.createElement("div", {
__source: {
fileName: _jsxFileName,
lineNumber: 1
},
__self: this
}));
`;
exports[`transform react to jsx should allow constructor as prop 1`] = `
React.createElement(Component, {
constructor: "foo"
});
`;
exports[`transform react to jsx should allow deeper js namespacing 1`] = `React.createElement(Namespace.DeepNamespace.Component, null);`;
exports[`transform react to jsx should allow elements as attributes 1`] = `
React.createElement("div", {
attr: React.createElement("div", null)
});
`;
exports[`transform react to jsx should allow js namespacing 1`] = `React.createElement(Namespace.Component, null);`;
exports[`transform react to jsx should allow nested fragments 1`] = `React.createElement("div", null, React.createElement(React.Fragment, null, React.createElement(React.Fragment, null, React.createElement("span", null, "Hello"), React.createElement("span", null, "world")), React.createElement(React.Fragment, null, React.createElement("span", null, "Goodbye"), React.createElement("span", null, "world"))));`;
exports[`transform react to jsx should avoid wrapping in extra parens if not needed 1`] = `
var x = React.createElement("div", null, React.createElement(Component, null));
var x = React.createElement("div", null, props.children);
var x = React.createElement(Composite, null, props.children);
var x = React.createElement(Composite, null, React.createElement(Composite2, null));
`;
exports[`transform react to jsx should convert simple tags 1`] = `var x = React.createElement("div", null);`;
exports[`transform react to jsx should convert simple text 1`] = `var x = React.createElement("div", null, "text");`;
exports[`transform react to jsx should escape xhtml jsxattribute 1`] = `
React.createElement("div", {
id: "w\\xF4w"
});
React.createElement("div", {
id: "w"
});
React.createElement("div", {
id: "w < w"
});
`;
exports[`transform react to jsx should escape xhtml jsxtext 1`] = `
React.createElement("div", null, "wow");
React.createElement("div", null, "w\\xF4w");
React.createElement("div", null, "w & w");
React.createElement("div", null, "w & w");
React.createElement("div", null, "w \\xA0 w");
React.createElement("div", null, "this should not parse as unicode: \\xA0");
React.createElement("div", null, "this should parse as nbsp: \\xA0 ");
React.createElement("div", null, "this should parse as unicode: ", '  ');
React.createElement("div", null, "w < w");
`;
exports[`transform react to jsx should handle attributed elements 1`] = `
var HelloMessage = React.createClass({
render: function () {
return React.createElement("div", null, "Hello ", this.props.name);
}
});
React.render(React.createElement(HelloMessage, {
name: React.createElement("span", null, "Sebastian")
}), mountNode);
`;
exports[`transform react to jsx should handle has own property correctly 1`] = `React.createElement("hasOwnProperty", null, "testing");`;
exports[`transform react to jsx should have correct comma in nested children 1`] = `var x = React.createElement("div", null, React.createElement("div", null, React.createElement("br", null)), React.createElement(Component, null, foo, React.createElement("br", null), bar), React.createElement("br", null));`;
exports[`transform react to jsx should insert commas after expressions before whitespace 1`] = `
var x = React.createElement("div", {
attr1: "foo" + "bar",
attr2: "foo" + "bar" + "baz" + "bug",
attr3: "foo" + "bar" + "baz" + "bug",
attr4: "baz"
});
`;
exports[`transform react to jsx should not add quotes to identifier names 1`] = `
var e = React.createElement(F, {
aaa: true,
new: true,
const: true,
var: true,
default: true,
"foo-bar": true
});
`;
exports[`transform react to jsx should not strip nbsp even couple with other whitespace 1`] = `React.createElement("div", null, "\\xA0 ");`;
exports[`transform react to jsx should not strip tags with a single child of nbsp 1`] = `React.createElement("div", null, "\\xA0");`;
exports[`transform react to jsx should properly handle comments adjacent to children 1`] = `var x = React.createElement("div", null, React.createElement("span", null), React.createElement("br", null));`;
exports[`transform react to jsx should properly handle comments between props 1`] = `
var x = React.createElement("div", {
/* a multi-line
comment */
attr1: "foo"
}, React.createElement("span", {
// a double-slash comment
attr2: "bar"
}));
`;
exports[`transform react to jsx should quote jsx attributes 1`] = `
React.createElement("button", {
"data-value": "a value"
}, "Button");
`;
exports[`transform react to jsx should support xml namespaces if flag 1`] = `
React.createElement("f:image", {
"n:attr": true
});
`;
exports[`transform react to jsx should transform known hyphenated tags 1`] = `React.createElement("font-face", null);`;
exports[`transform react to jsx useBuiltIns false uses extend instead of Object.assign 1`] = `
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
React.createElement(Component, _extends({
y: 2
}, x));
`;
exports[`transform react to jsx wraps props in react spread for first spread attributes 1`] = `
React.createElement(Component, Object.assign({}, x, {
y: 2,
z: true
}));
`;
exports[`transform react to jsx wraps props in react spread for last spread attributes 1`] = `
React.createElement(Component, Object.assign({
y: 2,
z: true
}, x));
`;
exports[`transform react to jsx wraps props in react spread for middle spread attributes 1`] = `
React.createElement(Component, Object.assign({
y: 2
}, x, {
z: true
}));
`;

View File

@@ -0,0 +1,400 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`transform react to jsx React.fragment to set keys and source 1`] = `
var _jsxFileName = "";
var x = React.jsxDEV(React.Fragment, {}, "foo", false, {
fileName: _jsxFileName,
lineNumber: 1
}, this);
`;
exports[`transform react to jsx adds appropriate new lines when using spread attribute 1`] = `
React.jsx(Component, Object.assign({}, props, {
sound: "moo"
}));
`;
exports[`transform react to jsx arrow functions 1`] = `
var foo = function () {
var _this = this;
return function () {
return React.jsx(_this, {});
};
};
var bar = function () {
var _this2 = this;
return function () {
return React.jsx(_this2.foo, {});
};
};
`;
exports[`transform react to jsx assignment 1`] = `
var div = React.jsx(Component, Object.assign({}, props, {
foo: "bar"
}));
`;
exports[`transform react to jsx concatenates adjacent string literals 1`] = `
var x = React.jsxs("div", {
children: ["foo", "bar", "baz", React.jsx("div", {
children: "buz bang"
}), "qux", null, "quack"]
});
`;
exports[`transform react to jsx duplicate children prop should transform into sequence expression with actual children 1`] = `
React.jsx(Component, {
children: (1, "2")
});
`;
exports[`transform react to jsx duplicate children prop should transform into sequence expression with next prop 1`] = `
React.jsx(Component, {
foo: (1, 3),
children: "2"
});
`;
exports[`transform react to jsx duplicate children prop should transform into sequence expression with spread 1`] = `
React.jsx(Component, Object.assign({}, (1, x), {
children: "2"
}));
`;
exports[`transform react to jsx duplicate children props should transform into sequence expression with next prop 1`] = `
React.jsx(Component, {
foo: (1, 4, 3),
children: "2"
});
`;
exports[`transform react to jsx fragment with no children 1`] = `var x = React.jsx(React.Fragment, {});`;
exports[`transform react to jsx fragments 1`] = `
var x = React.jsx(React.Fragment, {
children: React.jsx("div", {})
});
`;
exports[`transform react to jsx fragments in dev mode (no key and source) 1`] = `
var _jsxFileName = "";
var x = React.jsxDEV(React.Fragment, {
children: React.jsxDEV("div", {}, undefined, false, {
fileName: _jsxFileName,
lineNumber: 1
}, this)
}, undefined, false);
`;
exports[`transform react to jsx fragments to set keys 1`] = `var x = React.jsx(React.Fragment, {}, "foo");`;
exports[`transform react to jsx nonStatic children 1`] = `
var _jsxFileName = "";
var x = React.jsxDEV("div", {
children: [React.jsxDEV("span", {}, '0', false, {
fileName: _jsxFileName,
lineNumber: 3
}, this), React.jsxDEV("span", {}, '1', false, {
fileName: _jsxFileName,
lineNumber: 3
}, this)]
}, undefined, false, {
fileName: _jsxFileName,
lineNumber: 2
}, this);
`;
exports[`transform react to jsx properly handles keys 1`] = `
var x = React.jsxs("div", {
children: [React.jsx("div", {}, "1"), React.jsx("div", {
meow: "wolf"
}, "2"), React.jsx("div", {}, "3")]
});
`;
exports[`transform react to jsx properly passes in source and self 1`] = `
var _jsxFileName = "";
var x = React.jsxDEV("div", {}, undefined, false, {
fileName: _jsxFileName,
lineNumber: 1
}, this);
`;
exports[`transform react to jsx should allow constructor as prop 1`] = `
React.jsx(Component, {
constructor: "foo"
});
`;
exports[`transform react to jsx should allow deeper js namespacing 1`] = `React.jsx(Namespace.DeepNamespace.Component, {});`;
exports[`transform react to jsx should allow elements as attributes 1`] = `
React.jsx("div", {
attr: React.jsx("div", {})
});
`;
exports[`transform react to jsx should allow js namespacing 1`] = `React.jsx(Namespace.Component, {});`;
exports[`transform react to jsx should allow nested fragments 1`] = `
React.jsx("div", {
children: React.jsxs(React.Fragment, {
children: [React.jsxs(React.Fragment, {
children: [React.jsx("span", {
children: "Hello"
}), React.jsx("span", {
children: "world"
})]
}), React.jsxs(React.Fragment, {
children: [React.jsx("span", {
children: "Goodbye"
}), React.jsx("span", {
children: "world"
})]
})]
})
});
`;
exports[`transform react to jsx should avoid wrapping in extra parens if not needed 1`] = `
var x = React.jsx("div", {
children: React.jsx(Component, {})
});
var x = React.jsx("div", {
children: props.children
});
var x = React.jsx(Composite, {
children: props.children
});
var x = React.jsx(Composite, {
children: React.jsx(Composite2, {})
});
`;
exports[`transform react to jsx should convert simple tags 1`] = `var x = React.jsx("div", {});`;
exports[`transform react to jsx should convert simple text 1`] = `
var x = React.jsx("div", {
children: "text"
});
`;
exports[`transform react to jsx should escape xhtml jsxattribute 1`] = `
React.jsx("div", {
id: "w\\xF4w"
});
React.jsx("div", {
id: "w"
});
React.jsx("div", {
id: "w < w"
});
`;
exports[`transform react to jsx should escape xhtml jsxtext 1`] = `
React.jsx("div", {
children: "wow"
});
React.jsx("div", {
children: "w\\xF4w"
});
React.jsx("div", {
children: "w & w"
});
React.jsx("div", {
children: "w & w"
});
React.jsx("div", {
children: "w \\xA0 w"
});
React.jsx("div", {
children: "this should not parse as unicode: \\xA0"
});
React.jsx("div", {
children: "this should parse as nbsp: \\xA0 "
});
React.jsxs("div", {
children: ["this should parse as unicode: ", '  ']
});
React.jsx("div", {
children: "w < w"
});
`;
exports[`transform react to jsx should handle attributed elements 1`] = `
var HelloMessage = React.createClass({
render: function () {
return React.jsxs("div", {
children: ["Hello ", this.props.name]
});
}
});
React.render(React.jsx(HelloMessage, {
name: React.jsx("span", {
children: "Sebastian"
})
}), mountNode);
`;
exports[`transform react to jsx should handle has own property correctly 1`] = `
React.jsx("hasOwnProperty", {
children: "testing"
});
`;
exports[`transform react to jsx should have correct comma in nested children 1`] = `
var x = React.jsxs("div", {
children: [React.jsx("div", {
children: React.jsx("br", {})
}), React.jsxs(Component, {
children: [foo, React.jsx("br", {}), bar]
}), React.jsx("br", {})]
});
`;
exports[`transform react to jsx should insert commas after expressions before whitespace 1`] = `
var x = React.jsx("div", {
attr1: "foo" + "bar",
attr2: "foo" + "bar" + "baz" + "bug",
attr3: "foo" + "bar" + "baz" + "bug",
attr4: "baz"
});
`;
exports[`transform react to jsx should not add quotes to identifier names 1`] = `
var e = React.jsx(F, {
aaa: true,
new: true,
const: true,
var: true,
default: true,
"foo-bar": true
});
`;
exports[`transform react to jsx should not strip nbsp even couple with other whitespace 1`] = `
React.jsx("div", {
children: "\\xA0 "
});
`;
exports[`transform react to jsx should not strip tags with a single child of nbsp 1`] = `
React.jsx("div", {
children: "\\xA0"
});
`;
exports[`transform react to jsx should properly handle comments adjacent to children 1`] = `
var x = React.jsxs("div", {
children: [React.jsx("span", {}), React.jsx("br", {})]
});
`;
exports[`transform react to jsx should properly handle comments between props 1`] = `
var x = React.jsx("div", {
/* a multi-line
comment */
attr1: "foo",
children: React.jsx("span", {
// a double-slash comment
attr2: "bar"
})
});
`;
exports[`transform react to jsx should properly handle potentially null variables 1`] = `
var foo = null;
var x = React.jsx("div", Object.assign({}, foo));
`;
exports[`transform react to jsx should quote jsx attributes 1`] = `
React.jsx("button", {
"data-value": "a value",
children: "Button"
});
`;
exports[`transform react to jsx should support xml namespaces if flag 1`] = `
React.jsx("f:image", {
"n:attr": true
});
`;
exports[`transform react to jsx should transform known hyphenated tags 1`] = `React.jsx("font-face", {});`;
exports[`transform react to jsx static children 1`] = `
var _jsxFileName = "";
var x = React.jsxDEV("div", {
children: [React.jsxDEV("span", {}, undefined, false, {
fileName: _jsxFileName,
lineNumber: 3
}, this), [React.jsxDEV("span", {}, '0', false, {
fileName: _jsxFileName,
lineNumber: 4
}, this), React.jsxDEV("span", {}, '1', false, {
fileName: _jsxFileName,
lineNumber: 4
}, this)]]
}, undefined, true, {
fileName: _jsxFileName,
lineNumber: 2
}, this);
`;
exports[`transform react to jsx useBuiltIns false uses extend instead of Object.assign 1`] = `
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
React.jsx(Component, _extends({
y: 2
}, x));
`;
exports[`transform react to jsx uses createElement when the key comes after a spread 1`] = `
var x = React.createElement("div", Object.assign({}, props, {
key: "1",
foo: "bar"
}));
`;
exports[`transform react to jsx uses jsx when the key comes before a spread 1`] = `
var x = React.jsx("div", Object.assign({}, props, {
foo: "bar"
}), "1");
`;
exports[`transform react to jsx uses jsxDEV instead of jsx in dev mode 1`] = `
var _jsxFileName = "";
var x = React.jsxDEV("span", {
propOne: "one",
children: "Hi"
}, undefined, false, {
fileName: _jsxFileName,
lineNumber: 1
}, this);
`;
exports[`transform react to jsx wraps props in react spread for first spread attributes 1`] = `
React.jsx(Component, Object.assign({}, x, {
y: 2,
z: true
}));
`;
exports[`transform react to jsx wraps props in react spread for last spread attributes 1`] = `
React.jsx(Component, Object.assign({
y: 2,
z: true
}, x));
`;
exports[`transform react to jsx wraps props in react spread for middle spread attributes 1`] = `
React.jsx(Component, Object.assign({
y: 2
}, x, {
z: true
}));
`;

View File

@@ -0,0 +1,3 @@
'use strict';
module.exports = require('./src/TransformJSXToReactBabelPlugin');

View File

@@ -0,0 +1,7 @@
'use strict';
if (process.env.NODE_ENV === 'production') {
module.exports = require('./cjs/react-jsx-babel.production.min.js');
} else {
module.exports = require('./cjs/react-jsx-babel.development.js');
}

View File

@@ -0,0 +1,18 @@
{
"name": "babel-plugin-react-jsx",
"version": "0.1.0",
"private": true,
"description": "@babel/plugin-transform-react-jsx",
"main": "index.js",
"dependencies": {
"esutils": "^2.0.0"
},
"files": [
"README.md",
"index.js",
"build-info.json",
"cjs/",
"umd/"
]
}

View File

@@ -0,0 +1,658 @@
// MIT License
// Copyright (c) 2014-present Sebastian McKenzie and other contributors
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// © 2019 GitHub, Inc.
'use strict';
const esutils = require('esutils');
function helper(babel, opts) {
const {types: t} = babel;
const visitor = {};
visitor.JSXNamespacedName = function(path, state) {
const throwIfNamespace =
state.opts.throwIfNamespace === undefined
? true
: !!state.opts.throwIfNamespace;
if (throwIfNamespace) {
throw path.buildCodeFrameError(
`Namespace tags are not supported by default. React's JSX doesn't support namespace tags. \
You can turn on the 'throwIfNamespace' flag to bypass this warning.`,
);
}
};
visitor.JSXSpreadChild = function(path) {
throw path.buildCodeFrameError(
'Spread children are not supported in React.',
);
};
visitor.JSXElement = {
exit(path, file) {
let callExpr;
if (file.opts.useCreateElement || shouldUseCreateElement(path)) {
callExpr = buildCreateElementCall(path, file);
} else {
callExpr = buildJSXElementCall(path, file);
}
if (callExpr) {
path.replaceWith(t.inherits(callExpr, path.node));
}
},
};
visitor.JSXFragment = {
exit(path, file) {
if (opts.compat) {
throw path.buildCodeFrameError(
'Fragment tags are only supported in React 16 and up.',
);
}
let callExpr;
if (file.opts.useCreateElement) {
callExpr = buildCreateElementFragmentCall(path, file);
} else {
callExpr = buildJSXFragmentCall(path, file);
}
if (callExpr) {
path.replaceWith(t.inherits(callExpr, path.node));
}
},
};
return visitor;
function convertJSXIdentifier(node, parent) {
if (t.isJSXIdentifier(node)) {
if (node.name === 'this' && t.isReferenced(node, parent)) {
return t.thisExpression();
} else if (esutils.keyword.isIdentifierNameES6(node.name)) {
node.type = 'Identifier';
} else {
return t.stringLiteral(node.name);
}
} else if (t.isJSXMemberExpression(node)) {
return t.memberExpression(
convertJSXIdentifier(node.object, node),
convertJSXIdentifier(node.property, node),
);
} else if (t.isJSXNamespacedName(node)) {
/**
* If there is flag "throwIfNamespace"
* print XMLNamespace like string literal
*/
return t.stringLiteral(`${node.namespace.name}:${node.name.name}`);
}
return node;
}
function convertAttributeValue(node) {
if (t.isJSXExpressionContainer(node)) {
return node.expression;
} else {
return node;
}
}
function convertAttribute(node, duplicateChildren) {
let value = convertAttributeValue(node.value || t.booleanLiteral(true));
if (t.isStringLiteral(value) && !t.isJSXExpressionContainer(node.value)) {
value.value = value.value.replace(/\n\s+/g, ' ');
// "raw" JSXText should not be used from a StringLiteral because it needs to be escaped.
if (value.extra && value.extra.raw) {
delete value.extra.raw;
}
}
if (duplicateChildren && duplicateChildren.length > 0) {
value = t.sequenceExpression([...duplicateChildren, value]);
}
if (t.isJSXNamespacedName(node.name)) {
node.name = t.stringLiteral(
node.name.namespace.name + ':' + node.name.name.name,
);
} else if (esutils.keyword.isIdentifierNameES6(node.name.name)) {
node.name.type = 'Identifier';
} else {
node.name = t.stringLiteral(node.name.name);
}
return t.inherits(t.objectProperty(node.name, value), node);
}
// We want to use React.createElement, even in the case of
// jsx, for <div {...props} key={key} /> to distinguish it
// from <div key={key} {...props} />. This is an intermediary
// step while we deprecate key spread from props. Afterwards,
// we will remove createElement entirely
function shouldUseCreateElement(path) {
const openingPath = path.get('openingElement');
const attributes = openingPath.node.attributes;
let seenPropsSpread = false;
for (let i = 0; i < attributes.length; i++) {
const attr = attributes[i];
if (
seenPropsSpread &&
t.isJSXAttribute(attr) &&
attr.name.name === 'key'
) {
return true;
} else if (t.isJSXSpreadAttribute(attr)) {
seenPropsSpread = true;
}
}
return false;
}
// Builds JSX into:
// Production: React.jsx(type, arguments, key)
// Development: React.jsxDEV(type, arguments, key, isStaticChildren, source, self)
function buildJSXElementCall(path, file) {
if (opts.filter && !opts.filter(path.node, file)) {
return;
}
const openingPath = path.get('openingElement');
openingPath.parent.children = t.react.buildChildren(openingPath.parent);
const tagExpr = convertJSXIdentifier(
openingPath.node.name,
openingPath.node,
);
const args = [];
let tagName;
if (t.isIdentifier(tagExpr)) {
tagName = tagExpr.name;
} else if (t.isLiteral(tagExpr)) {
tagName = tagExpr.value;
}
const state = {
tagExpr: tagExpr,
tagName: tagName,
args: args,
};
if (opts.pre) {
opts.pre(state, file);
}
let attribs = [];
let key;
let source;
let self;
// for React.jsx, key, __source (dev), and __self (dev) is passed in as
// a separate argument rather than in the args object. We go through the
// props and filter out these three keywords so we can pass them in
// as separate arguments later
for (let i = 0; i < openingPath.node.attributes.length; i++) {
const attr = openingPath.node.attributes[i];
if (t.isJSXAttribute(attr) && t.isJSXIdentifier(attr.name)) {
if (attr.name.name === 'key') {
key = convertAttribute(attr).value;
} else if (attr.name.name === '__source') {
source = convertAttribute(attr).value;
} else if (attr.name.name === '__self') {
self = convertAttribute(attr).value;
} else {
attribs.push(attr);
}
} else {
attribs.push(attr);
}
}
if (attribs.length || path.node.children.length) {
attribs = buildJSXOpeningElementAttributes(
attribs,
file,
path.node.children,
);
} else {
// attributes should never be null
attribs = t.objectExpression([]);
}
args.push(attribs);
if (!file.opts.development) {
if (key !== undefined) {
args.push(key);
}
} else {
// isStaticChildren, __source, and __self are only used in development
args.push(
key === undefined ? t.identifier('undefined') : key,
t.booleanLiteral(path.node.children.length > 1),
source === undefined ? t.identifier('undefined') : source,
self === undefined ? t.identifier('undefined') : self,
);
}
if (opts.post) {
opts.post(state, file);
}
return (
state.call ||
t.callExpression(
path.node.children.length > 1 ? state.staticCallee : state.callee,
args,
)
);
}
function isChildrenProp(prop) {
return (
t.isJSXAttribute(prop) &&
t.isJSXIdentifier(prop.name) &&
prop.name.name === 'children'
);
}
// Builds props for React.jsx. This function adds children into the props
// and ensures that props is always an object
function buildJSXOpeningElementAttributes(attribs, file, children) {
let _props = [];
const objs = [];
// In order to avoid having duplicate "children" keys, we avoid
// pushing the "children" prop if we have actual children. However,
// the children prop may have side effects, so to be certain
// these side effects are evaluated, we add them to the following prop
// as a sequence expression to preserve order. So:
// <div children={x++} foo={y}>{child}</div> becomes
// React.jsx('div', {foo: (x++, y), children: child});
// duplicateChildren contains the extra children prop values
let duplicateChildren = [];
const hasChildren = children && children.length > 0;
const useBuiltIns = file.opts.useBuiltIns || false;
if (typeof useBuiltIns !== 'boolean') {
throw new Error(
'transform-react-jsx currently only accepts a boolean option for ' +
'useBuiltIns (defaults to false)',
);
}
while (attribs.length) {
const prop = attribs.shift();
if (hasChildren && isChildrenProp(prop)) {
duplicateChildren.push(convertAttributeValue(prop.value));
} else if (t.isJSXSpreadAttribute(prop)) {
_props = pushProps(_props, objs);
if (duplicateChildren.length > 0) {
objs.push(
t.sequenceExpression([...duplicateChildren, prop.argument]),
);
duplicateChildren = [];
} else {
objs.push(prop.argument);
}
} else {
_props.push(convertAttribute(prop, duplicateChildren));
if (duplicateChildren.length > 0) {
duplicateChildren = [];
}
}
}
// In React.JSX, children is no longer a separate argument, but passed in
// through the argument object
if (hasChildren) {
if (children.length === 1) {
_props.push(
t.objectProperty(
t.identifier('children'),
duplicateChildren.length > 0
? t.sequenceExpression([...duplicateChildren, children[0]])
: children[0],
),
);
} else {
_props.push(
t.objectProperty(
t.identifier('children'),
duplicateChildren.length > 0
? t.sequenceExpression([
...duplicateChildren,
t.arrayExpression(children),
])
: t.arrayExpression(children),
),
);
}
}
pushProps(_props, objs);
if (objs.length === 1) {
// only one object
if (!t.isObjectExpression(objs[0])) {
// if the prop object isn't an object, use Object.assign or _extends
// to ensure that the prop will always be an object (as opposed to a variable
// that could be null at some point)
const expressionHelper = useBuiltIns
? t.memberExpression(t.identifier('Object'), t.identifier('assign'))
: file.addHelper('extends');
attribs = t.callExpression(expressionHelper, [
t.objectExpression([]),
objs[0],
]);
} else {
attribs = objs[0];
}
} else {
// looks like we have multiple objects
if (!t.isObjectExpression(objs[0])) {
objs.unshift(t.objectExpression([]));
}
const expressionHelper = useBuiltIns
? t.memberExpression(t.identifier('Object'), t.identifier('assign'))
: file.addHelper('extends');
// spread it
attribs = t.callExpression(expressionHelper, objs);
}
return attribs;
}
// Builds JSX Fragment <></> into
// Production: React.jsx(type, arguments)
// Development: React.jsxDEV(type, { children})
function buildJSXFragmentCall(path, file) {
if (opts.filter && !opts.filter(path.node, file)) {
return;
}
const openingPath = path.get('openingElement');
openingPath.parent.children = t.react.buildChildren(openingPath.parent);
const args = [];
const tagName = null;
const tagExpr = file.get('jsxFragIdentifier')();
const state = {
tagExpr: tagExpr,
tagName: tagName,
args: args,
};
if (opts.pre) {
opts.pre(state, file);
}
let childrenNode;
if (path.node.children.length > 0) {
if (path.node.children.length === 1) {
childrenNode = path.node.children[0];
} else {
childrenNode = t.arrayExpression(path.node.children);
}
}
args.push(
t.objectExpression(
childrenNode !== undefined
? [t.objectProperty(t.identifier('children'), childrenNode)]
: [],
),
);
if (file.opts.development) {
args.push(
t.identifier('undefined'),
t.booleanLiteral(path.node.children.length > 1),
);
}
if (opts.post) {
opts.post(state, file);
}
return (
state.call ||
t.callExpression(
path.node.children.length > 1 ? state.staticCallee : state.callee,
args,
)
);
}
// Builds JSX into:
// Production: React.createElement(type, arguments, children)
// Development: React.createElement(type, arguments, children, source, self)
function buildCreateElementCall(path, file) {
if (opts.filter && !opts.filter(path.node, file)) {
return;
}
const openingPath = path.get('openingElement');
openingPath.parent.children = t.react.buildChildren(openingPath.parent);
const tagExpr = convertJSXIdentifier(
openingPath.node.name,
openingPath.node,
);
const args = [];
let tagName;
if (t.isIdentifier(tagExpr)) {
tagName = tagExpr.name;
} else if (t.isLiteral(tagExpr)) {
tagName = tagExpr.value;
}
const state = {
tagExpr: tagExpr,
tagName: tagName,
args: args,
};
if (opts.pre) {
opts.pre(state, file);
}
let attribs = openingPath.node.attributes;
if (attribs.length) {
attribs = buildCreateElementOpeningElementAttributes(attribs, file);
} else {
attribs = t.nullLiteral();
}
args.push(attribs, ...path.node.children);
if (opts.post) {
opts.post(state, file);
}
return state.call || t.callExpression(state.oldCallee, args);
}
function pushProps(_props, objs) {
if (!_props.length) {
return _props;
}
objs.push(t.objectExpression(_props));
return [];
}
/**
* The logic for this is quite terse. It's because we need to
* support spread elements. We loop over all attributes,
* breaking on spreads, we then push a new object containing
* all prior attributes to an array for later processing.
*/
function buildCreateElementOpeningElementAttributes(attribs, file) {
let _props = [];
const objs = [];
const useBuiltIns = file.opts.useBuiltIns || false;
if (typeof useBuiltIns !== 'boolean') {
throw new Error(
'transform-react-jsx currently only accepts a boolean option for ' +
'useBuiltIns (defaults to false)',
);
}
while (attribs.length) {
const prop = attribs.shift();
if (t.isJSXSpreadAttribute(prop)) {
_props = pushProps(_props, objs);
objs.push(prop.argument);
} else {
const attr = convertAttribute(prop);
_props.push(attr);
}
}
pushProps(_props, objs);
if (objs.length === 1) {
// only one object
attribs = objs[0];
} else {
// looks like we have multiple objects
if (!t.isObjectExpression(objs[0])) {
objs.unshift(t.objectExpression([]));
}
const expressionHelper = useBuiltIns
? t.memberExpression(t.identifier('Object'), t.identifier('assign'))
: file.addHelper('extends');
// spread it
attribs = t.callExpression(expressionHelper, objs);
}
return attribs;
}
function buildCreateElementFragmentCall(path, file) {
if (opts.filter && !opts.filter(path.node, file)) {
return;
}
const openingPath = path.get('openingElement');
openingPath.parent.children = t.react.buildChildren(openingPath.parent);
const args = [];
const tagName = null;
const tagExpr = file.get('jsxFragIdentifier')();
const state = {
tagExpr: tagExpr,
tagName: tagName,
args: args,
};
if (opts.pre) {
opts.pre(state, file);
}
// no attributes are allowed with <> syntax
args.push(t.nullLiteral(), ...path.node.children);
if (opts.post) {
opts.post(state, file);
}
return state.call || t.callExpression(state.oldCallee, args);
}
}
module.exports = function(babel) {
const {types: t} = babel;
const createIdentifierParser = id => () => {
return id
.split('.')
.map(name => t.identifier(name))
.reduce((object, property) => t.memberExpression(object, property));
};
const visitor = helper(babel, {
pre(state) {
const tagName = state.tagName;
const args = state.args;
if (t.react.isCompatTag(tagName)) {
args.push(t.stringLiteral(tagName));
} else {
args.push(state.tagExpr);
}
},
post(state, pass) {
state.callee = pass.get('jsxIdentifier')();
state.staticCallee = pass.get('jsxStaticIdentifier')();
state.oldCallee = pass.get('oldJSXIdentifier')();
},
});
visitor.Program = {
enter(path, state) {
state.set(
'oldJSXIdentifier',
createIdentifierParser('React.createElement'),
);
state.set(
'jsxIdentifier',
createIdentifierParser(
state.opts.development ? 'React.jsxDEV' : 'React.jsx',
),
);
state.set(
'jsxStaticIdentifier',
createIdentifierParser(
state.opts.development ? 'React.jsxDEV' : 'React.jsxs',
),
);
state.set('jsxFragIdentifier', createIdentifierParser('React.Fragment'));
},
};
visitor.JSXAttribute = function(path) {
if (t.isJSXElement(path.node.value)) {
path.node.value = t.jsxExpressionContainer(path.node.value);
}
};
return {
name: 'transform-react-jsx',
visitor,
};
};

View File

@@ -1,7 +1,7 @@
{
"name": "create-subscription",
"description": "utility for subscribing to external data sources inside React components",
"version": "16.9.0",
"version": "16.12.0",
"repository": {
"type": "git",
"url": "https://github.com/facebook/react.git",

View File

@@ -36,14 +36,16 @@ export function createSubscription<Property, Value>(
}> {
const {getCurrentValue, subscribe} = config;
warningWithoutStack(
typeof getCurrentValue === 'function',
'Subscription must specify a getCurrentValue function',
);
warningWithoutStack(
typeof subscribe === 'function',
'Subscription must specify a subscribe function',
);
if (__DEV__) {
warningWithoutStack(
typeof getCurrentValue === 'function',
'Subscription must specify a getCurrentValue function',
);
warningWithoutStack(
typeof subscribe === 'function',
'Subscription must specify a subscribe function',
);
}
type Props = {
children: (value: Value) => React$Element<any>,

View File

@@ -141,6 +141,46 @@ const tests = {
return useHook1(useHook2());
}
`,
`
// Valid because hooks can be used in anonymous arrow-function arguments
// to forwardRef.
const FancyButton = React.forwardRef((props, ref) => {
useHook();
return <button {...props} ref={ref} />
});
`,
`
// Valid because hooks can be used in anonymous function arguments to
// forwardRef.
const FancyButton = React.forwardRef(function (props, ref) {
useHook();
return <button {...props} ref={ref} />
});
`,
`
// Valid because hooks can be used in anonymous function arguments to
// forwardRef.
const FancyButton = forwardRef(function (props, ref) {
useHook();
return <button {...props} ref={ref} />
});
`,
`
// Valid because hooks can be used in anonymous function arguments to
// React.memo.
const MemoizedFunction = React.memo(props => {
useHook();
return <button {...props} />
});
`,
`
// Valid because hooks can be used in anonymous function arguments to
// memo.
const MemoizedFunction = memo(function (props) {
useHook();
return <button {...props} />
});
`,
`
// Valid because classes can call functions.
// We don't consider these to be hooks.
@@ -262,6 +302,24 @@ const tests = {
});
}
`,
`
// This is valid because "use"-prefixed functions called in
// unnamed function arguments are not assumed to be hooks.
React.unknownFunction((foo, bar) => {
if (foo) {
useNotAHook(bar)
}
});
`,
`
// This is valid because "use"-prefixed functions called in
// unnamed function arguments are not assumed to be hooks.
unknownFunction(function(foo, bar) {
if (foo) {
useNotAHook(bar)
}
});
`,
`
// Regression test for incorrectly flagged valid code.
function RegressionTest() {
@@ -437,6 +495,32 @@ const tests = {
`,
errors: [genericError('useHookInsideCallback')],
},
{
code: `
// Invalid because it's a common misunderstanding.
// We *could* make it valid but the runtime error could be confusing.
const ComponentWithHookInsideCallback = React.forwardRef((props, ref) => {
useEffect(() => {
useHookInsideCallback();
});
return <button {...props} ref={ref} />
});
`,
errors: [genericError('useHookInsideCallback')],
},
{
code: `
// Invalid because it's a common misunderstanding.
// We *could* make it valid but the runtime error could be confusing.
const ComponentWithHookInsideCallback = React.memo(props => {
useEffect(() => {
useHookInsideCallback();
});
return <button {...props} />
});
`,
errors: [genericError('useHookInsideCallback')],
},
{
code: `
// Invalid because it's a common misunderstanding.
@@ -695,6 +779,55 @@ const tests = {
// conditionalError('useState'),
],
},
{
code: `
// Invalid because it's dangerous and might not warn otherwise.
// This *must* be invalid.
const FancyButton = React.forwardRef((props, ref) => {
if (props.fancy) {
useCustomHook();
}
return <button ref={ref}>{props.children}</button>;
});
`,
errors: [conditionalError('useCustomHook')],
},
{
code: `
// Invalid because it's dangerous and might not warn otherwise.
// This *must* be invalid.
const FancyButton = forwardRef(function(props, ref) {
if (props.fancy) {
useCustomHook();
}
return <button ref={ref}>{props.children}</button>;
});
`,
errors: [conditionalError('useCustomHook')],
},
{
code: `
// Invalid because it's dangerous and might not warn otherwise.
// This *must* be invalid.
const MemoizedButton = memo(function(props) {
if (props.fancy) {
useCustomHook();
}
return <button>{props.children}</button>;
});
`,
errors: [conditionalError('useCustomHook')],
},
{
code: `
// This is invalid because "use"-prefixed functions used in named
// functions are assumed to be hooks.
React.unknownFunction(function notAComponent(foo, bar) {
useProbablyAHook(bar)
});
`,
errors: [functionError('useProbablyAHook', 'notAComponent')],
},
{
code: `
// Invalid because it's dangerous.
@@ -758,8 +891,8 @@ function loopError(hook) {
function functionError(hook, fn) {
return {
message:
`React Hook "${hook}" is called in function "${fn}" which is neither ` +
'a React function component or a custom React Hook function.',
`React Hook "${hook}" is called in function "${fn}" that is neither ` +
'a React function component nor a custom React Hook function.',
};
}

View File

@@ -1,7 +1,7 @@
{
"name": "eslint-plugin-react-hooks",
"description": "ESLint rules for React Hooks",
"version": "1.7.0",
"version": "2.3.0",
"repository": {
"type": "git",
"url": "https://github.com/facebook/react.git",

View File

@@ -54,6 +54,41 @@ function isComponentName(node) {
}
}
function isReactFunction(node, functionName) {
return (
node.name === functionName ||
(node.type === 'MemberExpression' &&
node.object.name === 'React' &&
node.property.name === functionName)
);
}
/**
* Checks if the node is a callback argument of forwardRef. This render function
* should follow the rules of hooks.
*/
function isForwardRefCallback(node) {
return !!(
node.parent &&
node.parent.callee &&
isReactFunction(node.parent.callee, 'forwardRef')
);
}
/**
* Checks if the node is a callback argument of React.memo. This anonymous
* functional component should follow the rules of hooks.
*/
function isMemoCallback(node) {
return !!(
node.parent &&
node.parent.callee &&
isReactFunction(node.parent.callee, 'memo')
);
}
function isInsideComponentOrHook(node) {
while (node) {
const functionName = getFunctionName(node);
@@ -62,6 +97,9 @@ function isInsideComponentOrHook(node) {
return true;
}
}
if (isForwardRefCallback(node) || isMemoCallback(node)) {
return true;
}
node = node.parent;
}
return false;
@@ -290,7 +328,8 @@ export default {
// `undefined` then we know either that we have an anonymous function
// expression or our code path is not in a function. In both cases we
// will want to error since neither are React function components or
// hook functions.
// hook functions - unless it is an anonymous function argument to
// forwardRef or memo.
const codePathFunctionName = getFunctionName(codePathNode);
// This is a valid code path for React hooks if we are directly in a React
@@ -301,7 +340,7 @@ export default {
const isDirectlyInsideComponentOrHook = codePathFunctionName
? isComponentName(codePathFunctionName) ||
isHook(codePathFunctionName)
: false;
: isForwardRefCallback(codePathNode) || isMemoCallback(codePathNode);
// Compute the earliest finalizer level using information from the
// cache. We expect all reachable final segments to have a cache entry
@@ -428,7 +467,7 @@ export default {
const message =
`React Hook "${context.getSource(hook)}" is called in ` +
`function "${context.getSource(codePathFunctionName)}" ` +
'which is neither a React function component or a custom ' +
'that is neither a React function component nor a custom ' +
'React Hook function.';
context.report({node: hook, message});
} else if (codePathNode.type === 'Program') {

View File

@@ -19,7 +19,7 @@
},
"homepage": "https://reactjs.org/",
"peerDependencies": {
"jest": "^23.0.1",
"jest": "^23.0.1 || ^24.0.0",
"scheduler": "^0.15.0"
},
"files": [

View File

@@ -1,6 +1,6 @@
{
"name": "jest-react",
"version": "0.7.0",
"version": "0.10.0",
"description": "Jest matchers and utilities for testing React components.",
"main": "index.js",
"repository": {
@@ -19,7 +19,7 @@
},
"homepage": "https://reactjs.org/",
"peerDependencies": {
"jest": "^23.0.1",
"jest": "^23.0.1 || ^24.0.0",
"react": "^16.0.0",
"react-test-renderer": "^16.0.0"
},

View File

@@ -22,6 +22,7 @@ import type {ReactSyntheticEvent} from './ReactSyntheticEventType';
import type {Fiber} from 'react-reconciler/src/ReactFiber';
import type {AnyNativeEvent} from './PluginModuleType';
import type {TopLevelType} from './TopLevelEventTypes';
import type {EventSystemFlags} from 'legacy-events/EventSystemFlags';
function isInteractive(tag) {
return (
@@ -133,7 +134,8 @@ function extractPluginEvents(
topLevelType: TopLevelType,
targetInst: null | Fiber,
nativeEvent: AnyNativeEvent,
nativeEventTarget: EventTarget,
nativeEventTarget: null | EventTarget,
eventSystemFlags: EventSystemFlags,
): Array<ReactSyntheticEvent> | ReactSyntheticEvent | null {
let events = null;
for (let i = 0; i < plugins.length; i++) {
@@ -145,6 +147,7 @@ function extractPluginEvents(
targetInst,
nativeEvent,
nativeEventTarget,
eventSystemFlags,
);
if (extractedEvents) {
events = accumulateInto(events, extractedEvents);
@@ -158,13 +161,15 @@ export function runExtractedPluginEventsInBatch(
topLevelType: TopLevelType,
targetInst: null | Fiber,
nativeEvent: AnyNativeEvent,
nativeEventTarget: EventTarget,
nativeEventTarget: null | EventTarget,
eventSystemFlags: EventSystemFlags,
) {
const events = extractPluginEvents(
topLevelType,
targetInst,
nativeEvent,
nativeEventTarget,
eventSystemFlags,
);
runEventsInBatch(events);
}

View File

@@ -14,3 +14,4 @@ export const RESPONDER_EVENT_SYSTEM = 1 << 1;
export const IS_PASSIVE = 1 << 2;
export const IS_ACTIVE = 1 << 3;
export const PASSIVE_NOT_SUPPORTED = 1 << 4;
export const IS_REPLAYED = 1 << 5;

View File

@@ -13,6 +13,7 @@ import type {
ReactSyntheticEvent,
} from './ReactSyntheticEventType';
import type {TopLevelType} from './TopLevelEventTypes';
import type {EventSystemFlags} from 'legacy-events/EventSystemFlags';
export type EventTypes = {[key: string]: DispatchConfig};
@@ -26,7 +27,8 @@ export type PluginModule<NativeEvent> = {
topLevelType: TopLevelType,
targetInst: null | Fiber,
nativeTarget: NativeEvent,
nativeEventTarget: EventTarget,
nativeEventTarget: null | EventTarget,
eventSystemFlags: EventSystemFlags,
) => ?ReactSyntheticEvent,
tapMoveThreshold?: number,
};

View File

@@ -9,8 +9,8 @@ import {
needsStateRestore,
restoreStateIfNeeded,
} from './ReactControlledComponent';
import {enableFlareAPI} from 'shared/ReactFeatureFlags';
import {enableFlareAPI} from 'shared/ReactFeatureFlags';
import {invokeGuardedCallbackAndCatchFirstError} from 'shared/ReactErrorUtils';
// Used as a way to call batchedUpdates when we don't have a reference to
@@ -77,7 +77,8 @@ export function batchedEventUpdates(fn, a, b) {
}
}
export function executeUserEventHandler(fn: any => void, value: any) {
// This is for the React Flare event system
export function executeUserEventHandler(fn: any => void, value: any): void {
const previouslyInEventHandler = isInsideEventHandler;
try {
isInsideEventHandler = true;

View File

@@ -507,6 +507,7 @@ const ResponderEventPlugin = {
targetInst,
nativeEvent,
nativeEventTarget,
eventSystemFlags,
) {
if (isStartish(topLevelType)) {
trackedTouchCount += 1;
@@ -514,7 +515,7 @@ const ResponderEventPlugin = {
if (trackedTouchCount >= 0) {
trackedTouchCount -= 1;
} else {
console.error(
console.warn(
'Ended a touch event which was not counted in `trackedTouchCount`.',
);
return null;

View File

@@ -284,16 +284,18 @@ function getPooledWarningPropertyDefinition(propName, getVal) {
function warn(action, result) {
const warningCondition = false;
warningWithoutStack(
warningCondition,
"This synthetic event is reused for performance reasons. If you're seeing this, " +
"you're %s `%s` on a released/nullified synthetic event. %s. " +
'If you must keep the original synthetic event around, use event.persist(). ' +
'See https://fb.me/react-event-pooling for more information.',
action,
propName,
result,
);
if (__DEV__) {
warningWithoutStack(
warningCondition,
"This synthetic event is reused for performance reasons. If you're seeing this, " +
"you're %s `%s` on a released/nullified synthetic event. %s. " +
'If you must keep the original synthetic event around, use event.persist(). ' +
'See https://fb.me/react-event-pooling for more information.',
action,
propName,
result,
);
}
}
}

View File

@@ -10,6 +10,7 @@
'use strict';
const {HostComponent} = require('shared/ReactWorkTags');
const {PLUGIN_EVENT_SYSTEM} = require('legacy-events/EventSystemFlags');
let EventBatching;
let EventPluginUtils;
@@ -316,6 +317,7 @@ const run = function(config, hierarchyConfig, nativeEventConfig) {
nativeEventConfig.targetInst,
nativeEventConfig.nativeEvent,
nativeEventConfig.target,
PLUGIN_EVENT_SYSTEM,
);
// At this point the negotiation events have been dispatched as part of the

View File

@@ -1,7 +1,7 @@
{
"name": "react-art",
"description": "React ART is a JavaScript library for drawing vector graphics using React. It provides declarative and reactive bindings to the ART library. Using the same declarative API you can render the output to either Canvas, SVG or VML (IE8).",
"version": "16.9.0",
"version": "16.12.0",
"main": "index.js",
"repository": {
"type": "git",
@@ -27,7 +27,7 @@
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1",
"prop-types": "^15.6.2",
"scheduler": "^0.15.0"
"scheduler": "^0.18.0"
},
"peerDependencies": {
"react": "^16.0.0"

View File

@@ -432,7 +432,6 @@ export function mountResponderInstance(
props: Object,
state: Object,
instance: Object,
rootContainerInstance: Object,
) {
throw new Error('Not yet implemented.');
}
@@ -462,3 +461,11 @@ export function updateFundamentalComponent(fundamentalInstance) {
export function unmountFundamentalComponent(fundamentalInstance) {
throw new Error('Not yet implemented.');
}
export function getInstanceFromNode(node) {
throw new Error('Not yet implemented.');
}
export function beforeRemoveInstance(instance) {
// noop
}

View File

@@ -14,8 +14,9 @@ import type {
ReactEventResponderListener,
} from 'shared/ReactTypes';
import type {Fiber} from 'react-reconciler/src/ReactFiber';
import type {Hook} from 'react-reconciler/src/ReactFiberHooks';
import type {Hook, TimeoutConfig} from 'react-reconciler/src/ReactFiberHooks';
import type {Dispatcher as DispatcherType} from 'react-reconciler/src/ReactFiberHooks';
import type {SuspenseConfig} from 'react-reconciler/src/ReactFiberSuspenseConfig';
import ErrorStackParser from 'error-stack-parser';
import ReactSharedInternals from 'shared/ReactSharedInternals';
@@ -236,6 +237,28 @@ function useResponder(
};
}
function useTransition(
config: SuspenseConfig | null | void,
): [(() => void) => void, boolean] {
nextHook();
hookLog.push({
primitive: 'Transition',
stackError: new Error(),
value: config,
});
return [callback => {}, false];
}
function useDeferredValue<T>(value: T, config: TimeoutConfig | null | void): T {
nextHook();
hookLog.push({
primitive: 'DeferredValue',
stackError: new Error(),
value,
});
return value;
}
const Dispatcher: DispatcherType = {
readContext,
useCallback,
@@ -249,18 +272,20 @@ const Dispatcher: DispatcherType = {
useRef,
useState,
useResponder,
useTransition,
useDeferredValue,
};
// Inspect
type HooksNode = {
export type HooksNode = {
id: number | null,
isStateEditable: boolean,
name: string,
value: mixed,
subHooks: Array<HooksNode>,
};
type HooksTree = Array<HooksNode>;
export type HooksTree = Array<HooksNode>;
// Don't assume
//

View File

@@ -180,7 +180,7 @@ describe('React hooks DevTools integration', () => {
}
});
it('should support overriding suspense in sync mode', () => {
it('should support overriding suspense in legacy mode', () => {
if (__DEV__) {
// Lock the first render
setSuspenseHandler(() => true);

View File

@@ -29,7 +29,7 @@ describe('ReactHooksInspection', () => {
const listener = React.unstable_useResponder(TestResponder, {
preventDefault: false,
});
return <div listeners={listener}>Hello world</div>;
return <div DEPRECATED_flareListeners={listener}>Hello world</div>;
}
let tree = ReactDebugTools.inspectHooks(Foo, {});
expect(tree).toEqual([

View File

@@ -12,20 +12,17 @@ This is similar requiring the `react-devtools` package, but provides several con
```js
const { connectToDevTools } = require("react-devtools-core");
connectToDevTools({
// Config options
});
connectToDevTools(config);
```
Run `connectToDevTools()` in the same context as React to set up a connection to DevTools.
Be sure to run this function *before* importing e.g. `react`, `react-dom`, `react-native`.
The `options` object may contain:
The `config` object may contain:
* `host: string` (defaults to "localhost") - Websocket will connect to this host.
* `port: number` (defaults to `8097`) - Websocket will connect to this port.
* `websocket: Websocket` - Custom websocked to use. Overrides `host` and `port` settings if provided.
* `resolveNativeStyle: (style: number) => ?Object` - Used by the React Native style plug-in.
* `resolveRNStyle: (style: number) => ?Object` - Used by the React Native style plug-in.
* `isAppActive: () => boolean` - If provided, DevTools will poll this method and wait until it returns true before connecting to React.
## `react-devtools-core/standalone`
@@ -41,4 +38,16 @@ require("react-devtools-core/standalone")
.startServer(port);
```
Reference the `react-devtools` package for a complete integration example.
Reference the `react-devtools` package for a complete integration example.
## Development
Watch for changes made to the backend entry point and rebuild:
```sh
yarn start:backend
```
Watch for changes made to the standalone UI entry point and rebuild:
```sh
yarn start:standalone
```

View File

@@ -0,0 +1 @@
module.exports = require('./dist/backend');

View File

@@ -1,5 +1,34 @@
{
"private": true,
"name": "react-devtools-core",
"version": "0.0.0"
"version": "4.2.1",
"description": "Use react-devtools outside of the browser",
"license": "MIT",
"main": "./dist/backend.js",
"repository": {
"type": "git",
"url": "https://github.com/facebook/react.git",
"directory": "packages/react-devtools-core"
},
"files": [
"dist",
"backend.js",
"build-info.json",
"standalone.js"
],
"scripts": {
"build": "yarn build:backend && yarn build:standalone",
"build:backend": "cross-env NODE_ENV=production webpack --config webpack.backend.js",
"build:standalone": "cross-env NODE_ENV=production webpack --config webpack.standalone.js",
"prepublish": "yarn run build",
"start:backend": "cross-env NODE_ENV=development webpack --config webpack.backend.js --watch",
"start:standalone": "cross-env NODE_ENV=development webpack --config webpack.standalone.js --watch"
},
"dependencies": {
"es6-symbol": "^3",
"shell-quote": "^1.6.1",
"ws": "^7"
},
"devDependencies": {
"cross-env": "^3.1.4"
}
}

View File

@@ -0,0 +1,284 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
import Agent from 'react-devtools-shared/src/backend/agent';
import Bridge from 'react-devtools-shared/src/bridge';
import {installHook} from 'react-devtools-shared/src/hook';
import {initBackend} from 'react-devtools-shared/src/backend';
import {__DEBUG__} from 'react-devtools-shared/src/constants';
import setupNativeStyleEditor from 'react-devtools-shared/src/backend/NativeStyleEditor/setupNativeStyleEditor';
import {getDefaultComponentFilters} from 'react-devtools-shared/src/utils';
import type {BackendBridge} from 'react-devtools-shared/src/bridge';
import type {ComponentFilter} from 'react-devtools-shared/src/types';
import type {DevToolsHook} from 'react-devtools-shared/src/backend/types';
import type {ResolveNativeStyle} from 'react-devtools-shared/src/backend/NativeStyleEditor/setupNativeStyleEditor';
type ConnectOptions = {
host?: string,
nativeStyleEditorValidAttributes?: $ReadOnlyArray<string>,
port?: number,
resolveRNStyle?: ResolveNativeStyle,
isAppActive?: () => boolean,
websocket?: ?WebSocket,
};
installHook(window);
const hook: DevToolsHook = window.__REACT_DEVTOOLS_GLOBAL_HOOK__;
let savedComponentFilters: Array<
ComponentFilter,
> = getDefaultComponentFilters();
function debug(methodName: string, ...args) {
if (__DEBUG__) {
console.log(
`%c[core/backend] %c${methodName}`,
'color: teal; font-weight: bold;',
'font-weight: bold;',
...args,
);
}
}
export function connectToDevTools(options: ?ConnectOptions) {
const {
host = 'localhost',
nativeStyleEditorValidAttributes,
port = 8097,
websocket,
resolveRNStyle = null,
isAppActive = () => true,
} =
options || {};
let retryTimeoutID: TimeoutID | null = null;
function scheduleRetry() {
if (retryTimeoutID === null) {
// Two seconds because RN had issues with quick retries.
retryTimeoutID = setTimeout(() => connectToDevTools(options), 2000);
}
}
if (!isAppActive()) {
// If the app is in background, maybe retry later.
// Don't actually attempt to connect until we're in foreground.
scheduleRetry();
return;
}
let bridge: BackendBridge | null = null;
const messageListeners = [];
const uri = 'ws://' + host + ':' + port;
// If existing websocket is passed, use it.
// This is necessary to support our custom integrations.
// See D6251744.
const ws = websocket ? websocket : new window.WebSocket(uri);
ws.onclose = handleClose;
ws.onerror = handleFailed;
ws.onmessage = handleMessage;
ws.onopen = function() {
bridge = new Bridge({
listen(fn) {
messageListeners.push(fn);
return () => {
const index = messageListeners.indexOf(fn);
if (index >= 0) {
messageListeners.splice(index, 1);
}
};
},
send(event: string, payload: any, transferable?: Array<any>) {
if (ws.readyState === ws.OPEN) {
if (__DEBUG__) {
debug('wall.send()', event, payload);
}
ws.send(JSON.stringify({event, payload}));
} else {
if (__DEBUG__) {
debug(
'wall.send()',
'Shutting down bridge because of closed WebSocket connection',
);
}
if (bridge !== null) {
bridge.shutdown();
}
scheduleRetry();
}
},
});
bridge.addListener(
'inspectElement',
({id, rendererID}: {id: number, rendererID: number}) => {
const renderer = agent.rendererInterfaces[rendererID];
if (renderer != null) {
// Send event for RN to highlight.
const nodes: ?Array<HTMLElement> = renderer.findNativeNodesForFiberID(
id,
);
if (nodes != null && nodes[0] != null) {
agent.emit('showNativeHighlight', nodes[0]);
}
}
},
);
bridge.addListener(
'updateComponentFilters',
(componentFilters: Array<ComponentFilter>) => {
// Save filter changes in memory, in case DevTools is reloaded.
// In that case, the renderer will already be using the updated values.
// We'll lose these in between backend reloads but that can't be helped.
savedComponentFilters = componentFilters;
},
);
// The renderer interface doesn't read saved component filters directly,
// because they are generally stored in localStorage within the context of the extension.
// Because of this it relies on the extension to pass filters.
// In the case of the standalone DevTools being used with a website,
// saved filters are injected along with the backend script tag so we shouldn't override them here.
// This injection strategy doesn't work for React Native though.
// Ideally the backend would save the filters itself, but RN doesn't provide a sync storage solution.
// So for now we just fall back to using the default filters...
if (window.__REACT_DEVTOOLS_COMPONENT_FILTERS__ == null) {
bridge.send('overrideComponentFilters', savedComponentFilters);
}
// TODO (npm-packages) Warn if "isBackendStorageAPISupported"
const agent = new Agent(bridge);
agent.addListener('shutdown', () => {
// If we received 'shutdown' from `agent`, we assume the `bridge` is already shutting down,
// and that caused the 'shutdown' event on the `agent`, so we don't need to call `bridge.shutdown()` here.
hook.emit('shutdown');
});
initBackend(hook, agent, window);
// Setup React Native style editor if the environment supports it.
if (resolveRNStyle != null || hook.resolveRNStyle != null) {
setupNativeStyleEditor(
bridge,
agent,
((resolveRNStyle || hook.resolveRNStyle: any): ResolveNativeStyle),
nativeStyleEditorValidAttributes ||
hook.nativeStyleEditorValidAttributes ||
null,
);
} else {
// Otherwise listen to detect if the environment later supports it.
// For example, Flipper does not eagerly inject these values.
// Instead it relies on the React Native Inspector to lazily inject them.
let lazyResolveRNStyle;
let lazyNativeStyleEditorValidAttributes;
const initAfterTick = () => {
if (bridge !== null) {
setupNativeStyleEditor(
bridge,
agent,
lazyResolveRNStyle,
lazyNativeStyleEditorValidAttributes,
);
}
};
if (!hook.hasOwnProperty('resolveRNStyle')) {
Object.defineProperty(
hook,
'resolveRNStyle',
({
enumerable: false,
get() {
return lazyResolveRNStyle;
},
set(value) {
lazyResolveRNStyle = value;
initAfterTick();
},
}: Object),
);
}
if (!hook.hasOwnProperty('nativeStyleEditorValidAttributes')) {
Object.defineProperty(
hook,
'nativeStyleEditorValidAttributes',
({
enumerable: false,
get() {
return lazyNativeStyleEditorValidAttributes;
},
set(value) {
lazyNativeStyleEditorValidAttributes = value;
initAfterTick();
},
}: Object),
);
}
}
};
function handleClose() {
if (__DEBUG__) {
debug('WebSocket.onclose');
}
if (bridge !== null) {
bridge.emit('shutdown');
}
scheduleRetry();
}
function handleFailed() {
if (__DEBUG__) {
debug('WebSocket.onerror');
}
scheduleRetry();
}
function handleMessage(event) {
let data;
try {
if (typeof event.data === 'string') {
data = JSON.parse(event.data);
if (__DEBUG__) {
debug('WebSocket.onmessage', data);
}
} else {
throw Error();
}
} catch (e) {
console.error(
'[React DevTools] Failed to parse JSON: ' + (event.data: any),
);
return;
}
messageListeners.forEach(fn => {
try {
fn(data);
} catch (error) {
// jsc doesn't play so well with tracebacks that go into eval'd code,
// so the stack trace here will stop at the `eval()` call. Getting the
// message that caused the error is the best we can do for now.
console.log('[React DevTools] Error calling listener', data);
console.log('error:', error);
throw error;
}
});
}
}

View File

@@ -0,0 +1,190 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
import {existsSync} from 'fs';
import {basename, join, isAbsolute} from 'path';
import {execSync, spawn} from 'child_process';
import {parse} from 'shell-quote';
function isTerminalEditor(editor: string): boolean {
switch (editor) {
case 'vim':
case 'emacs':
case 'nano':
return true;
default:
return false;
}
}
// Map from full process name to binary that starts the process
// We can't just re-use full process name, because it will spawn a new instance
// of the app every time
const COMMON_EDITORS = {
'/Applications/Atom.app/Contents/MacOS/Atom': 'atom',
'/Applications/Atom Beta.app/Contents/MacOS/Atom Beta':
'/Applications/Atom Beta.app/Contents/MacOS/Atom Beta',
'/Applications/Sublime Text.app/Contents/MacOS/Sublime Text':
'/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl',
'/Applications/Sublime Text 2.app/Contents/MacOS/Sublime Text 2':
'/Applications/Sublime Text 2.app/Contents/SharedSupport/bin/subl',
'/Applications/Visual Studio Code.app/Contents/MacOS/Electron': 'code',
};
function getArgumentsForLineNumber(
editor: string,
filePath: string,
lineNumber: number,
): Array<string> {
switch (basename(editor)) {
case 'vim':
case 'mvim':
return [filePath, '+' + lineNumber];
case 'atom':
case 'Atom':
case 'Atom Beta':
case 'subl':
case 'sublime':
case 'wstorm':
case 'appcode':
case 'charm':
case 'idea':
return [filePath + ':' + lineNumber];
case 'joe':
case 'emacs':
case 'emacsclient':
return ['+' + lineNumber, filePath];
case 'rmate':
case 'mate':
case 'mine':
return ['--line', lineNumber + '', filePath];
case 'code':
return ['-g', filePath + ':' + lineNumber];
default:
// For all others, drop the lineNumber until we have
// a mapping above, since providing the lineNumber incorrectly
// can result in errors or confusing behavior.
return [filePath];
}
}
function guessEditor(): Array<string> {
// Explicit config always wins
if (process.env.REACT_EDITOR) {
return parse(process.env.REACT_EDITOR);
}
// Using `ps x` on OSX we can find out which editor is currently running.
// Potentially we could use similar technique for Windows and Linux
if (process.platform === 'darwin') {
try {
const output = execSync('ps x').toString();
const processNames = Object.keys(COMMON_EDITORS);
for (let i = 0; i < processNames.length; i++) {
const processName = processNames[i];
if (output.indexOf(processName) !== -1) {
return [COMMON_EDITORS[processName]];
}
}
} catch (error) {
// Ignore...
}
}
// Last resort, use old skool env vars
if (process.env.VISUAL) {
return [process.env.VISUAL];
} else if (process.env.EDITOR) {
return [process.env.EDITOR];
}
return [];
}
let childProcess = null;
export function getValidFilePath(
maybeRelativePath: string,
absoluteProjectRoots: Array<string>,
): string | null {
// We use relative paths at Facebook with deterministic builds.
// This is why our internal tooling calls React DevTools with absoluteProjectRoots.
// If the filename is absolute then we don't need to care about this.
if (isAbsolute(maybeRelativePath)) {
if (existsSync(maybeRelativePath)) {
return maybeRelativePath;
}
} else {
for (let i = 0; i < absoluteProjectRoots.length; i++) {
const projectRoot = absoluteProjectRoots[i];
const joinedPath = join(projectRoot, maybeRelativePath);
if (existsSync(joinedPath)) {
return joinedPath;
}
}
}
return null;
}
export function doesFilePathExist(
maybeRelativePath: string,
absoluteProjectRoots: Array<string>,
): boolean {
return getValidFilePath(maybeRelativePath, absoluteProjectRoots) !== null;
}
export function launchEditor(
maybeRelativePath: string,
lineNumber: number,
absoluteProjectRoots: Array<string>,
) {
const filePath = getValidFilePath(maybeRelativePath, absoluteProjectRoots);
if (filePath === null) {
return;
}
// Sanitize lineNumber to prevent malicious use on win32
// via: https://github.com/nodejs/node/blob/c3bb4b1aa5e907d489619fb43d233c3336bfc03d/lib/child_process.js#L333
if (lineNumber && isNaN(lineNumber)) {
return;
}
let [editor, ...args] = guessEditor();
if (!editor) {
return;
}
if (lineNumber) {
args = args.concat(getArgumentsForLineNumber(editor, filePath, lineNumber));
} else {
args.push(filePath);
}
if (childProcess && isTerminalEditor(editor)) {
// There's an existing editor process already and it's attached
// to the terminal, so go kill it. Otherwise two separate editor
// instances attach to the stdin/stdout which gets confusing.
childProcess.kill('SIGKILL');
}
if (process.platform === 'win32') {
// On Windows, launch the editor in a shell because spawn can only
// launch .exe files.
childProcess = spawn('cmd.exe', ['/C', editor].concat(args), {
stdio: 'inherit',
});
} else {
childProcess = spawn(editor, args, {stdio: 'inherit'});
}
childProcess.on('error', function() {});
childProcess.on('exit', function(errorCode) {
childProcess = null;
});
}

View File

@@ -0,0 +1,332 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
import {createElement} from 'react';
import {
// $FlowFixMe Flow does not yet know about flushSync()
flushSync,
// $FlowFixMe Flow does not yet know about createRoot()
createRoot,
} from 'react-dom';
import Bridge from 'react-devtools-shared/src/bridge';
import Store from 'react-devtools-shared/src/devtools/store';
import {
getSavedComponentFilters,
getAppendComponentStack,
} from 'react-devtools-shared/src/utils';
import {Server} from 'ws';
import {join} from 'path';
import {readFileSync} from 'fs';
import {installHook} from 'react-devtools-shared/src/hook';
import DevTools from 'react-devtools-shared/src/devtools/views/DevTools';
import {doesFilePathExist, launchEditor} from './editor';
import {__DEBUG__} from 'react-devtools-shared/src/constants';
import type {FrontendBridge} from 'react-devtools-shared/src/bridge';
import type {InspectedElement} from 'react-devtools-shared/src/devtools/views/Components/types';
installHook(window);
export type StatusListener = (message: string) => void;
let node: HTMLElement = ((null: any): HTMLElement);
let nodeWaitingToConnectHTML: string = '';
let projectRoots: Array<string> = [];
let statusListener: StatusListener = (message: string) => {};
function setContentDOMNode(value: HTMLElement) {
node = value;
// Save so we can restore the exact waiting message between sessions.
nodeWaitingToConnectHTML = node.innerHTML;
return DevtoolsUI;
}
function setProjectRoots(value: Array<string>) {
projectRoots = value;
}
function setStatusListener(value: StatusListener) {
statusListener = value;
return DevtoolsUI;
}
let bridge: FrontendBridge | null = null;
let store: Store | null = null;
let root = null;
const log = (...args) => console.log('[React DevTools]', ...args);
log.warn = (...args) => console.warn('[React DevTools]', ...args);
log.error = (...args) => console.error('[React DevTools]', ...args);
function debug(methodName: string, ...args) {
if (__DEBUG__) {
console.log(
`%c[core/standalone] %c${methodName}`,
'color: teal; font-weight: bold;',
'font-weight: bold;',
...args,
);
}
}
function safeUnmount() {
flushSync(() => {
if (root !== null) {
root.unmount();
}
});
root = null;
}
function reload() {
safeUnmount();
node.innerHTML = '';
setTimeout(() => {
root = createRoot(node);
root.render(
createElement(DevTools, {
bridge: ((bridge: any): FrontendBridge),
canViewElementSourceFunction,
showTabBar: true,
store: ((store: any): Store),
warnIfLegacyBackendDetected: true,
viewElementSourceFunction,
}),
);
}, 100);
}
function canViewElementSourceFunction(
inspectedElement: InspectedElement,
): boolean {
if (
inspectedElement.canViewSource === false ||
inspectedElement.source === null
) {
return false;
}
const {source} = inspectedElement;
return doesFilePathExist(source.fileName, projectRoots);
}
function viewElementSourceFunction(
id: number,
inspectedElement: InspectedElement,
): void {
const {source} = inspectedElement;
if (source !== null) {
launchEditor(source.fileName, source.lineNumber, projectRoots);
} else {
log.error('Cannot inspect element', id);
}
}
function onDisconnected() {
safeUnmount();
node.innerHTML = nodeWaitingToConnectHTML;
}
function onError({code, message}) {
safeUnmount();
if (code === 'EADDRINUSE') {
node.innerHTML = `
<div class="box">
<div class="box-header">
Another instance of DevTools is running.
</div>
<div class="box-content">
Only one copy of DevTools can be used at a time.
</div>
</div>
`;
} else {
node.innerHTML = `
<div class="box">
<div class="box-header">
Unknown error
</div>
<div class="box-content">
${message}
</div>
</div>
`;
}
}
function initialize(socket: WebSocket) {
const listeners = [];
socket.onmessage = event => {
let data;
try {
if (typeof event.data === 'string') {
data = JSON.parse(event.data);
if (__DEBUG__) {
debug('WebSocket.onmessage', data);
}
} else {
throw Error();
}
} catch (e) {
log.error('Failed to parse JSON', event.data);
return;
}
listeners.forEach(fn => {
try {
fn(data);
} catch (error) {
log.error('Error calling listener', data);
throw error;
}
});
};
bridge = new Bridge({
listen(fn) {
listeners.push(fn);
return () => {
const index = listeners.indexOf(fn);
if (index >= 0) {
listeners.splice(index, 1);
}
};
},
send(event: string, payload: any, transferable?: Array<any>) {
if (socket.readyState === socket.OPEN) {
socket.send(JSON.stringify({event, payload}));
}
},
});
((bridge: any): FrontendBridge).addListener('shutdown', () => {
socket.close();
});
store = new Store(bridge, {supportsNativeInspection: false});
log('Connected');
reload();
}
let startServerTimeoutID: TimeoutID | null = null;
function connectToSocket(socket: WebSocket) {
socket.onerror = err => {
onDisconnected();
log.error('Error with websocket connection', err);
};
socket.onclose = () => {
onDisconnected();
log('Connection to RN closed');
};
initialize(socket);
return {
close: function() {
onDisconnected();
},
};
}
function startServer(port?: number = 8097) {
const httpServer = require('http').createServer();
const server = new Server({server: httpServer});
let connected: WebSocket | null = null;
server.on('connection', (socket: WebSocket) => {
if (connected !== null) {
connected.close();
log.warn(
'Only one connection allowed at a time.',
'Closing the previous connection',
);
}
connected = socket;
socket.onerror = error => {
connected = null;
onDisconnected();
log.error('Error with websocket connection', error);
};
socket.onclose = () => {
connected = null;
onDisconnected();
log('Connection to RN closed');
};
initialize(socket);
});
server.on('error', event => {
onError(event);
log.error('Failed to start the DevTools server', event);
startServerTimeoutID = setTimeout(() => startServer(port), 1000);
});
httpServer.on('request', (request, response) => {
// Serve a file that immediately sets up the connection.
const backendFile = readFileSync(join(__dirname, 'backend.js'));
// The renderer interface doesn't read saved component filters directly,
// because they are generally stored in localStorage within the context of the extension.
// Because of this it relies on the extension to pass filters, so include them wth the response here.
// This will ensure that saved filters are shared across different web pages.
const savedPreferencesString = `
window.__REACT_DEVTOOLS_COMPONENT_FILTERS__ = ${JSON.stringify(
getSavedComponentFilters(),
)};
window.__REACT_DEVTOOLS_APPEND_COMPONENT_STACK__ = ${JSON.stringify(
getAppendComponentStack(),
)};`;
response.end(
savedPreferencesString +
'\n;' +
backendFile.toString() +
'\n;' +
'ReactDevToolsBackend.connectToDevTools();',
);
});
httpServer.on('error', event => {
onError(event);
statusListener('Failed to start the server.');
startServerTimeoutID = setTimeout(() => startServer(port), 1000);
});
httpServer.listen(port, () => {
statusListener('The server is listening on the port ' + port + '.');
});
return {
close: function() {
connected = null;
onDisconnected();
if (startServerTimeoutID !== null) {
clearTimeout(startServerTimeoutID);
}
server.close();
httpServer.close();
},
};
}
const DevtoolsUI = {
connectToSocket,
setContentDOMNode,
setProjectRoots,
setStatusListener,
startServer,
};
export default DevtoolsUI;

View File

@@ -0,0 +1 @@
module.exports = require('./dist/standalone');

View File

@@ -0,0 +1,66 @@
const {resolve} = require('path');
const {DefinePlugin} = require('webpack');
const {
GITHUB_URL,
getVersionString,
} = require('react-devtools-extensions/utils');
const NODE_ENV = process.env.NODE_ENV;
if (!NODE_ENV) {
console.error('NODE_ENV not set');
process.exit(1);
}
const builtModulesDir = resolve(__dirname, '..', '..', 'build', 'node_modules');
const __DEV__ = NODE_ENV === 'development';
const DEVTOOLS_VERSION = getVersionString();
module.exports = {
mode: __DEV__ ? 'development' : 'production',
devtool: __DEV__ ? 'cheap-module-eval-source-map' : false,
entry: {
backend: './src/backend.js',
},
output: {
path: __dirname + '/dist',
filename: '[name].js',
// This name is important; standalone references it in order to connect.
library: 'ReactDevToolsBackend',
libraryTarget: 'umd',
},
resolve: {
alias: {
react: resolve(builtModulesDir, 'react'),
'react-dom': resolve(builtModulesDir, 'react-dom'),
'react-debug-tools': resolve(builtModulesDir, 'react-debug-tools'),
'react-is': resolve(builtModulesDir, 'react-is'),
scheduler: resolve(builtModulesDir, 'scheduler'),
},
},
plugins: [
new DefinePlugin({
__DEV__: true,
'process.env.DEVTOOLS_VERSION': `"${DEVTOOLS_VERSION}"`,
'process.env.GITHUB_URL': `"${GITHUB_URL}"`,
}),
],
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
options: {
configFile: resolve(
__dirname,
'..',
'react-devtools-shared',
'babel.config.js',
),
},
},
],
},
};

View File

@@ -0,0 +1,92 @@
const {resolve} = require('path');
const {DefinePlugin} = require('webpack');
const {
GITHUB_URL,
getVersionString,
} = require('react-devtools-extensions/utils');
const NODE_ENV = process.env.NODE_ENV;
if (!NODE_ENV) {
console.error('NODE_ENV not set');
process.exit(1);
}
const builtModulesDir = resolve(__dirname, '..', '..', 'build', 'node_modules');
const __DEV__ = NODE_ENV === 'development';
const DEVTOOLS_VERSION = getVersionString();
module.exports = {
mode: __DEV__ ? 'development' : 'production',
devtool: __DEV__ ? 'cheap-module-eval-source-map' : false,
target: 'electron-main',
entry: {
standalone: './src/standalone.js',
},
output: {
path: __dirname + '/dist',
filename: '[name].js',
library: '[name]',
libraryTarget: 'commonjs2',
},
resolve: {
alias: {
react: resolve(builtModulesDir, 'react'),
'react-dom': resolve(builtModulesDir, 'react-dom'),
'react-debug-tools': resolve(builtModulesDir, 'react-debug-tools'),
'react-is': resolve(builtModulesDir, 'react-is'),
scheduler: resolve(builtModulesDir, 'scheduler'),
},
},
node: {
// Don't replace __dirname!
// This would break the standalone DevTools ability to load the backend.
// see https://github.com/facebook/react-devtools/issues/1269
__dirname: false,
},
plugins: [
new DefinePlugin({
__DEV__: false,
'process.env.DEVTOOLS_VERSION': `"${DEVTOOLS_VERSION}"`,
'process.env.GITHUB_URL': `"${GITHUB_URL}"`,
'process.env.NODE_ENV': `"${NODE_ENV}"`,
}),
],
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
options: {
configFile: resolve(
__dirname,
'..',
'react-devtools-shared',
'babel.config.js',
),
},
},
{
test: /\.css$/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
options: {
// WARNING It's important that we disable CSS source maps for production builds.
// This causes style-loader to insert styles via a <style> tag rather than URL.createObjectURL,
// which in turn avoids a nasty Electron/Chromium bug that breaks DevTools in Nuclide.
// (Calls to URL.createObjectURL seem to crash the webview process.)
sourceMap: __DEV__,
modules: true,
localIdentName: '[local]___[hash:base64:5]',
},
},
],
},
],
},
};

Some files were not shown because too many files have changed in this diff Show More