bvaughn / react-devtools-experimental

Experimental rewrite of the React DevTools extension
https://react-devtools-experimental.now.sh
MIT License
965 stars 55 forks source link

React Native: Standalone package and basic RN support #334

Closed bvaughn closed 5 years ago

bvaughn commented 5 years ago

Need to create react-devtools and react-devtools-core packages to support React Native, Safari, iframes, and other embedded cases like Nuclide and Flipper.

Some features will require changes to support the RN environment:

In addition, because the v4 backend API is incompatible with v3, releasing the new react-devtools and react-devtools-core packages will also require updating and coordinating with: React Native, Flipper, and Nuclide packages (and possibly others).

For now, I will be pushing my work to the npm-packages branch. I will rebase and cleanup before merging.

jhen0409 commented 5 years ago

Hi @bvaughn, do you have any work about the update for Inspector.js? Currently it isn't working with the global hook of v4.

bvaughn commented 5 years ago

@jhen0409 Yes, I have a patch to a few React Native components. Inspector and several of the YellowBox* components. Here's the Inspector patch 😄

33c33,34
< // required for devtools to be able to edit react native styles
---
> // Required for React DevTools to view/edit React Native styles in Flipper.
> // Flipper doesn't inject these values when initializing DevTools.
34a36,39
> const viewConfig = require('../Components/View/ReactNativeViewViewConfig.js');
> hook.nativeStyleEditorValidAttributes = Object.keys(
>   viewConfig.validAttributes.style,
> );
37,39c42
<   const allRenderers = Object.keys(hook._renderers).map(
<     key => hook._renderers[key],
<   );
---
>   const allRenderers = Array.from(hook.renderers.values());
80a84
>   _hideTimeoutID: TimeoutID | null = null;
119,126c123,125
<     let _hideWait = null;
<     const hlSub = agent.sub('highlight', ({node, name, props}) => {
<       clearTimeout(_hideWait);
< 
<       if (typeof node !== 'number') {
<         // Fiber
<         node = ReactNative.findNodeHandle(node);
<       }
---
>     agent.addListener('hideNativeHighlight', this._onAgentHideNativeHighlight);
>     agent.addListener('showNativeHighlight', this._onAgentShowNativeHighlight);
>     agent.addListener('shutdown', this._onAgentShutdown);
128,136c127,128
<       UIManager.measure(node, (x, y, width, height, left, top) => {
<         this.setState({
<           hierarchy: [],
<           inspected: {
<             frame: {left, top, width, height},
<             style: props ? props.style : {},
<           },
<         });
<       });
---
>     this.setState({
>       devtoolsAgent: agent,
138,147c130,157
<     const hideSub = agent.sub('hideHighlight', () => {
<       if (this.state.inspected === null) {
<         return;
<       }
<       // we wait to actually hide in order to avoid flicker
<       _hideWait = setTimeout(() => {
<         this.setState({
<           inspected: null,
<         });
<       }, 100);
---
>   };
> 
>   _onAgentHideNativeHighlight = () => {
>     if (this.state.inspected === null) {
>       return;
>     }
>     // we wait to actually hide in order to avoid flicker
>     this._hideTimeoutID = setTimeout(() => {
>       this.setState({
>         inspected: null,
>       });
>     }, 100);
>   };
> 
>   _onAgentShowNativeHighlight = node => {
>     clearTimeout(this._hideTimeoutID);
> 
>     if (typeof node !== 'number') {
>       node = ReactNative.findNodeHandle(node);
>     }
> 
>     UIManager.measure(node, (x, y, width, height, left, top) => {
>       this.setState({
>         hierarchy: [],
>         inspected: {
>           frame: {left, top, width, height},
>         },
>       });
149c159,172
<     this._subs = [hlSub, hideSub];
---
>   };
> 
>   _onAgentShutdown = () => {
>     const agent = this.state.devtoolsAgent;
>     if (agent != null) {
>       agent.removeListener(
>         'hideNativeHighlight',
>         this._onAgentHideNativeHighlight,
>       );
>       agent.removeListener(
>         'showNativeHighlight',
>         this._onAgentShowNativeHighlight,
>       );
>       agent.removeListener('shutdown', this._onAgentShutdown);
151d173
<     agent.on('shutdown', () => {
153,157c175
<       this._subs = null;
<     });
<     this.setState({
<       devtoolsAgent: agent,
<     });
---
>     }
190,194c208
<       this.state.devtoolsAgent.selectFromDOMNode(
<         touchedViewTag,
<         true,
<         offsetFromLeaf,
<       );
---
>       this.state.devtoolsAgent.selectNode(touchedViewTag);
bvaughn commented 5 years ago

I will be landing support for this today (hopefully) within Facebook. Going to close this out for now.