豆豆友情提示:这是一个非官方 GitHub 代理镜像,主要用于网络测试或访问加速。请勿在此进行登录、注册或处理任何敏感信息。进行这些操作请务必访问官方网站 github.com。 Raw 内容也通过此代理提供。
Skip to content

Commit ca54db6

Browse files
finnurbrekiDevtools-frontend LUCI CQ
authored andcommitted
[GreenDev]: Add annotation indicator for the panels tab switcher.
Bug: 461428483 Change-Id: Ie0101039501847beceb391125b6f90111c02e4a1 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/7206086 Reviewed-by: Jack Franklin <jacktfranklin@chromium.org> Commit-Queue: Finnur Thorarinsson <finnur@chromium.org>
1 parent 53e6e75 commit ca54db6

File tree

6 files changed

+116
-11
lines changed

6 files changed

+116
-11
lines changed

PRESUBMIT.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
r'^front_end[\\/]third_party[\\/].*', # 3rd party code
3737
# Apple copyright
3838
r'^front_end[\\/]ui[\\/]legacy[\\/]components[\\/]data_grid[\\/]DataGrid\.ts$',
39+
r'^front_end[\\/]ui[\\/]legacy[\\/]tabbedPane\.css$', # Apple copyright
3940
r'^node_modules[\\/].*', # 3rd party code
4041
r'^scripts[\\/]build[\\/]build_inspector_overlay\.py$', # Lines too long
4142
r'^scripts[\\/]build[\\/]code_generator_frontend\.py$',

front_end/models/ai_assistance/agents/PerformanceAgent.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ const UIStringsNotTranslated = {
4747
mainThreadActivity: 'Investigating main thread activity…',
4848
} as const;
4949
const lockedString = i18n.i18n.lockedString;
50-
const annotationsEnabled = Annotations.AnnotationRepository.AnnotationRepository.annotationsEnabled();
50+
const annotationsEnabled = Annotations.AnnotationRepository.annotationsEnabled();
5151

5252
/**
5353
* WARNING: preamble defined in code is only used when userTier is
@@ -1094,15 +1094,15 @@ export class PerformanceAgent extends AiAgent<AgentFocus> {
10941094

10951095
async addElementAnnotation(elementId: string, annotationMessage: string):
10961096
Promise<FunctionCallHandlerResult<unknown>> {
1097-
if (!Annotations.AnnotationRepository.AnnotationRepository.annotationsEnabled()) {
1097+
if (!Annotations.AnnotationRepository.annotationsEnabled()) {
10981098
console.warn('Received agent request to add annotation with annotations disabled');
10991099
return {error: 'Annotations are not currently enabled'};
11001100
}
11011101

11021102
// eslint-disable-next-line no-console
11031103
console.log(`AI AGENT EVENT: Performance Agent adding annotation for element ${elementId}: '${annotationMessage}'`);
1104-
Annotations.AnnotationRepository.AnnotationRepository.instance().addAnnotationWithAnchor(
1105-
annotationMessage, elementId, Annotations.AnnotationType.AnnotationType.ELEMENT_NODE);
1104+
Annotations.AnnotationRepository.instance().addAnnotationWithAnchor(
1105+
annotationMessage, elementId, Annotations.AnnotationType.ELEMENT_NODE);
11061106
return {result: {success: true}};
11071107
}
11081108
}

front_end/ui/components/annotations/annotations.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,5 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
import * as AnnotationRepository from './AnnotationRepository.js';
6-
import * as AnnotationType from './AnnotationType.js';
7-
8-
export {
9-
AnnotationRepository,
10-
AnnotationType,
11-
};
5+
export * from './AnnotationRepository.js';
6+
export * from './AnnotationType.js';

front_end/ui/legacy/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ devtools_ui_module("ui") {
111111
"../../models/geometry:bundle",
112112
"../../models/text_utils:bundle",
113113
"../../ui/legacy/theme_support:bundle",
114+
"../components/annotations:bundle",
114115
"../components/buttons:bundle",
115116
"../components/helpers:bundle",
116117
"../components/highlighting:bundle",

front_end/ui/legacy/TabbedPane.ts

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import * as Common from '../../core/common/common.js';
1010
import * as i18n from '../../core/i18n/i18n.js';
1111
import * as Platform from '../../core/platform/platform.js';
1212
import * as Geometry from '../../models/geometry/geometry.js';
13+
import * as Annotations from '../../ui/components/annotations/annotations.js';
1314
import * as Buttons from '../../ui/components/buttons/buttons.js';
1415
import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
1516
import * as IconButton from '../components/icon_button/icon_button.js';
@@ -53,6 +54,10 @@ const UIStrings = {
5354
* @description Indicates that a tab contains a preview feature (i.e., a beta / experimental feature).
5455
*/
5556
previewFeature: 'Preview feature',
57+
/**
58+
* @description Indicates that a tab contains annotation(s).
59+
*/
60+
panelContainsAnnotation: 'This panel has one or more annotations',
5661
/**
5762
* @description Text to move a tab forwar.
5863
*/
@@ -121,6 +126,11 @@ export class TabbedPane extends Common.ObjectWrapper.eventMixin<EventTypes, type
121126
this.currentDevicePixelRatio = window.devicePixelRatio;
122127
ZoomManager.instance().addEventListener(ZoomManagerEvents.ZOOM_CHANGED, this.zoomChanged, this);
123128
this.makeTabSlider();
129+
130+
if (Annotations.AnnotationRepository.annotationsEnabled()) {
131+
Annotations.AnnotationRepository.instance().addEventListener(
132+
Annotations.Events.ANNOTATION_ADDED, this.#onAnnotationAdded, this);
133+
}
124134
}
125135

126136
setAccessibleName(name: string): void {
@@ -555,6 +565,36 @@ export class TabbedPane extends Common.ObjectWrapper.eventMixin<EventTypes, type
555565
this.performUpdate();
556566
}
557567

568+
updateTabAnnotationIcons(): void {
569+
if (!Annotations.AnnotationRepository.annotationsEnabled()) {
570+
return;
571+
}
572+
573+
const annotations = Annotations.AnnotationRepository.instance();
574+
if (!annotations) {
575+
return;
576+
}
577+
578+
for (const tab of this.tabs) {
579+
let primaryType = -1;
580+
let secondaryType = -1;
581+
switch (tab.id) {
582+
case 'elements':
583+
primaryType = Annotations.AnnotationType.ELEMENT_NODE;
584+
secondaryType = Annotations.AnnotationType.STYLE_RULE;
585+
break;
586+
case 'network':
587+
primaryType = Annotations.AnnotationType.NETWORK_REQUEST;
588+
secondaryType = Annotations.AnnotationType.NETWORK_REQUEST_SUBPANEL_HEADERS;
589+
break;
590+
}
591+
592+
const showTabAnnotationIcon = annotations.getAnnotationsByType(primaryType).length > 0 ||
593+
annotations.getAnnotationsByType(secondaryType).length > 0;
594+
this.setTabAnnotationIcon(tab.id, showTabAnnotationIcon);
595+
}
596+
}
597+
558598
override performUpdate(): void {
559599
if (!this.isShowing()) {
560600
return;
@@ -583,6 +623,7 @@ export class TabbedPane extends Common.ObjectWrapper.eventMixin<EventTypes, type
583623
this.updateWidths();
584624
this.updateTabsDropDown();
585625
this.updateTabSlider();
626+
this.updateTabAnnotationIcons();
586627
}
587628

588629
private adjustToolbarWidth(): void {
@@ -939,6 +980,17 @@ export class TabbedPane extends Common.ObjectWrapper.eventMixin<EventTypes, type
939980
this.automaticReorder = automatic;
940981
}
941982

983+
setTabAnnotationIcon(id: string, iconVisible: boolean): void {
984+
const tab = this.tabsById.get(id);
985+
if (tab) {
986+
tab.tabAnnotationIcon = iconVisible;
987+
}
988+
}
989+
990+
#onAnnotationAdded(): void {
991+
this.updateTabAnnotationIcons();
992+
}
993+
942994
private keyDown(event: KeyboardEvent): void {
943995
if (!this.currentTab) {
944996
return;
@@ -1009,6 +1061,7 @@ export interface EventTypes {
10091061
export class TabbedPaneTab {
10101062
closeable: boolean;
10111063
previewFeature = false;
1064+
#tabAnnotationIcon = false;
10121065
private readonly tabbedPane: TabbedPane;
10131066
#id: string;
10141067
#title: string;
@@ -1064,6 +1117,32 @@ export class TabbedPaneTab {
10641117
return this.#jslogContext ?? (this.#id === 'console-view' ? 'console' : this.#id);
10651118
}
10661119

1120+
get tabAnnotationIcon(): boolean {
1121+
return this.#tabAnnotationIcon;
1122+
}
1123+
1124+
set tabAnnotationIcon(iconVisible: boolean) {
1125+
if (this.#tabAnnotationIcon === iconVisible) {
1126+
return;
1127+
}
1128+
this.#tabAnnotationIcon = iconVisible;
1129+
if (!this.#tabElement) {
1130+
return;
1131+
}
1132+
const iconElement = this.#tabElement.querySelector('.ai-icon');
1133+
if (iconVisible) {
1134+
if (!iconElement) {
1135+
const closeButton = this.#tabElement.querySelector('.close-button');
1136+
this.#tabElement.insertBefore(this.createTabAnnotationIcon(), closeButton);
1137+
}
1138+
} else {
1139+
iconElement?.remove();
1140+
}
1141+
this.#tabElement.classList.toggle('ai', iconVisible);
1142+
delete this.measuredWidth;
1143+
this.tabbedPane.requestUpdate();
1144+
}
1145+
10671146
isCloseable(): boolean {
10681147
return this.closeable;
10691148
}
@@ -1204,6 +1283,12 @@ export class TabbedPaneTab {
12041283
tabElement.classList.add('preview');
12051284
}
12061285

1286+
if (this.tabAnnotationIcon) {
1287+
const tabAnnotationIcon = this.createTabAnnotationIcon();
1288+
tabElement.appendChild(tabAnnotationIcon);
1289+
tabElement.classList.add('ai');
1290+
}
1291+
12071292
if (this.closeable) {
12081293
const closeIcon = this.createCloseIconButton();
12091294
tabElement.appendChild(closeIcon);
@@ -1230,6 +1315,19 @@ export class TabbedPaneTab {
12301315
return tabElement as HTMLElement;
12311316
}
12321317

1318+
private createTabAnnotationIcon(): HTMLDivElement {
1319+
// TODO(finnur): Replace the ai-icon with the squiggly svg once it becomes available.
1320+
const iconContainer = document.createElement('div');
1321+
iconContainer.classList.add('ai-icon');
1322+
const tabAnnotationIcon = new IconButton.Icon.Icon();
1323+
tabAnnotationIcon.name = 'smart-assistant';
1324+
tabAnnotationIcon.classList.add('small');
1325+
iconContainer.appendChild(tabAnnotationIcon);
1326+
iconContainer.setAttribute('title', i18nString(UIStrings.panelContainsAnnotation));
1327+
iconContainer.setAttribute('aria-label', i18nString(UIStrings.panelContainsAnnotation));
1328+
return iconContainer;
1329+
}
1330+
12331331
private createCloseIconButton(): Buttons.Button.Button {
12341332
const closeButton = new Buttons.Button.Button();
12351333
closeButton.data = {

front_end/ui/legacy/tabbedPane.css

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,3 +520,13 @@
520520
--tabbed-pane-close-icon-color: HighlightText;
521521
}
522522
}
523+
524+
.tabbed-pane-header-tab.ai .ai-icon {
525+
background-color: var(--sys-color-primary);
526+
border-radius: 50%;
527+
margin-left: 4px;
528+
}
529+
530+
.tabbed-pane-header-tab.ai .ai-icon devtools-icon {
531+
color: var(--sys-color-on-primary);
532+
}

0 commit comments

Comments
 (0)