Skip to content

Commit 0cd5795

Browse files
guangyuexuDevtools-frontend LUCI CQ
authored andcommitted
Refactor InspectorView: extract drawer logic into InspectorDrawerView
This is a preparatory CL that extracts the existing drawer logic into the new InspectorDrawerView.ts without adding any new functionality. This is a pure refactoring. Original CL for the minimized drawer: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/7566246 Bug: 483762280 Change-Id: I808e1235776ad7b1bc826f00361ba461087b7cbb Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/7685970 Reviewed-by: Danil Somsikov <dsv@chromium.org> Commit-Queue: Guangyue Xu <guangyue.xu@microsoft.com> Reviewed-by: Piotr Paulski <piotrpaulski@chromium.org>
1 parent 3fde160 commit 0cd5795

9 files changed

Lines changed: 589 additions & 381 deletions

File tree

config/gni/devtools_grd_files.gni

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2598,6 +2598,7 @@ grd_files_unbundled_sources = [
25982598
"front_end/ui/legacy/GlassPane.js",
25992599
"front_end/ui/legacy/Infobar.js",
26002600
"front_end/ui/legacy/InplaceEditor.js",
2601+
"front_end/ui/legacy/InspectorDrawerView.js",
26012602
"front_end/ui/legacy/InspectorView.js",
26022603
"front_end/ui/legacy/KeyboardShortcut.js",
26032604
"front_end/ui/legacy/LinkContextMenuProvider.js",
@@ -2742,6 +2743,7 @@ grd_files_unbundled_sources = [
27422743
"front_end/ui/legacy/glassPane.css.js",
27432744
"front_end/ui/legacy/infobar.css.js",
27442745
"front_end/ui/legacy/inspectorCommon.css.js",
2746+
"front_end/ui/legacy/inspectorDrawerTabbedPane.css.js",
27452747
"front_end/ui/legacy/listWidget.css.js",
27462748
"front_end/ui/legacy/popover.css.js",
27472749
"front_end/ui/legacy/progressIndicator.css.js",

front_end/ui/legacy/BUILD.gn

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ generate_css("css_files") {
2020
"glassPane.css",
2121
"infobar.css",
2222
"inspectorCommon.css",
23+
"inspectorDrawerTabbedPane.css",
2324
"listWidget.css",
2425
"popover.css",
2526
"progressIndicator.css",
@@ -65,6 +66,7 @@ devtools_ui_module("ui") {
6566
"GlassPane.ts",
6667
"Infobar.ts",
6768
"InplaceEditor.ts",
69+
"InspectorDrawerView.ts",
6870
"InspectorView.ts",
6971
"KeyboardShortcut.ts",
7072
"LinkContextMenuProvider.ts",
@@ -184,6 +186,7 @@ devtools_ui_module("unittests") {
184186
"DockController.test.ts",
185187
"FilterBar.test.ts",
186188
"Infobar.test.ts",
189+
"InspectorDrawerView.test.ts",
187190
"InspectorView.test.ts",
188191
"KeyboardShortcut.test.ts",
189192
"ListModel.test.ts",
Lines changed: 304 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,304 @@
1+
// Copyright 2026 The Chromium Authors
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import * as Common from '../../core/common/common.js';
6+
import * as Host from '../../core/host/host.js';
7+
import {renderElementIntoDOM} from '../../testing/DOMHelpers.js';
8+
import {describeWithEnvironment} from '../../testing/EnvironmentHelpers.js';
9+
import {expectCall} from '../../testing/ExpectStubCall.js';
10+
import {setupSettingsHooks} from '../../testing/SettingsHelpers.js';
11+
12+
import * as LegacyUI from './legacy.js';
13+
14+
const InspectorView = LegacyUI.InspectorView.InspectorView;
15+
const Settings = Common.Settings.Settings;
16+
const DrawerOrientation = LegacyUI.InspectorView.DrawerOrientation;
17+
const {DockState} = LegacyUI.DockController;
18+
const {DockMode} = LegacyUI.InspectorView;
19+
const DRAWER_ORIENTATION_SETTING_NAME = 'inspector.drawer-orientation-by-dock-mode';
20+
21+
function getDrawerOrientationSettingByDock(dockMode: LegacyUI.InspectorView.DockMode):
22+
LegacyUI.InspectorView.DrawerOrientation {
23+
const setting = Settings.instance().settingForTest(DRAWER_ORIENTATION_SETTING_NAME);
24+
return (setting.get() as LegacyUI.InspectorView.DrawerOrientationByDockMode)[dockMode];
25+
}
26+
27+
describeWithEnvironment('InspectorDrawerView', () => {
28+
setupSettingsHooks();
29+
30+
function createInspectorViewWithDockState(dockState: LegacyUI.DockController.DockState): {
31+
inspectorView: LegacyUI.InspectorView.InspectorView,
32+
dockController: LegacyUI.DockController.DockController,
33+
} {
34+
const dockController = LegacyUI.DockController.DockController.instance({forceNew: true, canDock: true});
35+
dockController.setDockSide(dockState);
36+
37+
const inspectorView = InspectorView.instance({forceNew: true});
38+
inspectorView.markAsRoot();
39+
renderElementIntoDOM(inspectorView);
40+
41+
return {inspectorView, dockController};
42+
}
43+
44+
beforeEach(() => {
45+
// `setIsDocked` resolves async and leaves elements in the body after the test is finished.
46+
sinon.stub(Host.InspectorFrontendHost.InspectorFrontendHostInstance, 'setIsDocked');
47+
});
48+
49+
describe('drawer orientation', () => {
50+
describe('toggleDrawerOrientation', () => {
51+
it('drawer orientation and setting updates after each toggle for current dock mode', () => {
52+
const {inspectorView} = createInspectorViewWithDockState(DockState.BOTTOM);
53+
inspectorView.showDrawer({focus: true, hasTargetDrawer: false});
54+
55+
assert.strictEqual(getDrawerOrientationSettingByDock(DockMode.BOTTOM), DrawerOrientation.UNSET);
56+
inspectorView.toggleDrawerOrientation();
57+
58+
assert.strictEqual(getDrawerOrientationSettingByDock(DockMode.BOTTOM), DrawerOrientation.HORIZONTAL);
59+
assert.isFalse(inspectorView.isDrawerOrientationVertical());
60+
61+
inspectorView.toggleDrawerOrientation();
62+
assert.strictEqual(getDrawerOrientationSettingByDock(DockMode.BOTTOM), DrawerOrientation.VERTICAL);
63+
assert.isTrue(inspectorView.isDrawerOrientationVertical());
64+
});
65+
66+
for (const settingValue of [DrawerOrientation.UNSET, DrawerOrientation.VERTICAL, DrawerOrientation.HORIZONTAL]) {
67+
it(`drawer orientation stays ${settingValue} when toggled while drawer is hidden`, () => {
68+
const dockSpecificValue = {
69+
[DockMode.BOTTOM]: settingValue,
70+
[DockMode.SIDE]: DrawerOrientation.UNSET,
71+
[DockMode.UNDOCKED]: DrawerOrientation.UNSET,
72+
};
73+
const setting = Settings.instance().createSetting(DRAWER_ORIENTATION_SETTING_NAME, dockSpecificValue);
74+
const {inspectorView} = createInspectorViewWithDockState(DockState.BOTTOM);
75+
assert.isFalse(inspectorView.drawerVisible());
76+
assert.deepEqual(setting.get(), dockSpecificValue);
77+
const drawerOrientation = inspectorView.isDrawerOrientationVertical();
78+
79+
inspectorView.toggleDrawerOrientation();
80+
assert.deepEqual(setting.get(), dockSpecificValue, 'setting value should not change');
81+
assert.strictEqual(
82+
inspectorView.isDrawerOrientationVertical(), drawerOrientation, 'drawer orientation should not change');
83+
84+
inspectorView.toggleDrawerOrientation({force: DrawerOrientation.HORIZONTAL});
85+
assert.deepEqual(setting.get(), dockSpecificValue, 'setting value should not change when forced horizontal');
86+
assert.strictEqual(
87+
inspectorView.isDrawerOrientationVertical(), drawerOrientation,
88+
'drawer orientation should not change when forced horizontal');
89+
90+
inspectorView.toggleDrawerOrientation({force: DrawerOrientation.VERTICAL});
91+
assert.deepEqual(setting.get(), dockSpecificValue, 'setting value should not change when forced vertical');
92+
assert.strictEqual(
93+
inspectorView.isDrawerOrientationVertical(), drawerOrientation,
94+
'drawer orientation should not change when forced vertical');
95+
});
96+
}
97+
98+
for (const settingValue of [DrawerOrientation.VERTICAL, DrawerOrientation.HORIZONTAL]) {
99+
it(`drawer starts ${settingValue} if setting is ${settingValue}`, () => {
100+
const dockSpecificValue = {
101+
[DockMode.BOTTOM]: settingValue,
102+
[DockMode.SIDE]: DrawerOrientation.UNSET,
103+
[DockMode.UNDOCKED]: DrawerOrientation.UNSET,
104+
};
105+
Settings.instance().createSetting(DRAWER_ORIENTATION_SETTING_NAME, dockSpecificValue);
106+
const {inspectorView} = createInspectorViewWithDockState(DockState.BOTTOM);
107+
assert.strictEqual(inspectorView.isDrawerOrientationVertical(), settingValue === DrawerOrientation.VERTICAL);
108+
});
109+
}
110+
111+
for (const {force, isVertical} of
112+
[{force: DrawerOrientation.HORIZONTAL, isVertical: false},
113+
{force: DrawerOrientation.VERTICAL, isVertical: true},
114+
]) {
115+
it(`toggleDrawerOrientation can force ${force} orientation`, () => {
116+
const {inspectorView} = createInspectorViewWithDockState(DockState.BOTTOM);
117+
inspectorView.showDrawer({focus: true, hasTargetDrawer: false});
118+
assert.isTrue(inspectorView.isDrawerOrientationVertical());
119+
assert.strictEqual(getDrawerOrientationSettingByDock(DockMode.BOTTOM), DrawerOrientation.UNSET);
120+
121+
inspectorView.toggleDrawerOrientation({force});
122+
123+
assert.strictEqual(inspectorView.isDrawerOrientationVertical(), isVertical);
124+
assert.strictEqual(getDrawerOrientationSettingByDock(DockMode.BOTTOM), force);
125+
126+
inspectorView.toggleDrawerOrientation({force});
127+
128+
assert.strictEqual(inspectorView.isDrawerOrientationVertical(), isVertical);
129+
assert.strictEqual(getDrawerOrientationSettingByDock(DockMode.BOTTOM), force);
130+
131+
inspectorView.toggleDrawerOrientation();
132+
inspectorView.toggleDrawerOrientation({force});
133+
134+
assert.strictEqual(inspectorView.isDrawerOrientationVertical(), isVertical);
135+
assert.strictEqual(getDrawerOrientationSettingByDock(DockMode.BOTTOM), force);
136+
});
137+
}
138+
});
139+
140+
describe('isUserExplicitlyUpdatedDrawerOrientation', () => {
141+
it('isUserExplicitlyUpdatedDrawerOrientation returns false by default', () => {
142+
const {inspectorView} = createInspectorViewWithDockState(DockState.BOTTOM);
143+
144+
assert.isFalse(inspectorView.isUserExplicitlyUpdatedDrawerOrientation());
145+
});
146+
147+
it('isUserExplicitlyUpdatedDrawerOrientation returns true when orientation is toggled', () => {
148+
const {inspectorView} = createInspectorViewWithDockState(DockState.BOTTOM);
149+
150+
inspectorView.showDrawer({focus: true, hasTargetDrawer: false});
151+
inspectorView.toggleDrawerOrientation();
152+
153+
assert.isTrue(inspectorView.isUserExplicitlyUpdatedDrawerOrientation());
154+
});
155+
156+
it('returns true only for current dock mode', async () => {
157+
const {inspectorView, dockController} = createInspectorViewWithDockState(DockState.BOTTOM);
158+
const onDockSideChangeHandledForTestStub =
159+
sinon.stub(LegacyUI.InspectorView.InspectorView.instance(), 'applyDrawerOrientationForDockSideForTest');
160+
inspectorView.showDrawer({focus: true, hasTargetDrawer: false});
161+
162+
inspectorView.toggleDrawerOrientation();
163+
assert.isTrue(inspectorView.isUserExplicitlyUpdatedDrawerOrientation());
164+
165+
const waitForFirstDockSideChangeHandled = expectCall(onDockSideChangeHandledForTestStub);
166+
dockController.setDockSide(DockState.RIGHT);
167+
await waitForFirstDockSideChangeHandled;
168+
assert.isFalse(inspectorView.isUserExplicitlyUpdatedDrawerOrientation());
169+
170+
inspectorView.toggleDrawerOrientation();
171+
assert.isTrue(inspectorView.isUserExplicitlyUpdatedDrawerOrientation());
172+
173+
const waitForSecondDockSideChangeHandled = expectCall(onDockSideChangeHandledForTestStub);
174+
dockController.setDockSide(DockState.UNDOCKED);
175+
await waitForSecondDockSideChangeHandled;
176+
assert.isFalse(inspectorView.isUserExplicitlyUpdatedDrawerOrientation());
177+
178+
inspectorView.toggleDrawerOrientation();
179+
assert.isTrue(inspectorView.isUserExplicitlyUpdatedDrawerOrientation());
180+
});
181+
});
182+
183+
describe('dock-specific drawer orientation', () => {
184+
describe('default orientations by dock state', () => {
185+
it('defaults to horizontal orientation for RIGHT dock position', () => {
186+
const {inspectorView} = createInspectorViewWithDockState(DockState.RIGHT);
187+
assert.isFalse(inspectorView.isDrawerOrientationVertical());
188+
});
189+
190+
it('defaults to horizontal orientation for LEFT dock position', () => {
191+
const {inspectorView} = createInspectorViewWithDockState(DockState.LEFT);
192+
assert.isFalse(inspectorView.isDrawerOrientationVertical());
193+
});
194+
195+
it('defaults to horizontal orientation for UNDOCKED dock position', () => {
196+
const {inspectorView} = createInspectorViewWithDockState(DockState.UNDOCKED);
197+
assert.isFalse(inspectorView.isDrawerOrientationVertical());
198+
});
199+
200+
it('defaults to vertical orientation for BOTTOM dock position', () => {
201+
const {inspectorView} = createInspectorViewWithDockState(DockState.BOTTOM);
202+
assert.isTrue(inspectorView.isDrawerOrientationVertical());
203+
});
204+
});
205+
206+
describe('automatic dock state change handling', () => {
207+
it('automatically updates drawer orientation when switching from bottom to side dock', async () => {
208+
const {inspectorView, dockController} = createInspectorViewWithDockState(DockState.BOTTOM);
209+
const waitForDockSideChangeHandled = expectCall(
210+
sinon.stub(LegacyUI.InspectorView.InspectorView.instance(), 'applyDrawerOrientationForDockSideForTest'));
211+
inspectorView.showDrawer({focus: true, hasTargetDrawer: false});
212+
213+
assert.isTrue(inspectorView.isDrawerOrientationVertical());
214+
dockController.setDockSide(DockState.RIGHT);
215+
await waitForDockSideChangeHandled;
216+
217+
assert.isFalse(inspectorView.isDrawerOrientationVertical());
218+
});
219+
220+
it('automatically updates drawer orientation when switching from side to bottom dock', async () => {
221+
const {inspectorView, dockController} = createInspectorViewWithDockState(DockState.RIGHT);
222+
const waitForDockSideChangeHandled = expectCall(
223+
sinon.stub(LegacyUI.InspectorView.InspectorView.instance(), 'applyDrawerOrientationForDockSideForTest'));
224+
inspectorView.showDrawer({focus: true, hasTargetDrawer: false});
225+
226+
assert.isFalse(inspectorView.isDrawerOrientationVertical());
227+
dockController.setDockSide(DockState.BOTTOM);
228+
await waitForDockSideChangeHandled;
229+
230+
assert.isTrue(inspectorView.isDrawerOrientationVertical());
231+
});
232+
233+
it('respects saved preferences when switching dock positions', async () => {
234+
const {inspectorView, dockController} = createInspectorViewWithDockState(DockState.BOTTOM);
235+
const onDockSideChangeHandledForTestStub =
236+
sinon.stub(LegacyUI.InspectorView.InspectorView.instance(), 'applyDrawerOrientationForDockSideForTest');
237+
const waitForFirstDockSideChangeHandled = expectCall(onDockSideChangeHandledForTestStub);
238+
inspectorView.showDrawer({focus: true, hasTargetDrawer: false});
239+
240+
inspectorView.toggleDrawerOrientation({force: DrawerOrientation.HORIZONTAL});
241+
assert.isFalse(inspectorView.isDrawerOrientationVertical());
242+
243+
dockController.setDockSide(DockState.RIGHT);
244+
await waitForFirstDockSideChangeHandled;
245+
inspectorView.toggleDrawerOrientation({force: DrawerOrientation.VERTICAL});
246+
assert.isTrue(inspectorView.isDrawerOrientationVertical());
247+
248+
const waitForSecondDockSideChangeHandled = expectCall(onDockSideChangeHandledForTestStub);
249+
dockController.setDockSide(DockState.UNDOCKED);
250+
await waitForSecondDockSideChangeHandled;
251+
inspectorView.toggleDrawerOrientation({force: DrawerOrientation.HORIZONTAL});
252+
assert.isFalse(inspectorView.isDrawerOrientationVertical());
253+
254+
const waitForThirdDockSideChangeHandled = expectCall(onDockSideChangeHandledForTestStub);
255+
dockController.setDockSide(DockState.BOTTOM);
256+
await waitForThirdDockSideChangeHandled;
257+
assert.isFalse(inspectorView.isDrawerOrientationVertical());
258+
259+
const waitForFourthDockSideChangeHandled = expectCall(onDockSideChangeHandledForTestStub);
260+
dockController.setDockSide(DockState.LEFT);
261+
await waitForFourthDockSideChangeHandled;
262+
assert.isTrue(inspectorView.isDrawerOrientationVertical());
263+
264+
const waitForFifthDockSideChangeHandled = expectCall(onDockSideChangeHandledForTestStub);
265+
dockController.setDockSide(DockState.UNDOCKED);
266+
await waitForFifthDockSideChangeHandled;
267+
assert.isFalse(inspectorView.isDrawerOrientationVertical());
268+
});
269+
270+
it('does not change orientation when drawer is closed during dock switch', async () => {
271+
const {inspectorView, dockController} = createInspectorViewWithDockState(DockState.BOTTOM);
272+
const waitForDockSideChangeHandled = expectCall(
273+
sinon.stub(LegacyUI.InspectorView.InspectorView.instance(), 'applyDrawerOrientationForDockSideForTest'));
274+
275+
assert.isFalse(inspectorView.drawerVisible());
276+
const initialOrientation = inspectorView.isDrawerOrientationVertical();
277+
278+
dockController.setDockSide(DockState.RIGHT);
279+
await waitForDockSideChangeHandled;
280+
281+
assert.strictEqual(inspectorView.isDrawerOrientationVertical(), initialOrientation);
282+
});
283+
284+
it('updates orientation correctly when showing the drawer for the first time after a dock switch', async () => {
285+
const {inspectorView, dockController} = createInspectorViewWithDockState(DockState.BOTTOM);
286+
const waitForDockSideChangeHandled = expectCall(
287+
sinon.stub(LegacyUI.InspectorView.InspectorView.instance(), 'applyDrawerOrientationForDockSideForTest'));
288+
289+
assert.isFalse(inspectorView.drawerVisible());
290+
assert.isTrue(
291+
inspectorView.isDrawerOrientationVertical(), 'Drawer should be vertical when docked at the bottom');
292+
293+
dockController.setDockSide(DockState.RIGHT);
294+
await waitForDockSideChangeHandled;
295+
296+
inspectorView.showDrawer({focus: true, hasTargetDrawer: false});
297+
298+
assert.isFalse(
299+
inspectorView.isDrawerOrientationVertical(), 'Drawer should become horizontal when docked to the right');
300+
});
301+
});
302+
});
303+
});
304+
});

0 commit comments

Comments
 (0)