- 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_
## Summary
Removing `enableNamedHooksFeature`, `enableProfilerChangedHookIndices`,
`enableProfilerComponentTree` feature flags, they are the same for all
configurations.
Fixes https://github.com/facebook/react/issues/26500
## Summary
- No more using `clipboard-js` from the backend side, now emitting
custom `saveToClipboard` event, also adding corresponding listener in
`store.js`
- Not migrating to `navigator.clipboard` api yet, there were some issues
with using it on Chrome, will add more details to
https://github.com/facebook/react/pull/26539
## How did you test this change?
- Tested on Chrome, Firefox, Edge
- Tested on standalone electron app: seems like context menu is not
expected to work there (cannot right-click on value, the menu is not
appearing), other logic (pressing on copy icon) was not changed
## 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.
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
## Hoistables
In the original implementation of Float, all hoisted elements were
treated like Resources. They had deduplication semantics and hydrated
based on a key. This made certain kinds of hoists very challenging such
as sequences of meta tags for `og:image:...` metadata. The reason is
each tag along is not dedupable based on only it's intrinsic properties.
two identical tags may need to be included and hoisted together with
preceding meta tags that describe a semantic object with a linear set of
html nodes.
It was clear that the concept of Browser Resources (stylesheets /
scripts / preloads) did not extend universally to all hositable tags
(title, meta, other links, etc...)
Additionally while Resources benefit from deduping they suffer an
inability to update because while we may have multiple rendered elements
that refer to a single Resource it isn't unambiguous which element owns
the props on the underlying resource. We could try merging props, but
that is still really hard to reason about for authors. Instead we
restrict Resource semantics to freezing the props at the time the
Resource is first constructed and warn if you attempt to render the same
Resource with different props via another rendered element or by
updating an existing element for that Resource.
This lack of updating restriction is however way more extreme than
necessary for instances that get hoisted but otherwise do not dedupe;
where there is a well defined DOM instance for each rendered element. We
should be able to update props on these instances.
Hoistable is a generalization of what Float tries to model for hoisting.
Instead of assuming every hoistable element is a Resource we now have
two distinct categories, hoistable elements and hoistable resources. As
one might guess the former has semantics that match regular Host
Components except the placement of the node is usually in the <head>.
The latter continues to behave how the original implementation of
HostResource behaved with the first iteration of Float
### Hoistable Element
On the server hoistable elements render just like regular tags except
the output is stored in special queues that can be emitted in the stream
earlier than they otherwise would be if rendered in place. This also
allow for instance the ability to render a hoistable before even
rendering the <html> tag because the queues for hoistable elements won't
flush until after we have flushed the preamble (`<DOCTYPE
html><html><head>`).
On the client, hoistable elements largely operate like HostComponents.
The most notable difference is in the hydration strategy. If we are
hydrating and encounter a hoistable element we will look for all tags in
the document that could potentially be a match and we check whether the
attributes match the props for this particular instance. We also do this
in the commit phase rather than the render phase. The reason hydration
can be done for HostComponents in render is the instance will be removed
from the document if hydration fails so mutating it in render is safe.
For hoistables the nodes are not in a hydration boundary (Root or
SuspenseBoundary at time of writing) and thus if hydration fails and we
may have an instance marked as bound to some Fiber when that Fiber never
commits. Moving the hydration matching to commit ensures we will always
succeed in pairing the hoisted DOM instance with a Fiber that has
committed.
### Hoistable Resource
On the server and client the semantics of Resources are largely the same
they just don't apply to title, meta, and most link tags anymore.
Resources hoist and dedupe via an `href` key and are ref counted. In a
future update we will add a garbage collector so we can clean up
Resources that no longer have any references
## `<style>` support
In earlier implementations there was no support for <style> tags. This
PR adds support for treating `<style href="..."
precedence="...">...</style>` as a Resource analagous to `<link
rel="stylesheet" href="..." precedence="..." />`
It may seem odd at first to require an href to get Resource semantics
for a style tag. The rationale is that these are for inlining of actual
external stylesheets as an optimization and for URI like scoping of
inline styles for css-in-js libraries. The href indicates that the key
space for `<style>` and `<link rel="stylesheet" />` Resources is shared.
and the precedence is there to allow for interleaving of both kinds of
Style resources. This is an advanced feature that we do not expect most
app developers to use directly but will be quite handy for various
styling libraries and for folks who want to inline as much as possible
once Fizz supports this feature.
## refactor notes
* HostResource Fiber type is renamed HostHoistable to reflect the
generalization of the concept
* The Resource object representation is modified to reduce hidden class
checks and to use less memory overall
* The thing that distinguishes a resource from an element is whether the
Fiber has a memoizedState. If it does, it will use resource semantics,
otherwise element semantics
* The time complexity of matching hositable elements for hydration
should be improved
The old version of prettier we were using didn't support the Flow syntax
to access properties in a type using `SomeType['prop']`. This updates
`prettier` and `rollup-plugin-prettier` to the latest versions.
I added the prettier config `arrowParens: "avoid"` to reduce the diff
size as the default has changed in Prettier 2.0. The largest amount of
changes comes from function expressions now having a space. This doesn't
have an option to preserve the old behavior, so we have to update this.
This enables the "exact_empty_objects" setting for Flow which makes
empty objects exact instead of building up the type as properties are
added in code below. This is in preparation to Flow 191 which makes this
the default and removes the config.
More about the change in the Flow blog
[here](https://medium.com/flow-type/improved-handling-of-the-empty-object-in-flow-ead91887e40c).
This setting is an incremental path to the next Flow version enforcing
type annotations on most functions (except some inline callbacks).
Used
```
node_modules/.bin/flow codemod annotate-functions-and-classes --write .
```
to add a majority of the types with some hand cleanup when for large
inferred objects that should just be `Fiber` or weird constructs
including `any`.
Suppressed the remaining issues.
Builds on #25918
## Summary
resolves#24522
To upgrade to Manifest V3, one of the biggest issue is that we are no
longer allowed to add a script element with code in textContent so that
it would run synchronously. It's necessary for us because we need to
inject a global hook for react reconciler to detect whether devtools
exist.
To do that, we'll leverage a new API
`chrome.scripting.registerContentScripts` in V3. Particularly, we rely
on the "world" option (added in Chrome v102
[commit](e5ad3451c1))
to run it in the "main world" on the page.
This PR also renames a few content script files so that it's easier to
tell them apart from other extension scripts and understand the purpose
of each of them.
Manifest V3 is not yet ready for Firefox, so we need to keep some code
for compatibility.
## How did you test this change?
`yarn build:chrome && yarn test:chrome`
`yarn build:edge && yarn test:edge`
`yarn build:firefox && yarn test:firefox`
* 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
The existential type `*` was deprecated and a codemod provided to replace it. Ran that and did some manual fixups:
```sh
node_modules/.bin/flow codemod replace-existentials --write .
```
ghstack-source-id: 4c98b8db6a
Pull Request resolved: https://github.com/facebook/react/pull/25416
- 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
This upgrade made more expressions invalidate refinements. In some
places this lead to a large number of suppressions that I automatically
suppressed and should be followed up on when the code is touched.
I think most of them might require either manual annotations or moving
a value into a const to allow refinement.
ghstack-source-id: a45b40abf0
Pull Request resolved: https://github.com/facebook/react/pull/25410
* [DevTools] add simple events for internal logging
* fix lint
* fix lint
* better event name
* fix flow
* better way to fix flow
* combine 'select-element'
* use same event name for selecting element by inspecting
This PR:
* Simplifies the code in `SidebarEventInfo` by passing it the actual clicked event rather than an index.
* Lightly refactored the `SidebarEventInfo` code so that it can be used for more than just `schedulingEvents`
* Fixes bug. Previously, whenever a state update event was clicked, we updated the `selectedCommitIndex` in the `ProfilerContext`. However, this index is used for the selected commit in the Flamegraph profiler, which caused a bug where if you would change the contents of the event sidebar, the commit sidebar in the Flamegraph profiler would change too. This PR replaces this with the actual event info instead
Add column number for `viewSourceLineFunction` and renamed the function to `viewUrlSourceFunction` to match the other source function naming conventions
* [DevTools] front-end for profiling event stack
Adds a side-bar to the profiling tab. Users can now select an update event, and are
shown the callstack from the originating component. When a source path is available
there is now UI to jump to source.
Add FB enabled feature flag: enableProfilerComponentTree for the side-bar.
resolves#24170
This PR:
* Increases test retry count to 2 so that flaky tests have more of a chance to pass
* Ideally most e2e tests will run for all React versions (and ensure DevTools elegantly fails if React doesn't support its features). However, some features aren't supported in older React versions at all (ex. Profiling) Add runOnlyForReactRange function in these cases to skip tests that don't satisfy the correct React semver range
* Fix should allow searching for component by name test, which was flaky because sometimes the Searchbox would be unfocused the second time we try to type in it
* Edited test Should allow elements to be inspected to check that element inspect gracefully fails in older React versions
* Updated config to add a config.use.url field and a config.use.react_version field, which change depending on the React Version (and whether it's specified)
We used to listen to at the document level for this event. That allowed us to listen to up/down arrow key events while another section
of DevTools (like the search input) was focused. This was a minor UX positive.
(We had to use ownerDocument rather than document for this, because the DevTools extension renders the Components and Profiler tabs into portals.)
This approach caused a problem though: it meant that a react-devtools-inline instance could steal (and prevent/block) keyboard events from other JavaScript on the page– which could even include other react-devtools-inline instances. This is a potential major UX negative.
Given the above trade offs, we now listen on the root of the Tree itself.
Rationale: The only case where the unsupported dialog really matters is React Naive. That's the case where the frontend and backend versions are most likely to mismatch. In React Native, the backend is likely to send the bridge protocol version before sending operations– since the agent does this proactively during initialization.
I've tested the React Native starter app– after forcefully downgrading the backend version to 4.19.1 (see #23307 (comment)) and verified that this change "fixes" things. Not only does DevTools no longer throw an error that causes the UI to be hidden– it works (meaning that the Components tree can be inspected and interacted with).
This information can help with bug investigation for renderers (like React Native) that embed the DevTools backend into their source (separately from the DevTools frontend, which gets run by the user).
If the DevTools backend is too old to report a version, or if the version reported is the same as the frontend (as will be the case with the browser extension) then only a single version string will be shown, as before. If a different version is reported, then both will be shown separately.
Refactor DevTools to record Timeline data (in memory) while profiling. Updated the Profiler UI to import/export Timeline data along with legacy profiler data.
Relates to issue #22529
* DevTools: Only show StrictMode badge on root elements
Showing an inline non-compliance badge for every element in the tree is noisy. This commit changes it so that we only show inline icons for root elements (although we continue to show an icon for inspected elements regardless).