Use scoped TargetManager API in the InspectElementModeController
Bug: 1417112
Change-Id: I195cd7b7af55f9316f557eb82cb92bf82565f23f
Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/4307578
Reviewed-by: Wolfgang Beyer <wolfi@chromium.org>
Commit-Queue: Danil Somsikov <dsv@chromium.org>
Auto-Submit: Danil Somsikov <dsv@chromium.org>
diff --git a/front_end/panels/elements/InspectElementModeController.ts b/front_end/panels/elements/InspectElementModeController.ts
index 44cdbfc..ccad9c0 100644
--- a/front_end/panels/elements/InspectElementModeController.ts
+++ b/front_end/panels/elements/InspectElementModeController.ts
@@ -50,9 +50,9 @@
SDK.TargetManager.Events.SuspendStateChanged, this.suspendStateChanged, this);
SDK.TargetManager.TargetManager.instance().addModelListener(
SDK.OverlayModel.OverlayModel, SDK.OverlayModel.Events.ExitedInspectMode,
- () => this.setMode(Protocol.Overlay.InspectMode.None));
+ () => this.setMode(Protocol.Overlay.InspectMode.None), undefined, {scoped: true});
SDK.OverlayModel.OverlayModel.setInspectNodeHandler(this.inspectNode.bind(this));
- SDK.TargetManager.TargetManager.instance().observeModels(SDK.OverlayModel.OverlayModel, this);
+ SDK.TargetManager.TargetManager.instance().observeModels(SDK.OverlayModel.OverlayModel, this, {scoped: true});
this.showDetailedInspectTooltipSetting =
Common.Settings.Settings.instance().moduleSetting('showDetailedInspectTooltip');
@@ -117,7 +117,8 @@
return;
}
this.mode = mode;
- for (const overlayModel of SDK.TargetManager.TargetManager.instance().models(SDK.OverlayModel.OverlayModel)) {
+ for (const overlayModel of SDK.TargetManager.TargetManager.instance().models(
+ SDK.OverlayModel.OverlayModel, {scoped: true})) {
void overlayModel.setInspectMode(mode, this.showDetailedInspectTooltipSetting.get());
}
if (this.toggleSearchAction) {
diff --git a/test/unittests/front_end/panels/elements/BUILD.gn b/test/unittests/front_end/panels/elements/BUILD.gn
index 69897d5..4250641 100644
--- a/test/unittests/front_end/panels/elements/BUILD.gn
+++ b/test/unittests/front_end/panels/elements/BUILD.gn
@@ -12,6 +12,7 @@
"CSSRuleValidator_test.ts",
"ClassesPaneWidget_test.ts",
"ElementsPanel_test.ts",
+ "InspectElementModeController_test.ts",
"LayoutSidebarPane_test.ts",
"StylePropertyHighlighter_test.ts",
"StylePropertyTreeElement_test.ts",
diff --git a/test/unittests/front_end/panels/elements/InspectElementModeController_test.ts b/test/unittests/front_end/panels/elements/InspectElementModeController_test.ts
new file mode 100644
index 0000000..9b8a959
--- /dev/null
+++ b/test/unittests/front_end/panels/elements/InspectElementModeController_test.ts
@@ -0,0 +1,81 @@
+// Copyright 2023 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import * as SDK from '../../../../../front_end/core/sdk/sdk.js';
+import * as Elements from '../../../../../front_end/panels/elements/elements.js';
+
+import type * as Protocol from '../../../../../front_end/generated/protocol.js';
+import {createTarget, stubNoopSettings} from '../../helpers/EnvironmentHelpers.js';
+import {assertNotNullOrUndefined} from '../../../../../front_end/core/platform/platform.js';
+import {describeWithMockConnection, setMockConnectionResponseHandler} from '../../helpers/MockConnection.js';
+
+const {assert} = chai;
+
+const NODE_ID = 1 as Protocol.DOM.NodeId;
+
+describeWithMockConnection('InspectElementModeController', () => {
+ let inScopeTarget: SDK.Target.Target;
+ let inScopeSubTarget: SDK.Target.Target;
+ let outOfScopeTarget: SDK.Target.Target;
+ let outOfScopeSubTarget: SDK.Target.Target;
+ let modeController: Elements.InspectElementModeController.InspectElementModeController;
+
+ function onModeToggle(target: SDK.Target.Target) {
+ const model = target.model(SDK.OverlayModel.OverlayModel);
+ assertNotNullOrUndefined(model);
+ return model.once(SDK.OverlayModel.Events.InspectModeWillBeToggled);
+ }
+
+ function failOnModeToggle(target: SDK.Target.Target) {
+ const model = target.model(SDK.OverlayModel.OverlayModel);
+ assertNotNullOrUndefined(model);
+ model.addEventListener(
+ SDK.OverlayModel.Events.InspectModeWillBeToggled,
+ () => assert.fail('Unexected mode toggle on out of scope target'));
+ }
+
+ beforeEach(() => {
+ stubNoopSettings();
+ const tabTarget = createTarget({type: SDK.Target.Type.Tab});
+ inScopeTarget = createTarget({parentTarget: tabTarget});
+ inScopeSubTarget = createTarget({parentTarget: inScopeTarget});
+ outOfScopeTarget = createTarget({parentTarget: tabTarget});
+ outOfScopeSubTarget = createTarget({parentTarget: outOfScopeTarget});
+ failOnModeToggle(outOfScopeTarget);
+ failOnModeToggle(outOfScopeSubTarget);
+ SDK.TargetManager.TargetManager.instance().setScopeTarget(inScopeTarget);
+ modeController = new Elements.InspectElementModeController.InspectElementModeController();
+ setMockConnectionResponseHandler('DOM.getDocument', () => ({root: {nodeId: NODE_ID}}));
+ });
+
+ it('synchronises mode for in scope models', async () => {
+ for (const target of SDK.TargetManager.TargetManager.instance().targets()) {
+ assert.isFalse(Boolean(target.model(SDK.OverlayModel.OverlayModel)?.inspectModeEnabled()));
+ }
+
+ modeController.toggleInspectMode();
+ await Promise.all([onModeToggle(inScopeTarget), onModeToggle(inScopeSubTarget)]);
+
+ const anotherInScopeSubTarget = createTarget({parentTarget: inScopeTarget});
+ await onModeToggle(anotherInScopeSubTarget);
+
+ const anotherOutOfScopeSubTarget = createTarget({parentTarget: inScopeTarget});
+ failOnModeToggle(anotherOutOfScopeSubTarget);
+
+ let expectToggle = false;
+ const modeToggles =
+ Promise.all([inScopeTarget, inScopeSubTarget, anotherInScopeSubTarget].map(t => onModeToggle(t).then(() => {
+ assert.isTrue(expectToggle);
+ })));
+ outOfScopeTarget.model(SDK.OverlayModel.OverlayModel)
+ ?.dispatchEventToListeners(SDK.OverlayModel.Events.ExitedInspectMode);
+
+ await new Promise<void>(resolve => queueMicrotask(resolve));
+
+ expectToggle = true;
+ inScopeTarget.model(SDK.OverlayModel.OverlayModel)
+ ?.dispatchEventToListeners(SDK.OverlayModel.Events.ExitedInspectMode);
+ await modeToggles;
+ });
+});