Skip to content

Commit be1ce71

Browse files
committed
DevTools: merge element fields in TreeStateContext
1 parent 291cf0d commit be1ce71

9 files changed

Lines changed: 230 additions & 266 deletions

File tree

packages/react-devtools-shared/src/__tests__/inspectedElement-test.js

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -115,16 +115,15 @@ describe('InspectedElement', () => {
115115

116116
const Contexts = ({
117117
children,
118-
defaultSelectedElementID = null,
119-
defaultSelectedElementIndex = null,
118+
defaultInspectedElementID = null,
119+
defaultInspectedElementIndex = null,
120120
}) => (
121121
<BridgeContext.Provider value={bridge}>
122122
<StoreContext.Provider value={store}>
123123
<SettingsContextController>
124124
<TreeContextController
125-
defaultSelectedElementID={defaultSelectedElementID}
126-
defaultSelectedElementIndex={defaultSelectedElementIndex}
127-
defaultInspectedElementID={defaultSelectedElementID}>
125+
defaultInspectedElementID={defaultInspectedElementID}
126+
defaultInspectedElementIndex={defaultInspectedElementIndex}>
128127
<InspectedElementContextController>
129128
{children}
130129
</InspectedElementContextController>
@@ -167,8 +166,8 @@ describe('InspectedElement', () => {
167166
testRendererInstance.update(
168167
<ErrorBoundary>
169168
<Contexts
170-
defaultSelectedElementID={id}
171-
defaultSelectedElementIndex={index}>
169+
defaultInspectedElementID={id}
170+
defaultInspectedElementIndex={index}>
172171
<React.Suspense fallback={null}>
173172
<Suspender id={id} index={index} />
174173
</React.Suspense>
@@ -355,7 +354,7 @@ describe('InspectedElement', () => {
355354
const {index, shouldHaveLegacyContext} = cases[i];
356355

357356
// HACK: Recreate TestRenderer instance because we rely on default state values
358-
// from props like defaultSelectedElementID and it's easier to reset here than
357+
// from props like defaultInspectedElementID and it's easier to reset here than
359358
// to read the TreeDispatcherContext and update the selected ID that way.
360359
// We're testing the inspected values here, not the context wiring, so that's ok.
361360
withErrorsOrWarningsIgnored(
@@ -2069,7 +2068,7 @@ describe('InspectedElement', () => {
20692068
}, false);
20702069

20712070
// HACK: Recreate TestRenderer instance because we rely on default state values
2072-
// from props like defaultSelectedElementID and it's easier to reset here than
2071+
// from props like defaultInspectedElementID and it's easier to reset here than
20732072
// to read the TreeDispatcherContext and update the selected ID that way.
20742073
// We're testing the inspected values here, not the context wiring, so that's ok.
20752074
withErrorsOrWarningsIgnored(
@@ -2129,7 +2128,7 @@ describe('InspectedElement', () => {
21292128
}, false);
21302129

21312130
// HACK: Recreate TestRenderer instance because we rely on default state values
2132-
// from props like defaultSelectedElementID and it's easier to reset here than
2131+
// from props like defaultInspectedElementID and it's easier to reset here than
21332132
// to read the TreeDispatcherContext and update the selected ID that way.
21342133
// We're testing the inspected values here, not the context wiring, so that's ok.
21352134
withErrorsOrWarningsIgnored(
@@ -2408,8 +2407,8 @@ describe('InspectedElement', () => {
24082407
await utils.actAsync(() => {
24092408
root = TestRenderer.create(
24102409
<Contexts
2411-
defaultSelectedElementID={id}
2412-
defaultSelectedElementIndex={index}>
2410+
defaultInspectedElementID={id}
2411+
defaultInspectedElementIndex={index}>
24132412
<React.Suspense fallback={null}>
24142413
<Suspender target={id} />
24152414
</React.Suspense>
@@ -3101,6 +3100,7 @@ describe('InspectedElement', () => {
31013100

31023101
await utils.actAsync(() => {
31033102
store.componentFilters = [utils.createDisplayNameFilter('Wrapper')];
3103+
jest.runOnlyPendingTimers();
31043104
}, false);
31053105

31063106
expect(state).toMatchInlineSnapshot(`
@@ -3120,6 +3120,7 @@ describe('InspectedElement', () => {
31203120

31213121
await utils.actAsync(() => {
31223122
store.componentFilters = [];
3123+
jest.runOnlyPendingTimers();
31233124
}, false);
31243125
expect(state).toMatchInlineSnapshot(`
31253126
✕ 0, ⚠ 2

packages/react-devtools-shared/src/__tests__/profilerContext-test.js

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,14 @@ describe('ProfilerContext', () => {
6969

7070
const Contexts = ({
7171
children = null,
72-
defaultSelectedElementID = null,
73-
defaultSelectedElementIndex = null,
72+
defaultInspectedElementID = null,
73+
defaultInspectedElementIndex = null,
7474
}: any) => (
7575
<BridgeContext.Provider value={bridge}>
7676
<StoreContext.Provider value={store}>
7777
<TreeContextController
78-
defaultSelectedElementID={defaultSelectedElementID}
79-
defaultSelectedElementIndex={defaultSelectedElementIndex}>
78+
defaultInspectedElementID={defaultInspectedElementID}
79+
defaultInspectedElementIndex={defaultInspectedElementIndex}>
8080
<ProfilerContextController>{children}</ProfilerContextController>
8181
</TreeContextController>
8282
</StoreContext.Provider>
@@ -225,8 +225,8 @@ describe('ProfilerContext', () => {
225225
await utils.actAsync(() =>
226226
TestRenderer.create(
227227
<Contexts
228-
defaultSelectedElementID={store.getElementIDAtIndex(3)}
229-
defaultSelectedElementIndex={3}>
228+
defaultInspectedElementID={store.getElementIDAtIndex(3)}
229+
defaultInspectedElementIndex={3}>
230230
<ContextReader />
231231
</Contexts>,
232232
),
@@ -276,8 +276,8 @@ describe('ProfilerContext', () => {
276276
await utils.actAsync(() =>
277277
TestRenderer.create(
278278
<Contexts
279-
defaultSelectedElementID={store.getElementIDAtIndex(3)}
280-
defaultSelectedElementIndex={3}>
279+
defaultInspectedElementID={store.getElementIDAtIndex(3)}
280+
defaultInspectedElementIndex={3}>
281281
<ContextReader />
282282
</Contexts>,
283283
),
@@ -323,8 +323,8 @@ describe('ProfilerContext', () => {
323323
await utils.actAsync(() =>
324324
TestRenderer.create(
325325
<Contexts
326-
defaultSelectedElementID={store.getElementIDAtIndex(3)}
327-
defaultSelectedElementIndex={3}>
326+
defaultInspectedElementID={store.getElementIDAtIndex(3)}
327+
defaultInspectedElementIndex={3}>
328328
<ContextReader />
329329
</Contexts>,
330330
),
@@ -374,8 +374,8 @@ describe('ProfilerContext', () => {
374374
await utils.actAsync(() =>
375375
TestRenderer.create(
376376
<Contexts
377-
defaultSelectedElementID={store.getElementIDAtIndex(3)}
378-
defaultSelectedElementIndex={3}>
377+
defaultInspectedElementID={store.getElementIDAtIndex(3)}
378+
defaultInspectedElementIndex={3}>
379379
<ContextReader />
380380
</Contexts>,
381381
),
@@ -415,11 +415,12 @@ describe('ProfilerContext', () => {
415415

416416
let context: Context = ((null: any): Context);
417417
let dispatch: DispatcherContext = ((null: any): DispatcherContext);
418-
let selectedElementID = null;
418+
let inspectedElementID = null;
419419
function ContextReader() {
420420
context = React.useContext(ProfilerContext);
421421
dispatch = React.useContext(TreeDispatcherContext);
422-
selectedElementID = React.useContext(TreeStateContext).selectedElementID;
422+
inspectedElementID =
423+
React.useContext(TreeStateContext).inspectedElementID;
423424
return null;
424425
}
425426

@@ -428,13 +429,15 @@ describe('ProfilerContext', () => {
428429
// Select an element within the second root.
429430
await utils.actAsync(() =>
430431
TestRenderer.create(
431-
<Contexts defaultSelectedElementID={id} defaultSelectedElementIndex={3}>
432+
<Contexts
433+
defaultInspectedElementID={id}
434+
defaultInspectedElementIndex={3}>
432435
<ContextReader />
433436
</Contexts>,
434437
),
435438
);
436439

437-
expect(selectedElementID).toBe(id);
440+
expect(inspectedElementID).toBe(id);
438441

439442
// Profile and record more updates to both roots
440443
await utils.actAsync(() => store.profilerStore.startProfiling());
@@ -448,7 +451,7 @@ describe('ProfilerContext', () => {
448451
utils.act(() => dispatch({type: 'SELECT_ELEMENT_AT_INDEX', payload: 0}));
449452

450453
// Verify that the initial Profiler root selection is maintained.
451-
expect(selectedElementID).toBe(otherID);
454+
expect(inspectedElementID).toBe(otherID);
452455
expect(context).not.toBeNull();
453456
expect(context.rootID).toBe(store.getRootIDForElement(id));
454457
});
@@ -484,11 +487,12 @@ describe('ProfilerContext', () => {
484487

485488
let context: Context = ((null: any): Context);
486489
let dispatch: DispatcherContext = ((null: any): DispatcherContext);
487-
let selectedElementID = null;
490+
let inspectedElementID = null;
488491
function ContextReader() {
489492
context = React.useContext(ProfilerContext);
490493
dispatch = React.useContext(TreeDispatcherContext);
491-
selectedElementID = React.useContext(TreeStateContext).selectedElementID;
494+
inspectedElementID =
495+
React.useContext(TreeStateContext).inspectedElementID;
492496
return null;
493497
}
494498

@@ -497,13 +501,15 @@ describe('ProfilerContext', () => {
497501
// Select an element within the second root.
498502
await utils.actAsync(() =>
499503
TestRenderer.create(
500-
<Contexts defaultSelectedElementID={id} defaultSelectedElementIndex={3}>
504+
<Contexts
505+
defaultInspectedElementID={id}
506+
defaultInspectedElementIndex={3}>
501507
<ContextReader />
502508
</Contexts>,
503509
),
504510
);
505511

506-
expect(selectedElementID).toBe(id);
512+
expect(inspectedElementID).toBe(id);
507513

508514
// Profile and record more updates to both roots
509515
await utils.actAsync(() => store.profilerStore.startProfiling());
@@ -517,7 +523,7 @@ describe('ProfilerContext', () => {
517523
utils.act(() => dispatch({type: 'SELECT_ELEMENT_AT_INDEX', payload: 0}));
518524

519525
// Verify that the initial Profiler root selection is maintained.
520-
expect(selectedElementID).toBe(otherID);
526+
expect(inspectedElementID).toBe(otherID);
521527
expect(context).not.toBeNull();
522528
expect(context.rootID).toBe(store.getRootIDForElement(id));
523529
});
@@ -553,10 +559,11 @@ describe('ProfilerContext', () => {
553559
`);
554560

555561
let context: Context = ((null: any): Context);
556-
let selectedElementID = null;
562+
let inspectedElementID = null;
557563
function ContextReader() {
558564
context = React.useContext(ProfilerContext);
559-
selectedElementID = React.useContext(TreeStateContext).selectedElementID;
565+
inspectedElementID =
566+
React.useContext(TreeStateContext).inspectedElementID;
560567
return null;
561568
}
562569

@@ -567,14 +574,14 @@ describe('ProfilerContext', () => {
567574
</Contexts>,
568575
),
569576
);
570-
expect(selectedElementID).toBeNull();
577+
expect(inspectedElementID).toBeNull();
571578

572579
// Select an element in the Profiler tab and verify that the selection is synced to the Components tab.
573580
await utils.actAsync(() => context.selectFiber(parentID, 'Parent'));
574-
expect(selectedElementID).toBe(parentID);
581+
expect(inspectedElementID).toBe(parentID);
575582

576583
// Select an unmounted element and verify no Components tab selection doesn't change.
577584
await utils.actAsync(() => context.selectFiber(childID, 'Child'));
578-
expect(selectedElementID).toBe(parentID);
585+
expect(inspectedElementID).toBe(parentID);
579586
});
580587
});

packages/react-devtools-shared/src/devtools/utils.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ export function printStore(
6767
if (state === null) {
6868
return '';
6969
}
70-
return state.selectedElementIndex === index ? `→` : ' ';
70+
return state.inspectedElementIndex === index ? `→` : ' ';
7171
}
7272

7373
function printErrorsAndWarnings(element: Element): string {

packages/react-devtools-shared/src/devtools/views/Components/Element.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ type Props = {
3333

3434
export default function Element({data, index, style}: Props): React.Node {
3535
const store = useContext(StoreContext);
36-
const {ownerFlatTree, ownerID, selectedElementID} =
36+
const {ownerFlatTree, ownerID, inspectedElementID} =
3737
useContext(TreeStateContext);
3838
const dispatch = useContext(TreeDispatcherContext);
3939

@@ -46,7 +46,7 @@ export default function Element({data, index, style}: Props): React.Node {
4646

4747
const {isNavigatingWithKeyboard, onElementMouseEnter, treeFocused} = data;
4848
const id = element === null ? null : element.id;
49-
const isSelected = selectedElementID === id;
49+
const isSelected = inspectedElementID === id;
5050

5151
const errorsAndWarningsSubscription = useMemo(
5252
() => ({

packages/react-devtools-shared/src/devtools/views/Components/NativeStyleEditor/context.js

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,10 @@ function NativeStyleContextController({children}: Props): React.Node {
100100
[store],
101101
);
102102

103-
// It's very important that this context consumes selectedElementID and not NativeStyleID.
103+
// It's very important that this context consumes inspectedElementID and not NativeStyleID.
104104
// Otherwise the effect that sends the "inspect" message across the bridge-
105105
// would itself be blocked by the same render that suspends (waiting for the data).
106-
const {selectedElementID} = useContext<StateContext>(TreeStateContext);
106+
const {inspectedElementID} = useContext<StateContext>(TreeStateContext);
107107

108108
const [currentStyleAndLayout, setCurrentStyleAndLayout] =
109109
useState<StyleAndLayoutFrontend | null>(null);
@@ -128,7 +128,7 @@ function NativeStyleContextController({children}: Props): React.Node {
128128
resource.write(element, styleAndLayout);
129129

130130
// Schedule update with React if the currently-selected element has been invalidated.
131-
if (id === selectedElementID) {
131+
if (id === inspectedElementID) {
132132
setCurrentStyleAndLayout(styleAndLayout);
133133
}
134134
}
@@ -141,15 +141,15 @@ function NativeStyleContextController({children}: Props): React.Node {
141141
'NativeStyleEditor_styleAndLayout',
142142
onStyleAndLayout,
143143
);
144-
}, [bridge, currentStyleAndLayout, selectedElementID, store]);
144+
}, [bridge, currentStyleAndLayout, inspectedElementID, store]);
145145

146146
// This effect handler polls for updates on the currently selected element.
147147
useEffect(() => {
148-
if (selectedElementID === null) {
148+
if (inspectedElementID === null) {
149149
return () => {};
150150
}
151151

152-
const rendererID = store.getRendererIDForElement(selectedElementID);
152+
const rendererID = store.getRendererIDForElement(inspectedElementID);
153153

154154
let timeoutID: TimeoutID | null = null;
155155

@@ -158,7 +158,7 @@ function NativeStyleContextController({children}: Props): React.Node {
158158

159159
if (rendererID !== null) {
160160
bridge.send('NativeStyleEditor_measure', {
161-
id: selectedElementID,
161+
id: inspectedElementID,
162162
rendererID,
163163
});
164164
}
@@ -170,7 +170,7 @@ function NativeStyleContextController({children}: Props): React.Node {
170170

171171
const onStyleAndLayout = ({id}: StyleAndLayoutBackend) => {
172172
// If this is the element we requested, wait a little bit and then ask for another update.
173-
if (id === selectedElementID) {
173+
if (id === inspectedElementID) {
174174
if (timeoutID !== null) {
175175
clearTimeout(timeoutID);
176176
}
@@ -190,7 +190,7 @@ function NativeStyleContextController({children}: Props): React.Node {
190190
clearTimeout(timeoutID);
191191
}
192192
};
193-
}, [bridge, selectedElementID, store]);
193+
}, [bridge, inspectedElementID, store]);
194194

195195
const value = useMemo(
196196
() => ({getStyleAndLayout}),

packages/react-devtools-shared/src/devtools/views/Components/SelectedTreeHighlight.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,19 @@ export default function SelectedTreeHighlight(_: {}): React.Node {
2828
const {lineHeight} = useContext(SettingsContext);
2929
const store = useContext(StoreContext);
3030
const treeFocused = useContext(TreeFocusedContext);
31-
const {ownerID, selectedElementID} = useContext(TreeStateContext);
31+
const {ownerID, inspectedElementID} = useContext(TreeStateContext);
3232

3333
const subscription = useMemo(
3434
() => ({
3535
getCurrentValue: () => {
3636
if (
37-
selectedElementID === null ||
38-
store.isInsideCollapsedSubTree(selectedElementID)
37+
inspectedElementID === null ||
38+
store.isInsideCollapsedSubTree(inspectedElementID)
3939
) {
4040
return null;
4141
}
4242

43-
const element = store.getElementByID(selectedElementID);
43+
const element = store.getElementByID(inspectedElementID);
4444
if (
4545
element === null ||
4646
element.isCollapsed ||
@@ -83,7 +83,7 @@ export default function SelectedTreeHighlight(_: {}): React.Node {
8383
};
8484
},
8585
}),
86-
[selectedElementID, store],
86+
[inspectedElementID, store],
8787
);
8888
const data = useSubscription<Data | null>(subscription);
8989

0 commit comments

Comments
 (0)