chrome-devtools-frontend 1.0.1611825 → 1.0.1613625
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/verification/SKILL.md +5 -1
- package/front_end/Images/src/flowsheet.svg +1 -0
- package/front_end/core/common/Color.ts +3 -2
- package/front_end/core/common/MapWithDefault.ts +2 -2
- package/front_end/core/common/Object.ts +9 -6
- package/front_end/core/platform/StringUtilities.ts +5 -0
- package/front_end/core/sdk/NetworkManager.ts +7 -0
- package/front_end/generated/InspectorBackendCommands.ts +2 -2
- package/front_end/generated/protocol.ts +12 -2
- package/front_end/models/ai_assistance/agents/README.md +77 -0
- package/front_end/models/greendev/Prototypes.ts +7 -4
- package/front_end/models/har/HARFormat.ts +30 -0
- package/front_end/models/har/Importer.ts +12 -1
- package/front_end/models/har/Log.ts +28 -0
- package/front_end/models/heap_snapshot/HeapSnapshotProxy.ts +6 -4
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +62 -22
- package/front_end/panels/ai_assistance/PatchWidget.ts +7 -23
- package/front_end/panels/ai_assistance/SelectWorkspaceDialog.ts +3 -3
- package/front_end/panels/ai_assistance/ai_assistance-meta.ts +7 -0
- package/front_end/panels/ai_assistance/ai_assistance.ts +1 -0
- package/front_end/panels/ai_assistance/components/ChatMessage.ts +13 -3
- package/front_end/panels/ai_assistance/components/ChatView.ts +4 -0
- package/front_end/panels/ai_assistance/components/ExportForAgentsDialog.ts +14 -7
- package/front_end/panels/ai_assistance/components/OptInChangeDialog.ts +179 -0
- package/front_end/panels/ai_assistance/components/WalkthroughView.ts +4 -3
- package/front_end/panels/ai_assistance/components/optInChangeDialog.css +95 -0
- package/front_end/panels/ai_assistance/components/walkthroughView.css +1 -1
- package/front_end/panels/application/CookieItemsView.ts +3 -2
- package/front_end/panels/changes/ChangesView.ts +0 -12
- package/front_end/panels/common/common.ts +0 -1
- package/front_end/panels/console/ConsolePrompt.ts +2 -2
- package/front_end/panels/elements/StylePropertyTreeElement.ts +2 -1
- package/front_end/panels/elements/StylesSidebarPane.ts +6 -2
- package/front_end/panels/elements/elements-meta.ts +14 -0
- package/front_end/panels/emulation/DeviceModeToolbar.ts +13 -4
- package/front_end/panels/network/NetworkLogView.ts +58 -28
- package/front_end/panels/profiler/HeapSnapshotDataGrids.ts +1 -1
- package/front_end/panels/profiler/HeapSnapshotGridNodes.ts +9 -17
- package/front_end/panels/protocol_monitor/JSONEditor.ts +30 -4
- package/front_end/panels/recorder/RecorderController.ts +4 -4
- package/front_end/panels/recorder/models/RecordingPlayer.ts +1 -1
- package/front_end/panels/settings/AISettingsTab.ts +53 -6
- package/front_end/panels/settings/SettingsScreen.ts +2 -2
- package/front_end/services/puppeteer/PuppeteerConnection.ts +1 -1
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/ui/kit/icons/Icon.ts +1 -0
- package/front_end/ui/legacy/SplitWidget.ts +9 -6
- package/front_end/ui/legacy/TextPrompt.ts +1 -1
- package/front_end/ui/legacy/Treeoutline.ts +3 -2
- package/front_end/ui/legacy/components/data_grid/DataGridElement.ts +4 -3
- package/front_end/ui/legacy/components/settings_ui/SettingsUI.ts +3 -3
- package/front_end/ui/legacy/components/source_frame/FontView.ts +101 -88
- package/front_end/ui/legacy/components/source_frame/SourceFrame.ts +4 -4
- package/front_end/ui/visual_logging/KnownContextValues.ts +13 -0
- package/package.json +2 -2
- package/front_end/panels/common/CopyChangesToPrompt.ts +0 -233
|
@@ -13,7 +13,6 @@ import * as i18n from '../../core/i18n/i18n.js';
|
|
|
13
13
|
import * as Platform from '../../core/platform/platform.js';
|
|
14
14
|
import * as Root from '../../core/root/root.js';
|
|
15
15
|
import * as AiAssistanceModel from '../../models/ai_assistance/ai_assistance.js';
|
|
16
|
-
import * as GreenDev from '../../models/greendev/greendev.js';
|
|
17
16
|
import * as Persistence from '../../models/persistence/persistence.js';
|
|
18
17
|
import * as Workspace from '../../models/workspace/workspace.js';
|
|
19
18
|
import * as WorkspaceDiff from '../../models/workspace_diff/workspace_diff.js';
|
|
@@ -273,20 +272,6 @@ const DEFAULT_VIEW: View = (input, output, target) => {
|
|
|
273
272
|
nothing}`;
|
|
274
273
|
}
|
|
275
274
|
|
|
276
|
-
function renderCopyPrompt(changedCode?: string): LitTemplate {
|
|
277
|
-
if (!GreenDev.Prototypes.instance().isEnabled('copyToGemini') || !changedCode) {
|
|
278
|
-
return nothing;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
// clang-format off
|
|
282
|
-
return html`<devtools-widget class="copy-to-prompt"
|
|
283
|
-
${widget(PanelCommon.CopyChangesToPrompt, {
|
|
284
|
-
workspaceDiff: input.workspaceDiff,
|
|
285
|
-
patchAgentCSSChange: changedCode,
|
|
286
|
-
})}></devtools-widget>`;
|
|
287
|
-
// clang-format on
|
|
288
|
-
}
|
|
289
|
-
|
|
290
275
|
function renderFooter(): LitTemplate {
|
|
291
276
|
if (input.savedToDisk) {
|
|
292
277
|
return nothing;
|
|
@@ -357,7 +342,6 @@ const DEFAULT_VIEW: View = (input, output, target) => {
|
|
|
357
342
|
</div>
|
|
358
343
|
` :
|
|
359
344
|
html`
|
|
360
|
-
${renderCopyPrompt(input.changeSummary)}
|
|
361
345
|
<devtools-button
|
|
362
346
|
@click=${input.onApplyToWorkspace}
|
|
363
347
|
.jslogContext=${'patch-widget.apply-to-workspace'}
|
|
@@ -435,7 +419,7 @@ export class PatchWidget extends UI.Widget.Widget {
|
|
|
435
419
|
#project?: Workspace.Workspace.Project;
|
|
436
420
|
#patchSources?: string;
|
|
437
421
|
#savedToDisk?: boolean;
|
|
438
|
-
#
|
|
422
|
+
#loggingEnabled: boolean; // Whether the enterprise setting is `ALLOW_WITHOUT_LOGGING` or not.
|
|
439
423
|
#patchSuggestionState = PatchSuggestionState.INITIAL;
|
|
440
424
|
#workspaceDiff = WorkspaceDiff.WorkspaceDiff.workspaceDiff();
|
|
441
425
|
#workspace = Workspace.Workspace.WorkspaceImpl.instance();
|
|
@@ -450,7 +434,7 @@ export class PatchWidget extends UI.Widget.Widget {
|
|
|
450
434
|
}) {
|
|
451
435
|
super(element);
|
|
452
436
|
this.#aidaClient = opts?.aidaClient ?? new Host.AidaClient.AidaClient();
|
|
453
|
-
this.#
|
|
437
|
+
this.#loggingEnabled = Root.Runtime.hostConfig.aidaAvailability?.enterprisePolicyValue !==
|
|
454
438
|
Root.Runtime.GenAiEnterprisePolicyValue.ALLOW_WITHOUT_LOGGING;
|
|
455
439
|
this.#view = view;
|
|
456
440
|
|
|
@@ -514,9 +498,9 @@ export class PatchWidget extends UI.Widget.Widget {
|
|
|
514
498
|
projectPath,
|
|
515
499
|
projectType: this.#getSelectedProjectType(projectPath),
|
|
516
500
|
savedToDisk: this.#savedToDisk,
|
|
517
|
-
applyToWorkspaceTooltipText: this.#
|
|
518
|
-
lockedString(UIStringsNotTranslate.
|
|
519
|
-
lockedString(UIStringsNotTranslate.
|
|
501
|
+
applyToWorkspaceTooltipText: this.#loggingEnabled ?
|
|
502
|
+
lockedString(UIStringsNotTranslate.applyToWorkspaceTooltip) :
|
|
503
|
+
lockedString(UIStringsNotTranslate.applyToWorkspaceTooltipNoLogging),
|
|
520
504
|
onLearnMoreTooltipClick: this.#onLearnMoreTooltipClick.bind(this),
|
|
521
505
|
onApplyToWorkspace: this.#onApplyToWorkspace.bind(this),
|
|
522
506
|
onCancel: () => {
|
|
@@ -566,8 +550,8 @@ export class PatchWidget extends UI.Widget.Widget {
|
|
|
566
550
|
},
|
|
567
551
|
{
|
|
568
552
|
iconName: 'google',
|
|
569
|
-
content: this.#
|
|
570
|
-
|
|
553
|
+
content: this.#loggingEnabled ? lockedString(UIStringsNotTranslate.freDisclaimerTextPrivacy) :
|
|
554
|
+
lockedString(UIStringsNotTranslate.freDisclaimerTextPrivacyNoLogging),
|
|
571
555
|
},
|
|
572
556
|
{
|
|
573
557
|
iconName: 'warning',
|
|
@@ -233,14 +233,14 @@ export class SelectWorkspaceDialog extends UI.Widget.VBox {
|
|
|
233
233
|
}
|
|
234
234
|
|
|
235
235
|
override performUpdate(): void {
|
|
236
|
-
const
|
|
236
|
+
const loggingEnabled = Root.Runtime.hostConfig.aidaAvailability?.enterprisePolicyValue !==
|
|
237
237
|
Root.Runtime.GenAiEnterprisePolicyValue.ALLOW_WITHOUT_LOGGING;
|
|
238
238
|
|
|
239
239
|
const viewInput = {
|
|
240
240
|
folders: this.#folders,
|
|
241
241
|
selectedIndex: this.#selectedIndex,
|
|
242
|
-
selectProjectRootText:
|
|
243
|
-
|
|
242
|
+
selectProjectRootText: loggingEnabled ? lockedString(UIStringsNotTranslate.selectProjectRoot) :
|
|
243
|
+
lockedString(UIStringsNotTranslate.selectProjectRootNoLogging),
|
|
244
244
|
showAutomaticWorkspaceNudge: this.#automaticFileSystemManager.automaticFileSystem === null &&
|
|
245
245
|
this.#automaticFileSystemManager.availability === 'available',
|
|
246
246
|
onProjectSelected: (index: number) => {
|
|
@@ -161,6 +161,13 @@ Common.Settings.registerSettingExtension({
|
|
|
161
161
|
},
|
|
162
162
|
});
|
|
163
163
|
|
|
164
|
+
Common.Settings.registerSettingExtension({
|
|
165
|
+
category: Common.Settings.SettingCategory.AI,
|
|
166
|
+
settingName: 'ai-assistance-v2-opt-in-change-dialog-seen',
|
|
167
|
+
settingType: Common.Settings.SettingType.BOOLEAN,
|
|
168
|
+
defaultValue: false,
|
|
169
|
+
});
|
|
170
|
+
|
|
164
171
|
UI.ActionRegistration.registerActionExtension({
|
|
165
172
|
actionId: 'freestyler.main-menu',
|
|
166
173
|
contextTypes(): [] {
|
|
@@ -11,6 +11,7 @@ export * from './SelectWorkspaceDialog.js';
|
|
|
11
11
|
export * as ChatMessage from './components/ChatMessage.js';
|
|
12
12
|
export * as ExploreWidget from './components/ExploreWidget.js';
|
|
13
13
|
export * as ExportForAgentsDialog from './components/ExportForAgentsDialog.js';
|
|
14
|
+
export * as OptInChangeDialog from './components/OptInChangeDialog.js';
|
|
14
15
|
export * as PatchWidget from './PatchWidget.js';
|
|
15
16
|
export * as DisabledWidget from './components/DisabledWidget.js';
|
|
16
17
|
export * as WalkthroughView from './components/WalkthroughView.js';
|
|
@@ -729,7 +729,7 @@ export function renderStep({step, isLoading, markdownRenderer, isLast}: {
|
|
|
729
729
|
// clang-format off
|
|
730
730
|
return html`
|
|
731
731
|
<details class=${stepClasses}
|
|
732
|
-
jslog=${VisualLogging.
|
|
732
|
+
jslog=${VisualLogging.expand('step').track({click: true})}
|
|
733
733
|
.open=${Boolean(step.requestApproval)}>
|
|
734
734
|
<summary>
|
|
735
735
|
<div class="summary">
|
|
@@ -755,6 +755,7 @@ interface WidgetMakerResponse {
|
|
|
755
755
|
customRevealTitle?: Platform.UIString.LocalizedString;
|
|
756
756
|
// Can be null if the widget is only used to add the Reveal CTA.
|
|
757
757
|
title: Lit.LitTemplate|Platform.UIString.LocalizedString|null;
|
|
758
|
+
jslogContext?: string;
|
|
758
759
|
}
|
|
759
760
|
|
|
760
761
|
const nodeCache = new Map<Protocol.DOM.BackendNodeId, SDK.DOMModel.DOMNode>();
|
|
@@ -823,6 +824,7 @@ async function makeComputedStyleWidget(widgetData: ComputedStyleAiWidget): Promi
|
|
|
823
824
|
</span>
|
|
824
825
|
</span>`,
|
|
825
826
|
// clang-format on
|
|
827
|
+
jslogContext: 'computed-styles',
|
|
826
828
|
};
|
|
827
829
|
}
|
|
828
830
|
|
|
@@ -836,6 +838,7 @@ async function makeCoreWebVitalsWidget(widgetData: CoreVitalsAiWidget): Promise<
|
|
|
836
838
|
renderedWidget,
|
|
837
839
|
revealable: new TimelineUtils.Helpers.RevealableCoreVitals(widgetData.data.insightSetKey),
|
|
838
840
|
title: lockedString(UIStringsNotTranslate.coreVitals),
|
|
841
|
+
jslogContext: 'core-web-vitals',
|
|
839
842
|
};
|
|
840
843
|
}
|
|
841
844
|
|
|
@@ -872,6 +875,7 @@ async function makeStylePropertiesWidget(widgetData: StylePropertiesAiWidget): P
|
|
|
872
875
|
node: domNodeForId,
|
|
873
876
|
})}
|
|
874
877
|
></devtools-widget>`,
|
|
878
|
+
jslogContext: 'standalone-styles',
|
|
875
879
|
};
|
|
876
880
|
}
|
|
877
881
|
|
|
@@ -894,6 +898,7 @@ async function makeLcpBreakdownWidget(widgetData: LcpBreakdownAiWidget): Promise
|
|
|
894
898
|
renderedWidget,
|
|
895
899
|
revealable: new TimelineUtils.Helpers.RevealableInsight(insight),
|
|
896
900
|
title: lockedString(UIStringsNotTranslate.lcpBreakdown),
|
|
901
|
+
jslogContext: 'lcp-breakdown',
|
|
897
902
|
};
|
|
898
903
|
}
|
|
899
904
|
|
|
@@ -922,7 +927,8 @@ async function makeBottomUpTimelineTreeWidget(widgetData: BottomUpTreeAiWidget):
|
|
|
922
927
|
return {
|
|
923
928
|
renderedWidget,
|
|
924
929
|
revealable: new TimelineUtils.Helpers.RevealableBottomUpProfile(widgetData.data.bounds),
|
|
925
|
-
title: lockedString(UIStringsNotTranslate.bottomUpTree)
|
|
930
|
+
title: lockedString(UIStringsNotTranslate.bottomUpTree),
|
|
931
|
+
jslogContext: 'bottom-up',
|
|
926
932
|
};
|
|
927
933
|
}
|
|
928
934
|
|
|
@@ -947,6 +953,7 @@ function renderWidgetResponse(response: WidgetMakerResponse|null): Lit.LitTempla
|
|
|
947
953
|
<devtools-button class="widget-reveal-button"
|
|
948
954
|
.variant=${Buttons.Button.Variant.TEXT}
|
|
949
955
|
.accessibleLabel=${lockedString(UIStringsNotTranslate.reveal)}
|
|
956
|
+
.jslogContext=${'reveal'}
|
|
950
957
|
@click=${onReveal}
|
|
951
958
|
>
|
|
952
959
|
${response.customRevealTitle ?? lockedString(UIStringsNotTranslate.reveal)}
|
|
@@ -956,7 +963,7 @@ function renderWidgetResponse(response: WidgetMakerResponse|null): Lit.LitTempla
|
|
|
956
963
|
|
|
957
964
|
// clang-format off
|
|
958
965
|
return html`
|
|
959
|
-
<div class=${classes}>
|
|
966
|
+
<div class=${classes} jslog=${ifDefined(response.jslogContext ? VisualLogging.section(response.jslogContext) : undefined)}>
|
|
960
967
|
${response.title ? html`
|
|
961
968
|
<div class="widget-header">
|
|
962
969
|
<h3 class="widget-name">${response.title}</h3>
|
|
@@ -986,6 +993,7 @@ async function makePerformanceTraceWidget(widgetData: PerformanceTraceAiWidget):
|
|
|
986
993
|
title: null,
|
|
987
994
|
revealable: new Timeline.TimelinePanel.ParsedTraceRevealable(widgetData.data.parsedTrace),
|
|
988
995
|
customRevealTitle: lockedString(UIStringsNotTranslate.revealTrace),
|
|
996
|
+
jslogContext: 'performance-trace',
|
|
989
997
|
};
|
|
990
998
|
}
|
|
991
999
|
|
|
@@ -1045,6 +1053,7 @@ async function makeDomTreeWidget(widgetData: DomTreeAiWidget): Promise<WidgetMak
|
|
|
1045
1053
|
renderedWidget,
|
|
1046
1054
|
revealable: new SDK.DOMModel.DeferredDOMNode(root.domModel().target(), root.backendNodeId()),
|
|
1047
1055
|
title: lockedString(UIStringsNotTranslate.lcpElement),
|
|
1056
|
+
jslogContext: 'dom-snapshot',
|
|
1048
1057
|
};
|
|
1049
1058
|
}
|
|
1050
1059
|
|
|
@@ -1607,5 +1616,6 @@ async function makeTimelineRangeSummaryWidget(widgetData: TimelineRangeSummaryAi
|
|
|
1607
1616
|
renderedWidget: template,
|
|
1608
1617
|
revealable: new TimelineUtils.Helpers.RevealableTimeRange(bounds),
|
|
1609
1618
|
title: lockedString(UIStringsNotTranslate.performanceSummary),
|
|
1619
|
+
jslogContext: 'timeline-range-summary',
|
|
1610
1620
|
};
|
|
1611
1621
|
}
|
|
@@ -282,6 +282,10 @@ export class ChatView extends HTMLElement {
|
|
|
282
282
|
textArea.focus();
|
|
283
283
|
}
|
|
284
284
|
|
|
285
|
+
setInputValue(text: string): void {
|
|
286
|
+
this.#output.input?.getWidget()?.setInputValue(text);
|
|
287
|
+
}
|
|
288
|
+
|
|
285
289
|
restoreScrollPosition(): void {
|
|
286
290
|
if (this.#scrollTop === undefined) {
|
|
287
291
|
return;
|
|
@@ -10,6 +10,7 @@ import * as Buttons from '../../../ui/components/buttons/buttons.js';
|
|
|
10
10
|
import * as Snackbars from '../../../ui/components/snackbars/snackbars.js';
|
|
11
11
|
import * as UI from '../../../ui/legacy/legacy.js';
|
|
12
12
|
import * as Lit from '../../../ui/lit/lit.js';
|
|
13
|
+
import * as VisualLogging from '../../../ui/visual_logging/visual_logging.js';
|
|
13
14
|
|
|
14
15
|
import styles from './exportForAgentsDialog.css.js';
|
|
15
16
|
|
|
@@ -59,6 +60,8 @@ export const enum StateType {
|
|
|
59
60
|
CONVERSATION = 'conversation',
|
|
60
61
|
}
|
|
61
62
|
|
|
63
|
+
const DEFAULT_STATE_TYPE = StateType.PROMPT;
|
|
64
|
+
|
|
62
65
|
export interface State {
|
|
63
66
|
activeType: StateType;
|
|
64
67
|
promptText: string;
|
|
@@ -78,14 +81,12 @@ type View = (input: ViewInput, output: undefined, target: HTMLElement) => void;
|
|
|
78
81
|
export const DEFAULT_VIEW: View = (input, _output, target): void => {
|
|
79
82
|
const isPrompt = input.state.activeType === StateType.PROMPT;
|
|
80
83
|
const buttonText = isPrompt ? i18nString(UIStrings.copyToClipboard) : i18nString(UIStrings.saveAsMarkdown);
|
|
81
|
-
const exportText = isPrompt
|
|
82
|
-
i18nString(UIStrings.generatingSummary) :
|
|
83
|
-
(isPrompt ? input.state.promptText : input.state.conversationText);
|
|
84
|
+
const exportText = isPrompt ? input.state.promptText : input.state.conversationText;
|
|
84
85
|
// clang-format off
|
|
85
86
|
|
|
86
87
|
render(html`
|
|
87
88
|
<style>${styles}</style>
|
|
88
|
-
<div class="export-for-agents-dialog">
|
|
89
|
+
<div class="export-for-agents-dialog" jslog=${VisualLogging.dialog('ai-export-for-agents')}>
|
|
89
90
|
<header>
|
|
90
91
|
<h1 id="export-for-agents-dialog-title" tabindex="-1">
|
|
91
92
|
${i18nString(UIStrings.exportForAgents)}
|
|
@@ -116,13 +117,13 @@ export const DEFAULT_VIEW: View = (input, _output, target): void => {
|
|
|
116
117
|
</label>
|
|
117
118
|
</div>
|
|
118
119
|
<main>
|
|
119
|
-
${input.state.isPromptLoading ? html`
|
|
120
|
+
${isPrompt && input.state.isPromptLoading ? html`
|
|
120
121
|
<span class="prompt-loading">
|
|
121
122
|
<devtools-spinner></devtools-spinner>
|
|
122
123
|
${i18nString(UIStrings.generatingSummary)}
|
|
123
124
|
</span>
|
|
124
125
|
` : Lit.nothing}
|
|
125
|
-
<textarea readonly .value=${input.state.isPromptLoading ? '' : exportText}></textarea>
|
|
126
|
+
<textarea readonly .value=${isPrompt && input.state.isPromptLoading ? '' : exportText}></textarea>
|
|
126
127
|
</main>
|
|
127
128
|
<div class="disclaimer">${i18nString(UIStrings.disclaimer)}</div>
|
|
128
129
|
<footer>
|
|
@@ -144,6 +145,7 @@ export const DEFAULT_VIEW: View = (input, _output, target): void => {
|
|
|
144
145
|
};
|
|
145
146
|
|
|
146
147
|
export class ExportForAgentsDialog extends UI.Widget.VBox {
|
|
148
|
+
static #lastSelectedType: StateType = DEFAULT_STATE_TYPE;
|
|
147
149
|
readonly #view: View;
|
|
148
150
|
readonly #dialog: UI.Dialog.Dialog;
|
|
149
151
|
#state: State;
|
|
@@ -160,7 +162,7 @@ export class ExportForAgentsDialog extends UI.Widget.VBox {
|
|
|
160
162
|
super();
|
|
161
163
|
this.#dialog = options.dialog;
|
|
162
164
|
this.#state = {
|
|
163
|
-
activeType:
|
|
165
|
+
activeType: ExportForAgentsDialog.#lastSelectedType,
|
|
164
166
|
promptText: typeof options.promptText === 'string' ? options.promptText : '',
|
|
165
167
|
conversationText: options.markdownText,
|
|
166
168
|
isPromptLoading: typeof options.promptText !== 'string',
|
|
@@ -179,8 +181,13 @@ export class ExportForAgentsDialog extends UI.Widget.VBox {
|
|
|
179
181
|
this.requestUpdate();
|
|
180
182
|
}
|
|
181
183
|
|
|
184
|
+
static clearPersistedViewState(): void {
|
|
185
|
+
ExportForAgentsDialog.#lastSelectedType = DEFAULT_STATE_TYPE;
|
|
186
|
+
}
|
|
187
|
+
|
|
182
188
|
#onStateChange = (newState: StateType): void => {
|
|
183
189
|
this.#state.activeType = newState;
|
|
190
|
+
ExportForAgentsDialog.#lastSelectedType = newState;
|
|
184
191
|
this.requestUpdate();
|
|
185
192
|
};
|
|
186
193
|
|
|
@@ -0,0 +1,179 @@
|
|
|
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 i18n from '../../../core/i18n/i18n.js';
|
|
6
|
+
import * as Root from '../../../core/root/root.js';
|
|
7
|
+
import * as Buttons from '../../../ui/components/buttons/buttons.js';
|
|
8
|
+
import * as UI from '../../../ui/legacy/legacy.js';
|
|
9
|
+
import * as Lit from '../../../ui/lit/lit.js';
|
|
10
|
+
import * as VisualLogging from '../../../ui/visual_logging/visual_logging.js';
|
|
11
|
+
|
|
12
|
+
import styles from './optInChangeDialog.css.js';
|
|
13
|
+
|
|
14
|
+
const {html, render} = Lit;
|
|
15
|
+
|
|
16
|
+
const UIStrings = {
|
|
17
|
+
/**
|
|
18
|
+
* @description Title for the opt-in change dialog.
|
|
19
|
+
*/
|
|
20
|
+
title: 'AI assistance just got better',
|
|
21
|
+
/**
|
|
22
|
+
* @description First point in the opt-in change dialog, describing the new integration.
|
|
23
|
+
*/
|
|
24
|
+
integrationPoint:
|
|
25
|
+
'AI assistance is now integrated with Application and Lighthouse panels, and pulls context from data sources simultaneously',
|
|
26
|
+
/**
|
|
27
|
+
* @description Second point in the opt-in change dialog, describing the new widgets.
|
|
28
|
+
*/
|
|
29
|
+
widgetPoint: 'Use widgets to verify results or jump to source data for select debugging cases',
|
|
30
|
+
/**
|
|
31
|
+
* @description Third point in the opt-in change dialog (disclaimer) for regular users.
|
|
32
|
+
*/
|
|
33
|
+
privacyDisclaimer:
|
|
34
|
+
'Chat messages, data accessible for this site via DevTools panels and Web APIs, and items you select such as network requests, files, and performance traces are sent to Google and may be seen by human reviewers to improve this feature. This is an experimental AI feature and won’t always get it right.',
|
|
35
|
+
/**
|
|
36
|
+
* @description Third point in the opt-in change dialog (disclaimer) for enterprise users with logging disabled.
|
|
37
|
+
*/
|
|
38
|
+
privacyDisclaimerEnterpriseNoLogging:
|
|
39
|
+
'Chat messages, data accessible for this site via DevTools panels and Web APIs, and items you select such as network requests, files, and performance traces are sent to Google. The content submitted to and generated by this feature will not be used to improve Google’s AI models. This is an experimental AI feature and won’t always get it right.',
|
|
40
|
+
/**
|
|
41
|
+
* @description Button text for managing settings.
|
|
42
|
+
*/
|
|
43
|
+
manageSettings: 'Manage in settings',
|
|
44
|
+
/**
|
|
45
|
+
* @description Button text for acknowledging the changes.
|
|
46
|
+
*/
|
|
47
|
+
gotIt: 'Got it',
|
|
48
|
+
} as const;
|
|
49
|
+
|
|
50
|
+
const str_ = i18n.i18n.registerUIStrings('panels/ai_assistance/components/OptInChangeDialog.ts', UIStrings);
|
|
51
|
+
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
52
|
+
|
|
53
|
+
interface ViewInput {
|
|
54
|
+
onGotIt: () => void;
|
|
55
|
+
onManageSettings: () => void;
|
|
56
|
+
loggingEnabled: boolean;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
type View = (input: ViewInput, output: undefined, target: HTMLElement) => void;
|
|
60
|
+
|
|
61
|
+
export const DEFAULT_VIEW: View = (input, _output, target): void => {
|
|
62
|
+
const disclaimer = input.loggingEnabled ? i18nString(UIStrings.privacyDisclaimer) :
|
|
63
|
+
i18nString(UIStrings.privacyDisclaimerEnterpriseNoLogging);
|
|
64
|
+
// clang-format off
|
|
65
|
+
render(html`
|
|
66
|
+
<style>${styles}</style>
|
|
67
|
+
<div class="opt-in-change-dialog" jslog=${VisualLogging.dialog('ai-v2-opt-in-change-dialog')}>
|
|
68
|
+
<header>
|
|
69
|
+
<div class="header-icon-container">
|
|
70
|
+
<devtools-icon name="smart-assistant" role="presentation"></devtools-icon>
|
|
71
|
+
</div>
|
|
72
|
+
<h1 tabindex="-1">
|
|
73
|
+
${i18nString(UIStrings.title)}
|
|
74
|
+
</h1>
|
|
75
|
+
</header>
|
|
76
|
+
<main>
|
|
77
|
+
<div class="item">
|
|
78
|
+
<devtools-icon name="lightbulb-spark" role="presentation"></devtools-icon>
|
|
79
|
+
<div class="text">${i18nString(UIStrings.integrationPoint)}</div>
|
|
80
|
+
</div>
|
|
81
|
+
<div class="item">
|
|
82
|
+
<devtools-icon name="flowsheet" role="presentation"></devtools-icon>
|
|
83
|
+
<div class="text">${i18nString(UIStrings.widgetPoint)}</div>
|
|
84
|
+
</div>
|
|
85
|
+
<div class="item">
|
|
86
|
+
<devtools-icon name="google" role="presentation"></devtools-icon>
|
|
87
|
+
<div class="text">${disclaimer}</div>
|
|
88
|
+
</div>
|
|
89
|
+
</main>
|
|
90
|
+
<footer>
|
|
91
|
+
<div class="right-buttons">
|
|
92
|
+
<devtools-button
|
|
93
|
+
@click=${input.onManageSettings}
|
|
94
|
+
.jslogContext=${'ai-assistance-v2-opt-in.manage-settings'}
|
|
95
|
+
.variant=${Buttons.Button.Variant.OUTLINED}
|
|
96
|
+
.accessibleLabel=${i18nString(UIStrings.manageSettings)}
|
|
97
|
+
>
|
|
98
|
+
${i18nString(UIStrings.manageSettings)}
|
|
99
|
+
</devtools-button>
|
|
100
|
+
<devtools-button
|
|
101
|
+
@click=${input.onGotIt}
|
|
102
|
+
.jslogContext=${'ai-assistance-v2-opt-in.got-it'}
|
|
103
|
+
.variant=${Buttons.Button.Variant.PRIMARY}
|
|
104
|
+
.accessibleLabel=${i18nString(UIStrings.gotIt)}
|
|
105
|
+
>
|
|
106
|
+
${i18nString(UIStrings.gotIt)}
|
|
107
|
+
</devtools-button>
|
|
108
|
+
</div>
|
|
109
|
+
</footer>
|
|
110
|
+
</div>
|
|
111
|
+
`, target);
|
|
112
|
+
// clang-format on
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
export class OptInChangeDialog extends UI.Widget.VBox {
|
|
116
|
+
readonly #view: View;
|
|
117
|
+
readonly #onGotIt: () => void;
|
|
118
|
+
readonly #onManageSettings: () => void;
|
|
119
|
+
|
|
120
|
+
constructor(
|
|
121
|
+
options: {
|
|
122
|
+
onGotIt: () => void,
|
|
123
|
+
onManageSettings: () => void,
|
|
124
|
+
},
|
|
125
|
+
view: View = DEFAULT_VIEW) {
|
|
126
|
+
super();
|
|
127
|
+
this.#onGotIt = options.onGotIt;
|
|
128
|
+
this.#onManageSettings = options.onManageSettings;
|
|
129
|
+
this.#view = view;
|
|
130
|
+
|
|
131
|
+
this.requestUpdate();
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
override performUpdate(): void {
|
|
135
|
+
const loggingEnabled = Root.Runtime.hostConfig.aidaAvailability?.enterprisePolicyValue !==
|
|
136
|
+
Root.Runtime.GenAiEnterprisePolicyValue.ALLOW_WITHOUT_LOGGING;
|
|
137
|
+
|
|
138
|
+
const viewInput = {
|
|
139
|
+
onGotIt: this.#onGotIt,
|
|
140
|
+
onManageSettings: this.#onManageSettings,
|
|
141
|
+
loggingEnabled,
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
this.#view(viewInput, undefined, this.contentElement);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
focusTitle(): void {
|
|
148
|
+
this.contentElement.querySelector('h1')?.focus();
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
static show(options: {
|
|
152
|
+
onGotIt: () => void,
|
|
153
|
+
onManageSettings: () => void,
|
|
154
|
+
}): void {
|
|
155
|
+
const dialog = new UI.Dialog.Dialog();
|
|
156
|
+
dialog.setAriaLabel(i18nString(UIStrings.title));
|
|
157
|
+
dialog.setOutsideClickCallback(event => event.consume(true));
|
|
158
|
+
dialog.setCloseOnEscape(false);
|
|
159
|
+
dialog.setSizeBehavior(UI.GlassPane.SizeBehavior.MEASURE_CONTENT);
|
|
160
|
+
dialog.setDimmed(true);
|
|
161
|
+
|
|
162
|
+
const optInChangeDialog = new OptInChangeDialog({
|
|
163
|
+
onGotIt: () => {
|
|
164
|
+
dialog.hide();
|
|
165
|
+
options.onGotIt();
|
|
166
|
+
},
|
|
167
|
+
onManageSettings: () => {
|
|
168
|
+
dialog.hide();
|
|
169
|
+
options.onManageSettings();
|
|
170
|
+
},
|
|
171
|
+
});
|
|
172
|
+
optInChangeDialog.show(dialog.contentElement);
|
|
173
|
+
|
|
174
|
+
void optInChangeDialog.updateComplete.then(() => {
|
|
175
|
+
dialog.show();
|
|
176
|
+
optInChangeDialog.focusTitle();
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|
|
@@ -9,6 +9,7 @@ import * as Input from '../../../ui/components/input/input.js';
|
|
|
9
9
|
import type {MarkdownLitRenderer} from '../../../ui/components/markdown_view/MarkdownView.js';
|
|
10
10
|
import * as UI from '../../../ui/legacy/legacy.js';
|
|
11
11
|
import * as Lit from '../../../ui/lit/lit.js';
|
|
12
|
+
import * as VisualLogging from '../../../ui/visual_logging/visual_logging.js';
|
|
12
13
|
|
|
13
14
|
import chatMessageStyles from './chatMessage.css.js';
|
|
14
15
|
import {type ModelChatMessage, renderStep, type Step, titleForStep} from './ChatMessage.js';
|
|
@@ -119,14 +120,14 @@ function renderInlineWalkthrough(input: ViewInput, stepsOutput: Lit.LitTemplate,
|
|
|
119
120
|
|
|
120
121
|
// clang-format off
|
|
121
122
|
return html`
|
|
122
|
-
<div class="inline-wrapper" ?data-open=${input.isExpanded}>
|
|
123
|
+
<div class="inline-wrapper" ?data-open=${input.isExpanded} jslog=${VisualLogging.section('walkthrough-container')}>
|
|
123
124
|
<span class="inline-icon">
|
|
124
125
|
${input.isLoading ?
|
|
125
126
|
html`<devtools-spinner aria-label=${lockedString(UIStrings.inProgress)}></devtools-spinner>` :
|
|
126
127
|
html`<devtools-icon name=${icon}></devtools-icon>`
|
|
127
128
|
}
|
|
128
129
|
</span>
|
|
129
|
-
<details class="walkthrough-inline" ?open=${input.isExpanded} @toggle=${onToggle}>
|
|
130
|
+
<details class="walkthrough-inline" ?open=${input.isExpanded} @toggle=${onToggle} jslog=${VisualLogging.expand('walkthrough').track({click: true})}>
|
|
130
131
|
<summary ?data-has-widgets=${!input.isLoading && hasWidgets}>
|
|
131
132
|
<span class="walkthrough-inline-title">
|
|
132
133
|
${input.isExpanded ?
|
|
@@ -151,7 +152,7 @@ function renderSidebarWalkthrough(input: ViewInput, stepsOutput: Lit.LitTemplate
|
|
|
151
152
|
|
|
152
153
|
// clang-format off
|
|
153
154
|
return html`
|
|
154
|
-
<div class="walkthrough-view">
|
|
155
|
+
<div class="walkthrough-view" jslog=${VisualLogging.section('walkthrough-container')}>
|
|
155
156
|
<div class="walkthrough-header">
|
|
156
157
|
<h2 class="walkthrough-title">${i18nString(UIStrings.title)}</h2>
|
|
157
158
|
<devtools-button
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 The Chromium Authors
|
|
3
|
+
* Use of this source code is governed by a BSD-style license that can be
|
|
4
|
+
* found in the LICENSE file.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
@scope to (devtools-widget > *) {
|
|
8
|
+
:scope {
|
|
9
|
+
width: 100%;
|
|
10
|
+
box-shadow: none;
|
|
11
|
+
padding: var(--sys-size-8);
|
|
12
|
+
background-color: var(--sys-color-surface);
|
|
13
|
+
border-radius: var(--sys-shape-corner-medium);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.opt-in-change-dialog {
|
|
17
|
+
width: var(--sys-size-33);
|
|
18
|
+
max-width: 100%;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
header {
|
|
22
|
+
display: flex;
|
|
23
|
+
flex-direction: row;
|
|
24
|
+
align-items: center;
|
|
25
|
+
gap: var(--sys-size-8);
|
|
26
|
+
margin-bottom: var(--sys-size-8);
|
|
27
|
+
|
|
28
|
+
h2 {
|
|
29
|
+
margin: 0;
|
|
30
|
+
color: var(--sys-color-on-surface);
|
|
31
|
+
font: var(--sys-typescale-headline5);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.header-icon-container {
|
|
35
|
+
background: linear-gradient(
|
|
36
|
+
135deg,
|
|
37
|
+
var(--sys-color-gradient-primary),
|
|
38
|
+
var(--sys-color-gradient-tertiary)
|
|
39
|
+
);
|
|
40
|
+
border-radius: var(--sys-size-4);
|
|
41
|
+
height: var(--sys-size-14);
|
|
42
|
+
width: var(--sys-size-14);
|
|
43
|
+
display: flex;
|
|
44
|
+
align-items: center;
|
|
45
|
+
justify-content: center;
|
|
46
|
+
|
|
47
|
+
devtools-icon {
|
|
48
|
+
width: var(--sys-size-9);
|
|
49
|
+
height: var(--sys-size-9);
|
|
50
|
+
color: var(--sys-color-on-primary);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
main {
|
|
56
|
+
background-color: var(--sys-color-surface4);
|
|
57
|
+
border-radius: var(--sys-shape-corner-medium-small);
|
|
58
|
+
padding: var(--sys-size-8);
|
|
59
|
+
display: flex;
|
|
60
|
+
flex-direction: column;
|
|
61
|
+
gap: var(--sys-size-6);
|
|
62
|
+
margin-bottom: var(--sys-size-8);
|
|
63
|
+
|
|
64
|
+
.item {
|
|
65
|
+
display: flex;
|
|
66
|
+
flex-direction: row;
|
|
67
|
+
align-items: center;
|
|
68
|
+
gap: var(--sys-size-8);
|
|
69
|
+
|
|
70
|
+
devtools-icon {
|
|
71
|
+
width: var(--sys-size-8);
|
|
72
|
+
height: var(--sys-size-8);
|
|
73
|
+
flex-shrink: 0;
|
|
74
|
+
color: var(--sys-color-on-surface-subtle);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.text {
|
|
78
|
+
font: var(--sys-typescale-body4);
|
|
79
|
+
color: var(--sys-color-on-surface);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
footer {
|
|
85
|
+
display: flex;
|
|
86
|
+
flex-direction: row;
|
|
87
|
+
align-items: center;
|
|
88
|
+
justify-content: flex-end;
|
|
89
|
+
|
|
90
|
+
.right-buttons {
|
|
91
|
+
display: flex;
|
|
92
|
+
gap: var(--sys-size-5);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -375,9 +375,10 @@ export class CookieItemsView extends UI.Widget.VBox {
|
|
|
375
375
|
}
|
|
376
376
|
|
|
377
377
|
deleteSelectedItem(): void {
|
|
378
|
-
|
|
378
|
+
const cookie = this.selectedCookie;
|
|
379
|
+
if (cookie) {
|
|
379
380
|
this.showPreview(null);
|
|
380
|
-
void this.model.deleteCookie(
|
|
381
|
+
void this.model.deleteCookie(cookie);
|
|
381
382
|
}
|
|
382
383
|
}
|
|
383
384
|
|