Commit Graph

57 Commits

Author SHA1 Message Date
Sophie Alpert
767f52237c
Use .slice() for all substring-ing (#26677)
- substr is Annex B
- substring silently flips its arguments if they're in the "wrong order", which is confusing
- slice is better than sliced bread (no pun intended) and also it works the same way on Arrays so there's less to remember

---

> I'd be down to just lint and enforce a single form just for the potential compression savings by using a repeated string.

_Originally posted by @sebmarkbage in https://github.com/facebook/react/pull/26663#discussion_r1170455401_
2023-04-19 14:26:01 -07:00
Mengdi Chen
451736b557
[DevTools][BE] move shared types & constants to consolidated locations (#26572)
## Summary

This pull request aims to improve the maintainability of the codebase by
consolidating types and constants that are shared between the backend
and frontend. This consolidation will allow us to maintain backwards
compatibility in the frontend in the future.

To achieve this, we have moved the shared types and constants to the
following blessed files:

- react-devtools-shared/src/constants
- react-devtools-shared/src/types
- react-devtools-shared/src/backend/types
- react-devtools-shared/src/backend/NativeStyleEditor/types

Please note that the inclusion of NativeStyleEditor in this list is
temporary, and we plan to remove it once we have a better plugin system
in place.

## How did you test this change?

I have tested it by running `yarn flow dom-node`, which reports no
errors.
2023-04-10 17:07:05 -04:00
Ruslan Lesiutin
b14f8da155
refactor[devtools]: forbid editing class instances in props (#26522)
## Summary
Fixes https://github.com/facebook/react/issues/24781

Restricting from editing props, which are class instances, because their
internals should be opaque.

Proposed changes:
1. Adding new data type `class_instance`: based on prototype chain of an
object we will check if its plain or not. If not, then will be marked as
`class_instance`. This should not affect `arrays`, ..., because we do
this in the end of an `object` case in `getDataType` function.

Important detail: this approach won't work for objects created with
`Object.create`, because of the custom prototype. This can also be
bypassed by manually deleting a prototype ¯\\\_(ツ)_/¯
I am not sure if there might be a better solution (which will cover all
cases) to detect if object is a class instance. Initially I was trying
to use `Object.getPrototypeOf(object) === Object.prototype`, but this
won't work for cases when we are dealing with `iframe`.


2. Objects with a type `class_instance` will be marked as unserializable
and read-only.

## Demo
`person` is a class instance, `object` is a plain object


https://user-images.githubusercontent.com/28902667/228914791-ebdc8ab0-eb5c-426d-8163-66d56b5e8790.mov
2023-04-03 11:32:17 +01:00
Jan Kassens
afea1d0c53
[flow] make Flow suppressions explicit on the error (#26487)
Added an explicit type to all $FlowFixMe suppressions to reduce
over-suppressions of new errors that might be caused on the same lines.

Also removes suppressions that aren't used (e.g. in a `@noflow` file as
they're purely misleading)

Test Plan:
yarn flow-ci
2023-03-27 13:43:04 +02:00
Jan Kassens
6ddcbd4f96
[flow] enable LTI inference mode (#26104)
This is the next generation inference mode for Flow.
2023-02-09 17:07:39 -05:00
Robert Balicki
fecc288b7d
[react devtools] Device storage support (#25452)
# Summary
* This PR adds support for persisting certain settings to device
storage, allowing e.g. RN apps to properly patch the console when
restarted.
* The device storage APIs have signature `getConsolePatchSettings()` and
`setConsolePatchSettings(string)`, in iOS, are thin wrappers around the
`Library/Settings` turbomodule, and wrap a new TM that uses the `SharedPreferences` class in Android.
* Pass device storage getters/setters from RN to DevTools'
`connectToDevtools`. The setters are then used to populate values on
`window`. Later, the console is patched using these values.
* If we receive a notification from DevTools that the console patching
fields have been updated, we write values back to local storage.
* See https://github.com/facebook/react-native/pull/34903

# How did you test this change?
Manual testing, `yarn run test-build-devtools`, `yarn run prettier`,
`yarn run flow dom`

## Manual testing setup:

### React DevTools Frontend
* Get the DevTools frontend in flipper:
* `nvm install -g react-devtools-core`, then replace that package with a
symlink to the local package
  * enable "use globally installed devtools" in flipper
* yarn run start in react-devtools, etc. as well

### React DevTools Backend
* `yarn run build:backend` in react-devtools-core, then copy-paste that
file to the expo app's node_modules directory

### React Native
* A local version of React Native can be patched in by modifying an expo
app's package.json, as in `"react-native":
"rbalicki2/react-native#branch-name"`

# Versioning safety
* There are three versioned modules to worry about: react native, the
devtools frontend and the devtools backend.
* The react devtools backend checks for whether a `cachedSettingsStore`
is passed from react native. If not (e.g. if React Native is outdated),
then no behavior changes.
* The devtools backend reads the patched console values from the cached
settings store. However, if nothing has been stored, for example because
the frontend is outdated or has never synced its settings, then behavior
doesn't change.
* The devtools frontend sends no new messages. However, if it did send a
new message (e.g. "store this value at this key"), and the backend was
outdated, that message would be silently ignored.
2022-10-25 13:25:33 +11:00
Andrew Clark
9cdf8a99ed
[Codemod] Update copyright header to Meta (#25315)
* Facebook -> Meta in copyright

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

* Manual tweaks
2022-10-18 11:19:24 -04:00
c0dedance
9fb581c7cc
Refactor: merge duplicate imports (#25489)
Co-authored-by: Jan Kassens <jan@kassens.net>
2022-10-16 21:58:58 -04:00
Jan Kassens
9f8a98a390 Flow upgrade to 0.153
- method unbinding is no longer supported in Flow for soundness, this added a bunch of suppressions
- Flow now prevents objects to be supertypes of interfaces/classes

ghstack-source-id: d7749cbad8
Pull Request resolved: https://github.com/facebook/react/pull/25412
2022-10-04 11:30:06 -04:00
Jan Kassens
adb58f529d Flow upgrade to 0.152
- 0.147 removes access to Object.prototype via the global object.
- 0.149 removed deprecated config options

ghstack-source-id: c77f9b3739
Pull Request resolved: https://github.com/facebook/react/pull/25411
2022-10-04 11:30:06 -04:00
Robert Balicki
540ba5b403
[react devtools][easy] Change variable names, etc. (#25211)
* Change variable names, put stuff in constants, etc. in preparation for next diff
2022-09-09 11:09:30 -04:00
Jan Kassens
a473d08fce
Update to Flow from 0.97 to 0.122 (#25204)
* flow 0.122
* update ReactModel type
2022-09-08 11:46:07 -04:00
Robert Balicki
7e5322ccf2
run prettier (#25164) 2022-08-31 14:20:01 -04:00
Robert Balicki
47867a772e
[react devtools][easy] Fix code highlighting in VSCode (#25155)
* Minor change that fixes code highlighting in VSCode in a particular file
2022-08-31 14:07:37 -04:00
Jan Kassens
a40ddf3124
Fix CI: run yarn prettier-all (#25163) 2022-08-31 18:50:04 +01:00
Robert Balicki
aa80a309b1
[react devtools][easy] Rename LOCAL_STORAGE_SHOULD_PATCH_CONSOLE_KEY to LOCAL_STORAGE_SHOULD_APPEND_COMPONENT_STACK_KEY (#25154)
* This more accurately describes what this constant does
2022-08-30 13:32:52 -04:00
Sebastian Silbermann
b66936ece7
devtools: Remove ForwardRef/Memo from display name if displayName is set (#21952)
* feat(devtools): Remove ForwardRef/Memo from display name if `displayName` is set

* Avoid potentially wasting work by inlining `functionName`
2022-07-25 09:02:12 +02:00
Luna Ruan
a6987bee73
add <TracingMarker> component boilerplate (#23275)
- Add Tracing Marker component type to React exports
- Add reconciler work tag
- Add devtools work tag
- Add boilerplate for the cache to render children

No functionality yet
2022-02-11 08:42:55 -08:00
Brian Vaughn
3b3daf5573
Advocate for StrictMode usage within Components tree (#22886)
Adds the concept of subtree modes to DevTools to bridge protocol as follows:
1. Add-root messages get two new attributes: one specifying whether the root is running in strict mode and another specifying whether the root (really the root's renderer) supports the concept of strict mode.
2. A new backend message type (TREE_OPERATION_SET_SUBTREE_MODE). This type specifies a subtree root (id) and a mode (bitmask). For now, the only mode this message deals with is strict mode.

The DevTools frontend has been updated as well to highlight non-StrictMode compliant components.

The changes to the bridge protocol require incrementing the bridge protocol version number, which will also require updating the version of react-devtools-core backend that is shipped with React Native.
2021-12-10 11:05:18 -05:00
EzzAk
255221c869
[DevTools] Add open in editor for fb (#22649)
Co-authored-by: Brian Vaughn <bvaughn@fb.com>
2021-11-03 11:27:30 -04:00
Behnam Mohammadi
580e2f56d5
Add isArray in devTools utils (#22438) 2021-09-27 17:17:30 -04:00
Brian Vaughn
2e41568313
DevTools encoding supports multibyte characters (e.g. "🟩") (#22424)
Changes our text encoding approach to properly support multibyte characters following this algorithm. Based on benchmarking, this new approach is roughly equivalent in terms of performance (sometimes slightly faster, sometimes slightly slower).

I also considered using TextEncoder/TextDecoder for this, but it was much slower (~85%).
2021-09-27 13:34:39 -04:00
Justin Grant
c88fb49d37
Improve DEV errors if string coercion throws (Temporal.*, Symbol, etc.) (#22064)
* Revise ESLint rules for string coercion

Currently, react uses `'' + value` to coerce mixed values to strings.
This code will throw for Temporal objects or symbols.

To make string-coercion safer and to improve user-facing error messages,
This commit adds a new ESLint rule called `safe-string-coercion`.

This rule has two modes: a production mode and a non-production mode.
* If the `isProductionUserAppCode` option is true, then `'' + value`
  coercions are allowed (because they're faster, although they may
  throw) and `String(value)` coercions are disallowed. Exception:
  when building error messages or running DEV-only code in prod
  files, `String()` should be used because it won't throw.
* If the `isProductionUserAppCode` option is false, then `'' + value`
  coercions are disallowed (because they may throw, and in non-prod
  code it's not worth the risk) and `String(value)` are allowed.

Production mode is used for all files which will be bundled with
developers' userland apps. Non-prod mode is used for all other React
code: tests, DEV blocks, devtools extension, etc.

In production mode, in addiiton to flagging `String(value)` calls,
the rule will also flag `'' + value` or `value + ''` coercions that may
throw. The rule is smart enough to silence itself in the following
"will never throw" cases:
* When the coercion is wrapped in a `typeof` test that restricts to safe
  (non-symbol, non-object) types. Example:
    if (typeof value === 'string' || typeof value === 'number') {
      thisWontReport('' + value);
    }
* When what's being coerced is a unary function result, because unary
   functions never return an object or a symbol.
* When the coerced value is a commonly-used numeric identifier:
  `i`, `idx`, or `lineNumber`.
* When the statement immeidately before the coercion is a DEV-only
  call to a function from shared/CheckStringCoercion.js. This call is a
  no-op in production, but in DEV it will show a console error
  explaining the problem, then will throw right after a long explanatory
  code comment so that debugger users will have an idea what's going on.
  The check function call must be in the following format:
    if (__DEV__) {
      checkXxxxxStringCoercion(value);
    };

Manually disabling the rule is usually not necessary because almost all
prod use of the `'' + value` pattern falls into one of the categories
above. But in the rare cases where the rule isn't smart enough to detect
safe usage (e.g. when a coercion is inside a nested ternary operator),
manually disabling the rule will be needed.

The rule should also be manually disabled in prod error handling code
where `String(value)` should be used for coercions, because it'd be
bad to throw while building an error message or stack trace!

The prod and non-prod modes have differentiated error messages to
explain how to do a proper coercion in that mode.

If a production check call is needed but is missing or incorrect
(e.g. not in a DEV block or not immediately before the coercion), then
a context-sensitive error message will be reported so that developers
can figure out what's wrong and how to fix the problem.

Because string coercions are now handled by the `safe-string-coercion`
rule, the `no-primitive-constructor` rule no longer flags `String()`
usage. It still flags `new String(value)` because that usage is almost
always a bug.

* Add DEV-only string coercion check functions

This commit adds DEV-only functions to check whether coercing
values to strings using the `'' + value` pattern will throw. If it will
throw, these functions will:
1. Display a console error with a friendly error message describing
   the problem and the developer can fix it.
2. Perform the coercion, which will throw. Right before the line where
   the throwing happens, there's a long code comment that will help
   debugger users (or others looking at the exception call stack) figure
   out what happened and how to fix the problem.

One of these check functions should be called before all string coercion
of user-provided values, except when the the coercion is guaranteed not
to throw, e.g.
* if inside a typeof check like `if (typeof value === 'string')`
* if coercing the result of a unary function like `+value` or `value++`
* if coercing a variable named in a whitelist of numeric identifiers:
  `i`, `idx`, or `lineNumber`.

The new `safe-string-coercion` internal ESLint rule enforces that
these check functions are called when they are required.

Only use these check functions in production code that will be bundled
with user apps.  For non-prod code (and for production error-handling
code), use `String(value)` instead which may be a little slower but will
never throw.

* Add failing tests for string coercion

Added failing tests to verify:
* That input, select, and textarea elements with value and defaultValue
  set to Temporal-like objects which will throw when coerced to string
  using the `'' + value` pattern.
* That text elements will throw for Temporal-like objects
* That dangerouslySetInnerHTML will *not* throw for Temporal-like
  objects because this value is not cast to a string before passing to
  the DOM.
* That keys that are Temporal-like objects will throw

All tests above validate the friendly error messages thrown.

* Use `String(value)` for coercion in non-prod files

This commit switches non-production code from `'' + value` (which
throws for Temporal objects and symbols) to instead use `String(value)`
which won't throw for these or other future plus-phobic types.

"Non-produciton code" includes anything not bundled into user apps:
* Tests and test utilities. Note that I didn't change legacy React
  test fixtures because I assumed it was good for those files to
  act just like old React, including coercion behavior.
* Build scripts
* Dev tools package - In addition to switching to `String`, I also
  removed special-case code for coercing symbols which is now
  unnecessary.

* Add DEV-only string coercion checks to prod files

This commit adds DEV-only function calls to to check if string coercion
using `'' + value` will throw, which it will if the value is a Temporal
object or a symbol because those types can't be added with `+`.

If it will throw, then in DEV these checks will show a console error
to help the user undertsand what went wrong and how to fix the
problem. After emitting the console error, the check functions will
retry the coercion which will throw with a call stack that's easy (or
at least easier!) to troubleshoot because the exception happens right
after a long comment explaining the issue. So whether the user is in
a debugger, looking at the browser console, or viewing the in-browser
DEV call stack, it should be easy to understand and fix the problem.

In most cases, the safe-string-coercion ESLint rule is smart enough to
detect when a coercion is safe. But in rare cases (e.g. when a coercion
is inside a ternary) this rule will have to be manually disabled.

This commit also switches error-handling code to use `String(value)`
for coercion, because it's bad to crash when you're trying to build
an error message or a call stack!  Because `String()` is usually
disallowed by the `safe-string-coercion` ESLint rule in production
code, the rule must be disabled when `String()` is used.
2021-09-27 10:05:07 -07:00
Brian Vaughn
f2fd1b80d5
Updated the utfDecodeString() method to avoid call stack exceeded error (#22330) 2021-09-17 09:52:52 -04:00
Luna Ruan
60a30cf32e
Console Logging for StrictMode Double Rendering (#22030)
React currently suppress console logs in StrictMode during double rendering. However, this causes a lot of confusion. This PR moves the console suppression logic from React into React Devtools. Now by default, we no longer suppress console logs. Instead, we gray out the logs in console during double render. We also add a setting in React Devtools to allow developers to hide console logs during double render if they choose.
2021-08-25 15:35:38 -07:00
Brian Vaughn
c5cfa71948
DevTools: Show hook names based on variable usage (#21641)
Co-authored-by: Brian Vaughn <brian.david.vaughn@gmail.com>
Co-authored-by: Saphal Patro <saphal1998@gmail.com>
Co-authored-by: VibhorCodecianGupta <vibhordelgupta@gmail.com>
2021-07-01 14:39:18 -04:00
Brian Vaughn
01be61c12f
DevTools can inspect Proxies that return broken iterator functions (#21660) 2021-06-11 10:15:48 -04:00
Brian Vaughn
4def1ceee2
Update DevTools Error strings to support GitHub fuzzy search (#21314) 2021-04-19 13:05:28 -04:00
ChenLei
ba9582da27
[devtools] Fix can't expand prop value in some scenario (#20534)
Co-authored-by: Brian Vaughn <bvaughn@fb.com>
2021-01-19 10:26:52 -05:00
Sebastian Silbermann
09a2c363a5
Expose DEV-mode warnings in devtools UI (#20463)
Co-authored-by: Brian Vaughn <bvaughn@fb.com>
2020-12-22 11:09:29 -05:00
Todor Totev
92c7e49895
Don't consumer iterators while inspecting (#19831)
Co-authored-by: Brian Vaughn <bvaughn@fb.com>
2020-09-22 14:23:20 -04:00
Brian Vaughn
50d9451f32
Improve DevTools editing interface (#19774)
* Improve DevTools editing interface

This commit adds the ability to rename or delete keys in the props/state/hooks/context editor and adds tests to cover this functionality. DevTools will degrade gracefully for older versions of React that do not inject the new reconciler rename* or delete* methods.

Specifically, this commit includes the following changes:
* Adds unit tests (for modern and legacy renderers) to cover overriding props, renaming keys, and deleting keys.
* Refactor backend override methods to reduce redundant Bridge/Agent listeners and methods.
* Inject new (DEV-only) methods from reconciler into DevTools to rename and delete paths.
* Refactor 'inspected element' UI components to improve readability.
* Improve auto-size input to better mimic Chrome's Style editor panel. (See this Code Sandbox for a proof of concept.)

It also contains the following code cleanup:
* Additional unit tests have been added for modifying values as well as renaming or deleting paths.
* Four new DEV-only methods have been added to the reconciler to be injected into the DevTools hook: overrideHookStateDeletePath, overrideHookStateRenamePath, overridePropsDeletePath, and overridePropsRenamePath. (DevTools will degrade gracefully for older renderers without these methods.)
* I also took this as an opportunity to refactor some of the existing code in a few places:
  * Rather than the backend implementing separate methods for editing props, state, hooks, and context– there are now three methods: deletePath, renamePath, and overrideValueAtPath that accept a type argument to differentiate between props, state, context, or hooks.
  * The various UI components for the DevTools frontend have been refactored to remove some unnecessary repetition.

This commit also adds temporary support for override* commands with mismatched backend/frontend versions:
* Add message forwarding for older backend methods (overrideContext, overrideHookState, overrideProps, and overrideState) to the new overrideValueAtPath method. This was done in both the frontend Bridge (for newer frontends passing messages to older embedded backends) and in the backend Agent (for older frontends passing messages to newer backends). We do this because React Native embeds the React DevTools backend, but cannot control which version of the frontend users use.
* Additional unit tests have been added as well to cover the older frontend to newer backend case. Our DevTools test infra does not make it easy to write tests for the other way around.
2020-09-18 11:07:18 -04:00
6h057
917cb01a58
React DevTools: Show symbols used as keys in state (#19786)
Co-authored-by: Brian Vaughn <bvaughn@fb.com>
2020-09-14 09:55:19 -04:00
Ben Pernick
60ba723bf7
Add SuspenseList to devTools (#19684)
* ensure getDisplayName is only called on functions

* add SuspenseList to Dev tools element names

* Add SuspenseList and pass tests

* Import SuspenseList directly

* run prettier

* Refactor tests to use real components

* run linter
2020-08-26 18:04:43 +01:00
6h057
49af88991c
Fix DevTools crash when inspecting document.all (#19619)
* Add html_all_collection type to correct typeof document.all

* process HTMLAllCollection like HTMLElement + fix flow issue

* fix lint

* move flow fix comment

* Make it work with iframes too

* optimize how we get html_all_collection type

* use once Object.prototype.toString.call
2020-08-21 14:31:16 +01:00
Pascal Fong Kye
b6e1d08604
DevTools bug fix: Proxied methods should be safely dehydrated for display 2020-08-12 12:15:53 -04:00
Dan Abramov
8eaf05e0e8
DevTools: Make break-on-warn off by default (#19309) 2020-07-10 14:11:32 +01:00
Brian Vaughn
2efe63d99c
DevTools: Add break-on-warn feature (#19048)
This commit adds a new tab to the Settings modal: Debugging

This new tab has the append component stacks feature and a new one: break on warn

This new feature adds a debugger statement into the console override
2020-05-29 14:34:43 -07:00
Nick Reiley
7c080902ef
[DevTools] Improve HOC search UX (#18802)
Co-authored-by: Brian Vaughn <brian.david.vaughn@gmail.com>
2020-05-15 10:37:34 -07:00
Sebastian Markbåge
3e94bce765
Enable prefer-const lint rules (#18451)
* Enable prefer-const rule

Stylistically I don't like this but Closure Compiler takes advantage of
this information.

* Auto-fix lints

* Manually fix the remaining callsites
2020-04-01 12:35:52 -07:00
Sebastian Markbåge
e2c6702fca
Remove ConcurrentMode and AsyncMode symbols (#18450)
This API was never released.
2020-04-01 10:18:52 -07:00
Brian Vaughn
d92631eab1
Remove "es6-symbol" package from DevTools (#18397) 2020-03-26 09:31:36 -07:00
Brian Vaughn
bc1f3e1a69
Fix DevTools Flow error for key-sort function (#17849) 2020-01-15 09:45:16 -08:00
Dawid Loranc
ff900095b9 Fix message typo in printOperationsArray function (#17039) 2020-01-09 14:13:03 -08:00
Brian Vaughn
2bb227ef80
DevTools: Improve function props display for inspected elements (#17789) 2020-01-06 09:19:59 -08:00
Brian Vaughn
7e2ab87a61
DevTools: Replaced unsafe hasOwnProperty() calls (#17768)
DevTools previously called  in several places with user-defined values. This could lead to runtime errors if those values had an overriden  attribute. This commit replaces those callse with  instead.

New test cases have been added.
2020-01-03 09:34:12 -08:00
Brian Vaughn
195b3db618
Added missing guard to DevTools for Objects with null proto (#17757)
This prevents a runtime error from occurring when these objects are inspected.
2020-01-02 08:27:29 -08:00
Brian Vaughn
f887d1aa27
[DevTools] Display RegExp values in props/state (#17690)
Previously, when props/state contained a regexp, it was shown as an
empty object. This commit adds regexps as values in need of special
rehydration (like Symbols or TypedArrays), and display them as a user
might expect.

Co-authored-by: Zirak <zirakertan@gmail.com>
2019-12-22 11:49:28 -08:00
Brian Vaughn
12c000412d
Improved inspected element props with inline previews (#17579)
* Improved inspected element props with inline previews

This mimics the inline preview shown by the brower console and dramatically improves the UX when inspecting deep values. I also updated tests to add more coverage for this new functionality.

* Cleaned up the DataView vs typed array check

* Added early bailouts to DevTools when generating preview strings for iterables/objects/arrays, to avoid doing unnecessary work
2019-12-11 17:52:17 -08: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