chrome-devtools-frontend 1.0.1602543 → 1.0.1604514
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/version-control/SKILL.md +17 -2
- package/front_end/core/host/AidaClient.ts +39 -462
- package/front_end/core/host/AidaClientTypes.ts +470 -0
- package/front_end/core/host/AidaGcaTranslation.ts +225 -122
- package/front_end/core/host/GcaTypes.ts +107 -155
- package/front_end/core/protocol_client/DevToolsCDPConnection.ts +1 -1
- package/front_end/core/sdk/DOMModel.ts +24 -22
- package/front_end/core/sdk/EmulationModel.ts +21 -23
- package/front_end/core/sdk/HeapProfilerModel.ts +4 -7
- package/front_end/core/sdk/NetworkManager.ts +35 -28
- package/front_end/core/sdk/OverlayModel.ts +23 -23
- package/front_end/core/sdk/OverlayPersistentHighlighter.ts +13 -10
- package/front_end/core/sdk/PreloadingModel.ts +3 -4
- package/front_end/core/sdk/RuntimeModel.ts +5 -5
- package/front_end/core/sdk/ServiceWorkerManager.ts +6 -5
- package/front_end/core/sdk/SourceMapScopesInfo.ts +93 -63
- package/front_end/core/sdk/TargetManager.ts +5 -0
- package/front_end/core/sdk/WebMCPModel.ts +6 -0
- package/front_end/entrypoints/formatter_worker/FormatterWorker.ts +1 -3
- package/front_end/entrypoints/heap_snapshot_worker/AllocationProfile.ts +22 -48
- package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshot.ts +1 -1
- package/front_end/generated/InspectorBackendCommands.ts +7 -0
- package/front_end/generated/SupportedCSSProperties.js +68 -2
- package/front_end/generated/protocol-mapping.d.ts +15 -0
- package/front_end/generated/protocol-proxy-api.d.ts +24 -0
- package/front_end/generated/protocol.ts +79 -0
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +16 -5
- package/front_end/models/ai_assistance/data_formatters/LighthouseFormatter.snapshot.txt +60 -9
- package/front_end/models/ai_assistance/data_formatters/LighthouseFormatter.ts +71 -15
- package/front_end/models/bindings/TempFile.ts +1 -4
- package/front_end/models/extensions/ExtensionAPI.ts +1 -1
- package/front_end/models/heap_snapshot_model/HeapSnapshotModel.ts +34 -47
- package/front_end/models/javascript_metadata/NativeFunctions.js +12 -8
- package/front_end/models/lighthouse/LighthouseReporterTypes.ts +10 -8
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +91 -21
- package/front_end/panels/ai_assistance/components/ChatMessage.ts +90 -32
- package/front_end/panels/ai_assistance/components/ChatView.ts +3 -2
- package/front_end/panels/ai_assistance/components/WalkthroughView.ts +65 -17
- package/front_end/panels/ai_assistance/components/chatMessage.css +33 -7
- package/front_end/panels/ai_assistance/components/walkthroughView.css +35 -5
- package/front_end/panels/common/ThrottlingUtils.ts +46 -0
- package/front_end/panels/common/common.ts +1 -0
- package/front_end/panels/elements/ComputedStyleWidget.ts +11 -1
- package/front_end/panels/elements/ElementsTreeElement.ts +91 -13
- package/front_end/panels/elements/StandaloneStylesContainer.ts +0 -3
- package/front_end/panels/elements/StylePropertiesSection.ts +0 -49
- package/front_end/panels/elements/StylesContainer.ts +0 -1
- package/front_end/panels/elements/StylesSidebarPane.ts +32 -7
- package/front_end/panels/elements/elementsTreeOutline.css +18 -0
- package/front_end/panels/mobile_throttling/NetworkThrottlingSelector.ts +14 -0
- package/front_end/panels/profiler/HeapSnapshotDataGrids.ts +15 -19
- package/front_end/panels/profiler/HeapSnapshotGridNodes.ts +4 -2
- package/front_end/panels/profiler/HeapSnapshotProxy.ts +12 -16
- package/front_end/panels/profiler/HeapSnapshotView.ts +3 -10
- package/front_end/panels/profiler/ProfileView.ts +0 -9
- package/front_end/panels/profiler/ProfilesPanel.ts +5 -7
- package/front_end/panels/sensors/SensorsView.ts +0 -2
- package/front_end/panels/settings/keybindsSettingsTab.css +25 -31
- package/front_end/panels/timeline/ThirdPartyTreeView.ts +8 -0
- package/front_end/panels/timeline/TimelinePanel.ts +15 -5
- package/front_end/panels/timeline/components/FieldSettingsDialog.ts +5 -9
- package/front_end/panels/timeline/components/LiveMetricsView.ts +36 -65
- package/front_end/panels/timeline/components/OriginMap.ts +176 -159
- package/front_end/panels/timeline/components/liveMetricsView.css +4 -0
- package/front_end/panels/timeline/components/originMap.css +4 -51
- package/front_end/panels/timeline/thirdPartyTreeView.css +6 -0
- package/front_end/panels/timeline/timeline-meta.ts +11 -0
- package/front_end/panels/timeline/utils/Helpers.ts +5 -25
- package/front_end/third_party/acorn/README.chromium +1 -0
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/ui/components/{list → lists}/List.ts +1 -1
- package/front_end/ui/components/{list → lists}/list.css +0 -1
- package/front_end/ui/legacy/components/data_grid/DataGridElement.ts +3 -3
- package/package.json +1 -1
- /package/front_end/ui/components/{list → lists}/lists.ts +0 -0
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
import type * as LHModel from '../../lighthouse/lighthouse.js';
|
|
6
6
|
|
|
7
|
+
import {bytes, millis} from './UnitFormatters.js';
|
|
8
|
+
|
|
7
9
|
/**
|
|
8
10
|
* A formatter that takes a raw Lighthouse report JSON and creates a markdown
|
|
9
11
|
* summary for an AI Agent.
|
|
@@ -120,37 +122,74 @@ export class LighthouseFormatter {
|
|
|
120
122
|
}
|
|
121
123
|
}
|
|
122
124
|
|
|
123
|
-
#formatTable(headings: LHModel.ReporterTypes.TableHeadingJSON[], items:
|
|
125
|
+
#formatTable(headings: LHModel.ReporterTypes.TableHeadingJSON[], items: LHModel.ReporterTypes.TableItem[]): string {
|
|
124
126
|
const lines: string[] = [];
|
|
125
|
-
|
|
127
|
+
|
|
126
128
|
for (const item of items) {
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
+
const itemLines: string[] = [];
|
|
130
|
+
for (const heading of headings) {
|
|
131
|
+
const value = item[heading.key] as LHModel.ReporterTypes.TableItemValue;
|
|
132
|
+
const formattedValues = this.#formatTableValues(value, heading.valueType);
|
|
133
|
+
for (const {labelSuffix, value: v} of formattedValues) {
|
|
134
|
+
const baseLabel = heading.label || heading.key;
|
|
135
|
+
const label = labelSuffix ? `${baseLabel} ${labelSuffix}` : baseLabel;
|
|
136
|
+
itemLines.push(` * **${label}**: ${v}`);
|
|
137
|
+
}
|
|
138
|
+
const subItems = item.subItems;
|
|
139
|
+
// subItems can technically be a string (TableItemValue), but we
|
|
140
|
+
// only care about it here if it's a SubItemsJSON (type:
|
|
141
|
+
// 'subitems'), which represents a nested table of values.
|
|
142
|
+
if (subItems && typeof subItems === 'object' && 'type' in subItems && subItems.type === 'subitems' &&
|
|
143
|
+
heading.subItemsHeading) {
|
|
144
|
+
for (const subItem of subItems.items) {
|
|
145
|
+
const subValue = subItem[heading.subItemsHeading.key] as LHModel.ReporterTypes.TableItemValue;
|
|
146
|
+
// Skip sub-item values that are identical to the main item's value
|
|
147
|
+
// for the same heading to avoid redundant output (e.g. if both
|
|
148
|
+
// show the same "Est Savings" value).
|
|
149
|
+
if (subValue === value) {
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
const formattedSubValues = this.#formatTableValues(subValue, heading.subItemsHeading.valueType);
|
|
153
|
+
for (const {value: v} of formattedSubValues) {
|
|
154
|
+
itemLines.push(` * ${v}`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (itemLines.length > 0) {
|
|
160
|
+
lines.push(`- Item:`);
|
|
161
|
+
lines.push(...itemLines);
|
|
162
|
+
}
|
|
129
163
|
}
|
|
130
164
|
return lines.join('\n');
|
|
131
165
|
}
|
|
132
166
|
|
|
133
|
-
#
|
|
167
|
+
#formatTableValues(value: LHModel.ReporterTypes.TableItemValue|undefined, valueType?: string): Array<{
|
|
168
|
+
value: string,
|
|
169
|
+
labelSuffix?: string,
|
|
170
|
+
}> {
|
|
134
171
|
if (value === undefined || value === null) {
|
|
135
|
-
return
|
|
172
|
+
return [];
|
|
136
173
|
}
|
|
137
174
|
if (typeof value === 'string' || typeof value === 'number') {
|
|
138
|
-
return
|
|
175
|
+
return [{value: this.#formatValue(value, valueType)}];
|
|
139
176
|
}
|
|
140
177
|
if (typeof value === 'object' && 'type' in value) {
|
|
141
178
|
switch (value.type) {
|
|
142
179
|
case 'node': {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
180
|
+
const results = [];
|
|
181
|
+
const label = value.nodeLabel || value.selector || value.snippet || '(node)';
|
|
182
|
+
results.push({value: label});
|
|
183
|
+
if (value.selector && value.selector !== label) {
|
|
184
|
+
results.push({labelSuffix: 'selector', value: value.selector});
|
|
146
185
|
}
|
|
147
186
|
if (value.path) {
|
|
148
|
-
|
|
187
|
+
results.push({labelSuffix: 'path', value: value.path});
|
|
149
188
|
}
|
|
150
189
|
if (value.explanation) {
|
|
151
|
-
|
|
190
|
+
results.push({labelSuffix: 'explanation', value: value.explanation.replace(/\n/g, ' ')});
|
|
152
191
|
}
|
|
153
|
-
return
|
|
192
|
+
return results;
|
|
154
193
|
}
|
|
155
194
|
case 'source-location': {
|
|
156
195
|
const parts = [];
|
|
@@ -163,10 +202,27 @@ export class LighthouseFormatter {
|
|
|
163
202
|
if (value.column) {
|
|
164
203
|
parts.push(String(value.column));
|
|
165
204
|
}
|
|
166
|
-
return parts.join(':');
|
|
205
|
+
return [{value: parts.join(':')}];
|
|
167
206
|
}
|
|
168
207
|
}
|
|
169
208
|
}
|
|
170
|
-
return
|
|
209
|
+
return [];
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
#formatValue(value: string|number, valueType?: string): string {
|
|
213
|
+
if (typeof value === 'string') {
|
|
214
|
+
return value;
|
|
215
|
+
}
|
|
216
|
+
switch (valueType) {
|
|
217
|
+
case 'bytes': {
|
|
218
|
+
return bytes(value);
|
|
219
|
+
}
|
|
220
|
+
case 'timespanMs':
|
|
221
|
+
case 'ms': {
|
|
222
|
+
return millis(value);
|
|
223
|
+
}
|
|
224
|
+
default:
|
|
225
|
+
return String(value);
|
|
226
|
+
}
|
|
171
227
|
}
|
|
172
228
|
}
|
|
@@ -7,10 +7,7 @@ import * as Common from '../../core/common/common.js';
|
|
|
7
7
|
import {ChunkedFileReader, type ChunkedReader} from './FileUtils.js';
|
|
8
8
|
|
|
9
9
|
export class TempFile {
|
|
10
|
-
#lastBlob: Blob|null;
|
|
11
|
-
constructor() {
|
|
12
|
-
this.#lastBlob = null;
|
|
13
|
-
}
|
|
10
|
+
#lastBlob: Blob|null = null;
|
|
14
11
|
|
|
15
12
|
write(pieces: Array<string|Blob>): void {
|
|
16
13
|
if (this.#lastBlob) {
|
|
@@ -616,7 +616,7 @@ self.injectedExtensionAPI = function(
|
|
|
616
616
|
entries[i].__proto__ = new (Constructor(Request))(entries[i]._requestId as number);
|
|
617
617
|
delete entries[i]._requestId;
|
|
618
618
|
}
|
|
619
|
-
callback?.(result
|
|
619
|
+
callback?.(result);
|
|
620
620
|
}
|
|
621
621
|
extensionServer.sendRequest({command: PrivateAPI.Commands.GetHAR}, callback && callbackWrapper);
|
|
622
622
|
},
|
|
@@ -71,13 +71,19 @@ export class Node {
|
|
|
71
71
|
retainedSize: number;
|
|
72
72
|
selfSize: number;
|
|
73
73
|
type: string;
|
|
74
|
-
canBeQueried
|
|
75
|
-
detachedDOMTreeNode
|
|
76
|
-
isAddedNotRemoved: boolean|null;
|
|
77
|
-
ignored
|
|
74
|
+
canBeQueried = false;
|
|
75
|
+
detachedDOMTreeNode = false;
|
|
76
|
+
isAddedNotRemoved: boolean|null = null;
|
|
77
|
+
ignored = false;
|
|
78
78
|
constructor(
|
|
79
|
-
id: number,
|
|
80
|
-
|
|
79
|
+
id: number,
|
|
80
|
+
name: string,
|
|
81
|
+
distance: number,
|
|
82
|
+
nodeIndex: number,
|
|
83
|
+
retainedSize: number,
|
|
84
|
+
selfSize: number,
|
|
85
|
+
type: string,
|
|
86
|
+
) {
|
|
81
87
|
this.id = id;
|
|
82
88
|
this.name = name;
|
|
83
89
|
this.distance = distance;
|
|
@@ -85,11 +91,6 @@ export class Node {
|
|
|
85
91
|
this.retainedSize = retainedSize;
|
|
86
92
|
this.selfSize = selfSize;
|
|
87
93
|
this.type = type;
|
|
88
|
-
|
|
89
|
-
this.canBeQueried = false;
|
|
90
|
-
this.detachedDOMTreeNode = false;
|
|
91
|
-
this.isAddedNotRemoved = null;
|
|
92
|
-
this.ignored = false;
|
|
93
94
|
}
|
|
94
95
|
}
|
|
95
96
|
|
|
@@ -98,13 +99,12 @@ export class Edge {
|
|
|
98
99
|
node: Node;
|
|
99
100
|
type: string;
|
|
100
101
|
edgeIndex: number;
|
|
101
|
-
isAddedNotRemoved: boolean|null;
|
|
102
|
+
isAddedNotRemoved: boolean|null = null;
|
|
102
103
|
constructor(name: string, node: Node, type: string, edgeIndex: number) {
|
|
103
104
|
this.name = name;
|
|
104
105
|
this.node = node;
|
|
105
106
|
this.type = type;
|
|
106
107
|
this.edgeIndex = edgeIndex;
|
|
107
|
-
this.isAddedNotRemoved = null;
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
110
|
|
|
@@ -132,37 +132,19 @@ export class AggregateForDiff {
|
|
|
132
132
|
|
|
133
133
|
export class Diff {
|
|
134
134
|
name: string;
|
|
135
|
-
addedCount
|
|
136
|
-
removedCount
|
|
137
|
-
addedSize
|
|
138
|
-
removedSize
|
|
139
|
-
deletedIndexes: number[];
|
|
140
|
-
addedIndexes: number[];
|
|
135
|
+
addedCount = 0;
|
|
136
|
+
removedCount = 0;
|
|
137
|
+
addedSize = 0;
|
|
138
|
+
removedSize = 0;
|
|
139
|
+
deletedIndexes: number[] = [];
|
|
140
|
+
addedIndexes: number[] = [];
|
|
141
141
|
countDelta!: number;
|
|
142
142
|
sizeDelta!: number;
|
|
143
143
|
constructor(name: string) {
|
|
144
144
|
this.name = name;
|
|
145
|
-
this.addedCount = 0;
|
|
146
|
-
this.removedCount = 0;
|
|
147
|
-
this.addedSize = 0;
|
|
148
|
-
this.removedSize = 0;
|
|
149
|
-
this.deletedIndexes = [];
|
|
150
|
-
this.addedIndexes = [];
|
|
151
145
|
}
|
|
152
146
|
}
|
|
153
147
|
|
|
154
|
-
export class DiffForClass {
|
|
155
|
-
name!: string;
|
|
156
|
-
addedCount!: number;
|
|
157
|
-
removedCount!: number;
|
|
158
|
-
addedSize!: number;
|
|
159
|
-
removedSize!: number;
|
|
160
|
-
deletedIndexes!: number[];
|
|
161
|
-
addedIndexes!: number[];
|
|
162
|
-
countDelta!: number;
|
|
163
|
-
sizeDelta!: number;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
148
|
export class ComparatorConfig {
|
|
167
149
|
fieldName1: string;
|
|
168
150
|
ascending1: boolean;
|
|
@@ -176,16 +158,16 @@ export class ComparatorConfig {
|
|
|
176
158
|
}
|
|
177
159
|
}
|
|
178
160
|
|
|
179
|
-
export
|
|
180
|
-
callId
|
|
181
|
-
disposition
|
|
182
|
-
objectId
|
|
183
|
-
newObjectId
|
|
184
|
-
methodName
|
|
161
|
+
export interface WorkerCommand {
|
|
162
|
+
callId: number;
|
|
163
|
+
disposition: string;
|
|
164
|
+
objectId: number;
|
|
165
|
+
newObjectId: number;
|
|
166
|
+
methodName: string;
|
|
185
167
|
// TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration
|
|
186
168
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
187
|
-
methodArguments
|
|
188
|
-
source
|
|
169
|
+
methodArguments: any[];
|
|
170
|
+
source: string;
|
|
189
171
|
}
|
|
190
172
|
|
|
191
173
|
export class ItemsRange {
|
|
@@ -244,8 +226,13 @@ export class SearchConfig {
|
|
|
244
226
|
shouldJump: boolean;
|
|
245
227
|
jumpBackward: boolean;
|
|
246
228
|
constructor(
|
|
247
|
-
query: string,
|
|
248
|
-
|
|
229
|
+
query: string,
|
|
230
|
+
caseSensitive: boolean,
|
|
231
|
+
wholeWord: boolean,
|
|
232
|
+
isRegex: boolean,
|
|
233
|
+
shouldJump: boolean,
|
|
234
|
+
jumpBackward: boolean,
|
|
235
|
+
) {
|
|
249
236
|
this.query = query;
|
|
250
237
|
this.caseSensitive = caseSensitive;
|
|
251
238
|
this.wholeWord = wholeWord;
|
|
@@ -1003,7 +1003,7 @@ export const NativeFunctions = [
|
|
|
1003
1003
|
{
|
|
1004
1004
|
name: "addEventListener",
|
|
1005
1005
|
signatures: [["type","listener","?options"]],
|
|
1006
|
-
receivers: ["AbortSignal","SharedWorker","Worker","ServiceWorker","Animation","AudioBufferSourceNode","AudioContext","AudioDecoder","AudioEncoder","AudioScheduledSourceNode","AudioWorkletNode","BaseAudioContext","BroadcastChannel","CSSAnimation","CSSTransition","CanvasCaptureMediaStreamTrack","ConstantSourceNode","CookieStore","Document","Element","EventSource","FileReader","FontFaceSet","Window","HTMLElement","MathMLElement","SVGElement","HTMLAnchorElement","HTMLAreaElement","HTMLAudioElement","HTMLBRElement","HTMLBaseElement","HTMLBodyElement","HTMLButtonElement","HTMLCanvasElement","HTMLDListElement","HTMLDataElement","HTMLDataListElement","HTMLDetailsElement","HTMLDialogElement","HTMLDirectoryElement","HTMLDivElement","HTMLDocument","HTMLEmbedElement","HTMLFieldSetElement","HTMLFontElement","HTMLFormElement","HTMLFrameElement","HTMLFrameSetElement","HTMLHRElement","HTMLHeadElement","HTMLHeadingElement","HTMLHtmlElement","HTMLIFrameElement","HTMLImageElement","HTMLInputElement","HTMLLIElement","HTMLLabelElement","HTMLLegendElement","HTMLLinkElement","HTMLMapElement","HTMLMarqueeElement","HTMLMediaElement","HTMLMenuElement","HTMLMetaElement","HTMLMeterElement","HTMLModElement","HTMLOListElement","HTMLObjectElement","HTMLOptGroupElement","HTMLOptionElement","HTMLOutputElement","HTMLParagraphElement","HTMLParamElement","HTMLPictureElement","HTMLPreElement","HTMLProgressElement","HTMLQuoteElement","HTMLScriptElement","HTMLSelectElement","HTMLSlotElement","HTMLSourceElement","HTMLSpanElement","HTMLStyleElement","HTMLTableCaptionElement","HTMLTableCellElement","HTMLTableColElement","HTMLTableDataCellElement","HTMLTableElement","HTMLTableHeaderCellElement","HTMLTableRowElement","HTMLTableSectionElement","HTMLTemplateElement","HTMLTextAreaElement","HTMLTimeElement","HTMLTitleElement","HTMLTrackElement","HTMLUListElement","HTMLUnknownElement","HTMLVideoElement","IDBDatabase","IDBOpenDBRequest","IDBRequest","IDBTransaction","MIDIAccess","MIDIInput","MIDIOutput","MIDIPort","MediaDevices","MediaKeySession","MediaQueryList","MediaRecorder","MediaSource","MediaStream","MediaStreamTrack","MessageEventTarget","MessagePort","NavigationHistoryEntry","Notification","OfflineAudioContext","OffscreenCanvas","OscillatorNode","PaymentRequest","PaymentResponse","Performance","PermissionStatus","PictureInPictureWindow","RTCDTMFSender","RTCDataChannel","RTCDtlsTransport","RTCIceTransport","RTCPeerConnection","RTCSctpTransport","RemotePlayback","SVGAElement","SVGAnimateElement","SVGAnimateMotionElement","SVGAnimateTransformElement","SVGAnimationElement","SVGCircleElement","SVGClipPathElement","SVGComponentTransferFunctionElement","SVGDefsElement","SVGDescElement","SVGEllipseElement","SVGFEBlendElement","SVGFEColorMatrixElement","SVGFEComponentTransferElement","SVGFECompositeElement","SVGFEConvolveMatrixElement","SVGFEDiffuseLightingElement","SVGFEDisplacementMapElement","SVGFEDistantLightElement","SVGFEDropShadowElement","SVGFEFloodElement","SVGFEFuncAElement","SVGFEFuncBElement","SVGFEFuncGElement","SVGFEFuncRElement","SVGFEGaussianBlurElement","SVGFEImageElement","SVGFEMergeElement","SVGFEMergeNodeElement","SVGFEMorphologyElement","SVGFEOffsetElement","SVGFEPointLightElement","SVGFESpecularLightingElement","SVGFESpotLightElement","SVGFETileElement","SVGFETurbulenceElement","SVGFilterElement","SVGForeignObjectElement","SVGGElement","SVGGeometryElement","SVGGradientElement","SVGGraphicsElement","SVGImageElement","SVGLineElement","SVGLinearGradientElement","SVGMPathElement","SVGMarkerElement","SVGMaskElement","SVGMetadataElement","SVGPathElement","SVGPatternElement","SVGPolygonElement","SVGPolylineElement","SVGRadialGradientElement","SVGRectElement","SVGSVGElement","SVGScriptElement","SVGSetElement","SVGStopElement","SVGStyleElement","SVGSwitchElement","SVGSymbolElement","SVGTSpanElement","SVGTextContentElement","SVGTextElement","SVGTextPathElement","SVGTextPositioningElement","SVGTitleElement","SVGUseElement","SVGViewElement","ScreenOrientation","ScriptProcessorNode","ServiceWorkerContainer","ServiceWorkerRegistration","ShadowRoot","SourceBuffer","SourceBufferList","SpeechSynthesis","SpeechSynthesisUtterance","TextTrack","TextTrackCue","TextTrackList","VTTCue","VideoDecoder","VideoEncoder","VisualViewport","WakeLockSentinel","WebSocket","XMLDocument","XMLHttpRequest","XMLHttpRequestEventTarget","XMLHttpRequestUpload","DedicatedWorkerGlobalScope","ServiceWorkerGlobalScope","SharedWorkerGlobalScope","WorkerGlobalScope"
|
|
1006
|
+
receivers: ["AbortSignal","SharedWorker","Worker","ServiceWorker","Animation","AudioBufferSourceNode","AudioContext","AudioDecoder","AudioEncoder","AudioScheduledSourceNode","AudioWorkletNode","BaseAudioContext","BroadcastChannel","CSSAnimation","CSSTransition","CanvasCaptureMediaStreamTrack","ConstantSourceNode","CookieStore","Document","Element","EventSource","FileReader","FontFaceSet","Window","HTMLElement","MathMLElement","SVGElement","HTMLAnchorElement","HTMLAreaElement","HTMLAudioElement","HTMLBRElement","HTMLBaseElement","HTMLBodyElement","HTMLButtonElement","HTMLCanvasElement","HTMLDListElement","HTMLDataElement","HTMLDataListElement","HTMLDetailsElement","HTMLDialogElement","HTMLDirectoryElement","HTMLDivElement","HTMLDocument","HTMLEmbedElement","HTMLFieldSetElement","HTMLFontElement","HTMLFormElement","HTMLFrameElement","HTMLFrameSetElement","HTMLHRElement","HTMLHeadElement","HTMLHeadingElement","HTMLHtmlElement","HTMLIFrameElement","HTMLImageElement","HTMLInputElement","HTMLLIElement","HTMLLabelElement","HTMLLegendElement","HTMLLinkElement","HTMLMapElement","HTMLMarqueeElement","HTMLMediaElement","HTMLMenuElement","HTMLMetaElement","HTMLMeterElement","HTMLModElement","HTMLOListElement","HTMLObjectElement","HTMLOptGroupElement","HTMLOptionElement","HTMLOutputElement","HTMLParagraphElement","HTMLParamElement","HTMLPictureElement","HTMLPreElement","HTMLProgressElement","HTMLQuoteElement","HTMLScriptElement","HTMLSelectElement","HTMLSlotElement","HTMLSourceElement","HTMLSpanElement","HTMLStyleElement","HTMLTableCaptionElement","HTMLTableCellElement","HTMLTableColElement","HTMLTableDataCellElement","HTMLTableElement","HTMLTableHeaderCellElement","HTMLTableRowElement","HTMLTableSectionElement","HTMLTemplateElement","HTMLTextAreaElement","HTMLTimeElement","HTMLTitleElement","HTMLTrackElement","HTMLUListElement","HTMLUnknownElement","HTMLVideoElement","IDBDatabase","IDBOpenDBRequest","IDBRequest","IDBTransaction","MIDIAccess","MIDIInput","MIDIOutput","MIDIPort","MediaDevices","MediaKeySession","MediaQueryList","MediaRecorder","MediaSource","MediaStream","MediaStreamTrack","MessageEventTarget","MessagePort","NavigationHistoryEntry","Notification","OfflineAudioContext","OffscreenCanvas","OscillatorNode","PaymentRequest","PaymentResponse","Performance","PermissionStatus","PictureInPictureWindow","RTCDTMFSender","RTCDataChannel","RTCDtlsTransport","RTCIceTransport","RTCPeerConnection","RTCSctpTransport","RemotePlayback","SVGAElement","SVGAnimateElement","SVGAnimateMotionElement","SVGAnimateTransformElement","SVGAnimationElement","SVGCircleElement","SVGClipPathElement","SVGComponentTransferFunctionElement","SVGDefsElement","SVGDescElement","SVGEllipseElement","SVGFEBlendElement","SVGFEColorMatrixElement","SVGFEComponentTransferElement","SVGFECompositeElement","SVGFEConvolveMatrixElement","SVGFEDiffuseLightingElement","SVGFEDisplacementMapElement","SVGFEDistantLightElement","SVGFEDropShadowElement","SVGFEFloodElement","SVGFEFuncAElement","SVGFEFuncBElement","SVGFEFuncGElement","SVGFEFuncRElement","SVGFEGaussianBlurElement","SVGFEImageElement","SVGFEMergeElement","SVGFEMergeNodeElement","SVGFEMorphologyElement","SVGFEOffsetElement","SVGFEPointLightElement","SVGFESpecularLightingElement","SVGFESpotLightElement","SVGFETileElement","SVGFETurbulenceElement","SVGFilterElement","SVGForeignObjectElement","SVGGElement","SVGGeometryElement","SVGGradientElement","SVGGraphicsElement","SVGImageElement","SVGLineElement","SVGLinearGradientElement","SVGMPathElement","SVGMarkerElement","SVGMaskElement","SVGMetadataElement","SVGPathElement","SVGPatternElement","SVGPolygonElement","SVGPolylineElement","SVGRadialGradientElement","SVGRectElement","SVGSVGElement","SVGScriptElement","SVGSetElement","SVGStopElement","SVGStyleElement","SVGSwitchElement","SVGSymbolElement","SVGTSpanElement","SVGTextContentElement","SVGTextElement","SVGTextPathElement","SVGTextPositioningElement","SVGTitleElement","SVGUseElement","SVGViewElement","ScreenOrientation","ScriptProcessorNode","ServiceWorkerContainer","ServiceWorkerRegistration","ShadowRoot","SourceBuffer","SourceBufferList","SpeechSynthesis","SpeechSynthesisUtterance","TextTrack","TextTrackCue","TextTrackList","VTTCue","VideoDecoder","VideoEncoder","VisualViewport","WakeLockSentinel","WebSocket","XMLDocument","XMLHttpRequest","XMLHttpRequestEventTarget","XMLHttpRequestUpload","DedicatedWorkerGlobalScope","ServiceWorkerGlobalScope","SharedWorkerGlobalScope","WorkerGlobalScope"]
|
|
1007
1007
|
},
|
|
1008
1008
|
{
|
|
1009
1009
|
name: "addEventListener",
|
|
@@ -1013,7 +1013,7 @@ export const NativeFunctions = [
|
|
|
1013
1013
|
{
|
|
1014
1014
|
name: "removeEventListener",
|
|
1015
1015
|
signatures: [["type","listener","?options"]],
|
|
1016
|
-
receivers: ["AbortSignal","SharedWorker","Worker","ServiceWorker","Animation","AudioBufferSourceNode","AudioContext","AudioDecoder","AudioEncoder","AudioScheduledSourceNode","AudioWorkletNode","BaseAudioContext","BroadcastChannel","CSSAnimation","CSSTransition","CanvasCaptureMediaStreamTrack","ConstantSourceNode","CookieStore","Document","Element","EventSource","FileReader","FontFaceSet","Window","HTMLElement","MathMLElement","SVGElement","HTMLAnchorElement","HTMLAreaElement","HTMLAudioElement","HTMLBRElement","HTMLBaseElement","HTMLBodyElement","HTMLButtonElement","HTMLCanvasElement","HTMLDListElement","HTMLDataElement","HTMLDataListElement","HTMLDetailsElement","HTMLDialogElement","HTMLDirectoryElement","HTMLDivElement","HTMLDocument","HTMLEmbedElement","HTMLFieldSetElement","HTMLFontElement","HTMLFormElement","HTMLFrameElement","HTMLFrameSetElement","HTMLHRElement","HTMLHeadElement","HTMLHeadingElement","HTMLHtmlElement","HTMLIFrameElement","HTMLImageElement","HTMLInputElement","HTMLLIElement","HTMLLabelElement","HTMLLegendElement","HTMLLinkElement","HTMLMapElement","HTMLMarqueeElement","HTMLMediaElement","HTMLMenuElement","HTMLMetaElement","HTMLMeterElement","HTMLModElement","HTMLOListElement","HTMLObjectElement","HTMLOptGroupElement","HTMLOptionElement","HTMLOutputElement","HTMLParagraphElement","HTMLParamElement","HTMLPictureElement","HTMLPreElement","HTMLProgressElement","HTMLQuoteElement","HTMLScriptElement","HTMLSelectElement","HTMLSlotElement","HTMLSourceElement","HTMLSpanElement","HTMLStyleElement","HTMLTableCaptionElement","HTMLTableCellElement","HTMLTableColElement","HTMLTableDataCellElement","HTMLTableElement","HTMLTableHeaderCellElement","HTMLTableRowElement","HTMLTableSectionElement","HTMLTemplateElement","HTMLTextAreaElement","HTMLTimeElement","HTMLTitleElement","HTMLTrackElement","HTMLUListElement","HTMLUnknownElement","HTMLVideoElement","IDBDatabase","IDBOpenDBRequest","IDBRequest","IDBTransaction","MIDIAccess","MIDIInput","MIDIOutput","MIDIPort","MediaDevices","MediaKeySession","MediaQueryList","MediaRecorder","MediaSource","MediaStream","MediaStreamTrack","MessageEventTarget","MessagePort","NavigationHistoryEntry","Notification","OfflineAudioContext","OffscreenCanvas","OscillatorNode","PaymentRequest","PaymentResponse","Performance","PermissionStatus","PictureInPictureWindow","RTCDTMFSender","RTCDataChannel","RTCDtlsTransport","RTCIceTransport","RTCPeerConnection","RTCSctpTransport","RemotePlayback","SVGAElement","SVGAnimateElement","SVGAnimateMotionElement","SVGAnimateTransformElement","SVGAnimationElement","SVGCircleElement","SVGClipPathElement","SVGComponentTransferFunctionElement","SVGDefsElement","SVGDescElement","SVGEllipseElement","SVGFEBlendElement","SVGFEColorMatrixElement","SVGFEComponentTransferElement","SVGFECompositeElement","SVGFEConvolveMatrixElement","SVGFEDiffuseLightingElement","SVGFEDisplacementMapElement","SVGFEDistantLightElement","SVGFEDropShadowElement","SVGFEFloodElement","SVGFEFuncAElement","SVGFEFuncBElement","SVGFEFuncGElement","SVGFEFuncRElement","SVGFEGaussianBlurElement","SVGFEImageElement","SVGFEMergeElement","SVGFEMergeNodeElement","SVGFEMorphologyElement","SVGFEOffsetElement","SVGFEPointLightElement","SVGFESpecularLightingElement","SVGFESpotLightElement","SVGFETileElement","SVGFETurbulenceElement","SVGFilterElement","SVGForeignObjectElement","SVGGElement","SVGGeometryElement","SVGGradientElement","SVGGraphicsElement","SVGImageElement","SVGLineElement","SVGLinearGradientElement","SVGMPathElement","SVGMarkerElement","SVGMaskElement","SVGMetadataElement","SVGPathElement","SVGPatternElement","SVGPolygonElement","SVGPolylineElement","SVGRadialGradientElement","SVGRectElement","SVGSVGElement","SVGScriptElement","SVGSetElement","SVGStopElement","SVGStyleElement","SVGSwitchElement","SVGSymbolElement","SVGTSpanElement","SVGTextContentElement","SVGTextElement","SVGTextPathElement","SVGTextPositioningElement","SVGTitleElement","SVGUseElement","SVGViewElement","ScreenOrientation","ScriptProcessorNode","ServiceWorkerContainer","ServiceWorkerRegistration","ShadowRoot","SourceBuffer","SourceBufferList","SpeechSynthesis","SpeechSynthesisUtterance","TextTrack","TextTrackCue","TextTrackList","VTTCue","VideoDecoder","VideoEncoder","VisualViewport","WakeLockSentinel","WebSocket","XMLDocument","XMLHttpRequest","XMLHttpRequestEventTarget","XMLHttpRequestUpload","DedicatedWorkerGlobalScope","ServiceWorkerGlobalScope","SharedWorkerGlobalScope","WorkerGlobalScope"
|
|
1016
|
+
receivers: ["AbortSignal","SharedWorker","Worker","ServiceWorker","Animation","AudioBufferSourceNode","AudioContext","AudioDecoder","AudioEncoder","AudioScheduledSourceNode","AudioWorkletNode","BaseAudioContext","BroadcastChannel","CSSAnimation","CSSTransition","CanvasCaptureMediaStreamTrack","ConstantSourceNode","CookieStore","Document","Element","EventSource","FileReader","FontFaceSet","Window","HTMLElement","MathMLElement","SVGElement","HTMLAnchorElement","HTMLAreaElement","HTMLAudioElement","HTMLBRElement","HTMLBaseElement","HTMLBodyElement","HTMLButtonElement","HTMLCanvasElement","HTMLDListElement","HTMLDataElement","HTMLDataListElement","HTMLDetailsElement","HTMLDialogElement","HTMLDirectoryElement","HTMLDivElement","HTMLDocument","HTMLEmbedElement","HTMLFieldSetElement","HTMLFontElement","HTMLFormElement","HTMLFrameElement","HTMLFrameSetElement","HTMLHRElement","HTMLHeadElement","HTMLHeadingElement","HTMLHtmlElement","HTMLIFrameElement","HTMLImageElement","HTMLInputElement","HTMLLIElement","HTMLLabelElement","HTMLLegendElement","HTMLLinkElement","HTMLMapElement","HTMLMarqueeElement","HTMLMediaElement","HTMLMenuElement","HTMLMetaElement","HTMLMeterElement","HTMLModElement","HTMLOListElement","HTMLObjectElement","HTMLOptGroupElement","HTMLOptionElement","HTMLOutputElement","HTMLParagraphElement","HTMLParamElement","HTMLPictureElement","HTMLPreElement","HTMLProgressElement","HTMLQuoteElement","HTMLScriptElement","HTMLSelectElement","HTMLSlotElement","HTMLSourceElement","HTMLSpanElement","HTMLStyleElement","HTMLTableCaptionElement","HTMLTableCellElement","HTMLTableColElement","HTMLTableDataCellElement","HTMLTableElement","HTMLTableHeaderCellElement","HTMLTableRowElement","HTMLTableSectionElement","HTMLTemplateElement","HTMLTextAreaElement","HTMLTimeElement","HTMLTitleElement","HTMLTrackElement","HTMLUListElement","HTMLUnknownElement","HTMLVideoElement","IDBDatabase","IDBOpenDBRequest","IDBRequest","IDBTransaction","MIDIAccess","MIDIInput","MIDIOutput","MIDIPort","MediaDevices","MediaKeySession","MediaQueryList","MediaRecorder","MediaSource","MediaStream","MediaStreamTrack","MessageEventTarget","MessagePort","NavigationHistoryEntry","Notification","OfflineAudioContext","OffscreenCanvas","OscillatorNode","PaymentRequest","PaymentResponse","Performance","PermissionStatus","PictureInPictureWindow","RTCDTMFSender","RTCDataChannel","RTCDtlsTransport","RTCIceTransport","RTCPeerConnection","RTCSctpTransport","RemotePlayback","SVGAElement","SVGAnimateElement","SVGAnimateMotionElement","SVGAnimateTransformElement","SVGAnimationElement","SVGCircleElement","SVGClipPathElement","SVGComponentTransferFunctionElement","SVGDefsElement","SVGDescElement","SVGEllipseElement","SVGFEBlendElement","SVGFEColorMatrixElement","SVGFEComponentTransferElement","SVGFECompositeElement","SVGFEConvolveMatrixElement","SVGFEDiffuseLightingElement","SVGFEDisplacementMapElement","SVGFEDistantLightElement","SVGFEDropShadowElement","SVGFEFloodElement","SVGFEFuncAElement","SVGFEFuncBElement","SVGFEFuncGElement","SVGFEFuncRElement","SVGFEGaussianBlurElement","SVGFEImageElement","SVGFEMergeElement","SVGFEMergeNodeElement","SVGFEMorphologyElement","SVGFEOffsetElement","SVGFEPointLightElement","SVGFESpecularLightingElement","SVGFESpotLightElement","SVGFETileElement","SVGFETurbulenceElement","SVGFilterElement","SVGForeignObjectElement","SVGGElement","SVGGeometryElement","SVGGradientElement","SVGGraphicsElement","SVGImageElement","SVGLineElement","SVGLinearGradientElement","SVGMPathElement","SVGMarkerElement","SVGMaskElement","SVGMetadataElement","SVGPathElement","SVGPatternElement","SVGPolygonElement","SVGPolylineElement","SVGRadialGradientElement","SVGRectElement","SVGSVGElement","SVGScriptElement","SVGSetElement","SVGStopElement","SVGStyleElement","SVGSwitchElement","SVGSymbolElement","SVGTSpanElement","SVGTextContentElement","SVGTextElement","SVGTextPathElement","SVGTextPositioningElement","SVGTitleElement","SVGUseElement","SVGViewElement","ScreenOrientation","ScriptProcessorNode","ServiceWorkerContainer","ServiceWorkerRegistration","ShadowRoot","SourceBuffer","SourceBufferList","SpeechSynthesis","SpeechSynthesisUtterance","TextTrack","TextTrackCue","TextTrackList","VTTCue","VideoDecoder","VideoEncoder","VisualViewport","WakeLockSentinel","WebSocket","XMLDocument","XMLHttpRequest","XMLHttpRequestEventTarget","XMLHttpRequestUpload","DedicatedWorkerGlobalScope","ServiceWorkerGlobalScope","SharedWorkerGlobalScope","WorkerGlobalScope"]
|
|
1017
1017
|
},
|
|
1018
1018
|
{
|
|
1019
1019
|
name: "removeEventListener",
|
|
@@ -2895,6 +2895,10 @@ export const NativeFunctions = [
|
|
|
2895
2895
|
signatures: [["?detailsPromise"]],
|
|
2896
2896
|
receivers: ["PaymentRequest"]
|
|
2897
2897
|
},
|
|
2898
|
+
{
|
|
2899
|
+
name: "attachInternals",
|
|
2900
|
+
signatures: [["?options"]]
|
|
2901
|
+
},
|
|
2898
2902
|
{
|
|
2899
2903
|
name: "showPopover",
|
|
2900
2904
|
signatures: [["?options"]]
|
|
@@ -6602,16 +6606,12 @@ export const NativeFunctions = [
|
|
|
6602
6606
|
name: "replaceWithHTMLUnsafe",
|
|
6603
6607
|
signatures: [["html","?options"]]
|
|
6604
6608
|
},
|
|
6605
|
-
{
|
|
6606
|
-
name: "streamBeforeHTMLUnsafe",
|
|
6607
|
-
signatures: [["?options"]]
|
|
6608
|
-
},
|
|
6609
6609
|
{
|
|
6610
6610
|
name: "streamBeforeHTML",
|
|
6611
6611
|
signatures: [["?options"]]
|
|
6612
6612
|
},
|
|
6613
6613
|
{
|
|
6614
|
-
name: "
|
|
6614
|
+
name: "streamBeforeHTMLUnsafe",
|
|
6615
6615
|
signatures: [["?options"]]
|
|
6616
6616
|
},
|
|
6617
6617
|
{
|
|
@@ -6619,13 +6619,17 @@ export const NativeFunctions = [
|
|
|
6619
6619
|
signatures: [["?options"]]
|
|
6620
6620
|
},
|
|
6621
6621
|
{
|
|
6622
|
-
name: "
|
|
6622
|
+
name: "streamAfterHTMLUnsafe",
|
|
6623
6623
|
signatures: [["?options"]]
|
|
6624
6624
|
},
|
|
6625
6625
|
{
|
|
6626
6626
|
name: "streamReplaceWithHTML",
|
|
6627
6627
|
signatures: [["?options"]]
|
|
6628
6628
|
},
|
|
6629
|
+
{
|
|
6630
|
+
name: "streamReplaceWithHTMLUnsafe",
|
|
6631
|
+
signatures: [["?options"]]
|
|
6632
|
+
},
|
|
6629
6633
|
{
|
|
6630
6634
|
name: "Comment",
|
|
6631
6635
|
signatures: [["?data"]]
|
|
@@ -82,10 +82,17 @@ export interface ReportJSON {
|
|
|
82
82
|
export type DetailsJSON =
|
|
83
83
|
|TableDetailsJSON|OpportunityDetailsJSON|FilmstripDetailsJSON|ScreenshotDetailsJSON|DebugDataDetailsJSON;
|
|
84
84
|
|
|
85
|
+
export interface SubItemsJSON {
|
|
86
|
+
type: 'subitems';
|
|
87
|
+
items: Array<Record<string, TableItemValue>>;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export type TableItem = Record<string, TableItemValue|SubItemsJSON|undefined>;
|
|
91
|
+
|
|
85
92
|
export interface TableDetailsJSON {
|
|
86
93
|
type: 'table';
|
|
87
94
|
headings: TableHeadingJSON[];
|
|
88
|
-
items:
|
|
95
|
+
items: TableItem[];
|
|
89
96
|
summary?: OpportunitySummary;
|
|
90
97
|
}
|
|
91
98
|
|
|
@@ -96,7 +103,7 @@ export interface TableHeadingJSON {
|
|
|
96
103
|
itemType?: string;
|
|
97
104
|
subItemsHeading?: {
|
|
98
105
|
key: string,
|
|
99
|
-
valueType
|
|
106
|
+
valueType?: string,
|
|
100
107
|
};
|
|
101
108
|
}
|
|
102
109
|
|
|
@@ -109,12 +116,7 @@ export type TableItemValue =|string|number|NodeDetailsJSON|SourceLocationDetails
|
|
|
109
116
|
export interface OpportunityDetailsJSON {
|
|
110
117
|
type: 'opportunity';
|
|
111
118
|
headings: TableHeadingJSON[];
|
|
112
|
-
items:
|
|
113
|
-
url: string,
|
|
114
|
-
wastedBytes?: number,
|
|
115
|
-
wastedMs?: number,
|
|
116
|
-
totalBytes?: number, [key: string]: unknown,
|
|
117
|
-
}>;
|
|
119
|
+
items: TableItem[];
|
|
118
120
|
overallSavingsMs: number;
|
|
119
121
|
overallSavingsBytes?: number;
|
|
120
122
|
}
|
|
@@ -383,7 +383,9 @@ interface ToolbarViewInput {
|
|
|
383
383
|
walkthrough: {
|
|
384
384
|
isExpanded: boolean,
|
|
385
385
|
isInlined: boolean,
|
|
386
|
-
onToggle: (isOpen: boolean) => void,
|
|
386
|
+
onToggle: (isOpen: boolean, message: ModelChatMessage) => void,
|
|
387
|
+
activeSidebarMessage: ModelChatMessage|null,
|
|
388
|
+
inlineExpandedMessages: ModelChatMessage[],
|
|
387
389
|
};
|
|
388
390
|
}
|
|
389
391
|
|
|
@@ -521,7 +523,7 @@ function defaultView(input: ViewInput, output: PanelViewOutput, target: HTMLElem
|
|
|
521
523
|
let walkthroughIsForLastMessage = false;
|
|
522
524
|
if(input.state === ViewState.CHAT_VIEW) {
|
|
523
525
|
const lastMessage = input.props.messages.at(-1);
|
|
524
|
-
if(lastMessage && input.props.walkthrough.
|
|
526
|
+
if(lastMessage && input.props.walkthrough.activeSidebarMessage === lastMessage) {
|
|
525
527
|
walkthroughIsForLastMessage = true;
|
|
526
528
|
}
|
|
527
529
|
}
|
|
@@ -542,7 +544,7 @@ function defaultView(input: ViewInput, output: PanelViewOutput, target: HTMLElem
|
|
|
542
544
|
<div slot="sidebar" class="sidebar-view">
|
|
543
545
|
${shouldShowWalkthrough ? html`
|
|
544
546
|
<devtools-widget ${widget(WalkthroughView, {
|
|
545
|
-
message: input.props.walkthrough.
|
|
547
|
+
message: input.props.walkthrough.activeSidebarMessage,
|
|
546
548
|
isLoading: input.props.isLoading && walkthroughIsForLastMessage,
|
|
547
549
|
markdownRenderer: input.props.markdownRenderer,
|
|
548
550
|
onToggle: input.props.walkthrough.onToggle,
|
|
@@ -610,10 +612,15 @@ function createPerformanceTraceContext(focus: AiAssistanceModel.AIContext.AgentF
|
|
|
610
612
|
|
|
611
613
|
/**
|
|
612
614
|
* State relating to the visibility of the Walkthrough.
|
|
613
|
-
*
|
|
614
|
-
*
|
|
615
|
-
*
|
|
616
|
-
*
|
|
615
|
+
*
|
|
616
|
+
* We track both an `activeSidebarMessage` and a list of `inlineExpandedMessages` because:
|
|
617
|
+
* 1. In Narrow (inline) mode, multiple walkthroughs can be expanded at once,
|
|
618
|
+
* so we need to track them all to render them correctly in the chat.
|
|
619
|
+
* 2. In Wide (sidebar) mode, only one walkthrough can be visible at a time.
|
|
620
|
+
* The `activeSidebarMessage` tracks which one is shown in the sidebar.
|
|
621
|
+
* 3. When transitioning from Narrow to Wide, we use the last message in
|
|
622
|
+
* `inlineExpandedMessages` to determine which one should stay expanded
|
|
623
|
+
* in the sidebar.
|
|
617
624
|
*/
|
|
618
625
|
interface WalkthroughState {
|
|
619
626
|
/**
|
|
@@ -625,11 +632,15 @@ interface WalkthroughState {
|
|
|
625
632
|
*/
|
|
626
633
|
isExpanded: boolean;
|
|
627
634
|
/**
|
|
628
|
-
* The message that the walkthrough is showing all the steps for.
|
|
629
|
-
*
|
|
630
|
-
*
|
|
635
|
+
* The message that the walkthrough is showing all the steps for. In Wide mode,
|
|
636
|
+
* this is the message shown in the sidebar. In Narrow mode, it tracks the
|
|
637
|
+
* most recently interacted message.
|
|
631
638
|
*/
|
|
632
|
-
|
|
639
|
+
activeSidebarMessage: ModelChatMessage|null;
|
|
640
|
+
/**
|
|
641
|
+
* Tracks which messages are expanded in inline mode.
|
|
642
|
+
*/
|
|
643
|
+
inlineExpandedMessages: ModelChatMessage[];
|
|
633
644
|
}
|
|
634
645
|
|
|
635
646
|
let panelInstance: AiAssistancePanel;
|
|
@@ -667,7 +678,8 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
667
678
|
#walkthrough: WalkthroughState = {
|
|
668
679
|
isInlined: false,
|
|
669
680
|
isExpanded: false,
|
|
670
|
-
|
|
681
|
+
activeSidebarMessage: null,
|
|
682
|
+
inlineExpandedMessages: [],
|
|
671
683
|
};
|
|
672
684
|
|
|
673
685
|
constructor(private view: View = defaultView, {aidaClient, aidaAvailability}: {
|
|
@@ -708,6 +720,8 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
708
720
|
isExpanded: this.#walkthrough.isExpanded,
|
|
709
721
|
isInlined: this.#walkthrough.isInlined,
|
|
710
722
|
onToggle: this.#toggleWalkthrough.bind(this),
|
|
723
|
+
activeSidebarMessage: this.#walkthrough.activeSidebarMessage,
|
|
724
|
+
inlineExpandedMessages: this.#walkthrough.inlineExpandedMessages,
|
|
711
725
|
}
|
|
712
726
|
};
|
|
713
727
|
}
|
|
@@ -796,7 +810,8 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
796
810
|
onOpen: this.#openWalkthrough.bind(this),
|
|
797
811
|
isExpanded: this.#walkthrough.isExpanded,
|
|
798
812
|
isInlined: this.#walkthrough.isInlined,
|
|
799
|
-
|
|
813
|
+
activeSidebarMessage: this.#walkthrough.activeSidebarMessage,
|
|
814
|
+
inlineExpandedMessages: this.#walkthrough.inlineExpandedMessages,
|
|
800
815
|
},
|
|
801
816
|
}
|
|
802
817
|
};
|
|
@@ -820,20 +835,73 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
820
835
|
if (isNarrow === this.#walkthrough.isInlined) {
|
|
821
836
|
return;
|
|
822
837
|
}
|
|
823
|
-
|
|
824
|
-
this.#clearWalkthrough();
|
|
838
|
+
|
|
825
839
|
this.#walkthrough.isInlined = isNarrow;
|
|
840
|
+
|
|
841
|
+
if (!this.#walkthrough.isExpanded) {
|
|
842
|
+
// If nothing was expanded, we just ensure the state is clean.
|
|
843
|
+
this.#walkthrough.activeSidebarMessage = null;
|
|
844
|
+
this.#walkthrough.inlineExpandedMessages = [];
|
|
845
|
+
this.requestUpdate();
|
|
846
|
+
return;
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
if (isNarrow) {
|
|
850
|
+
// Wide -> Inline: the walkthrough that was open stays expanded
|
|
851
|
+
this.#walkthrough.inlineExpandedMessages =
|
|
852
|
+
this.#walkthrough.activeSidebarMessage ? [this.#walkthrough.activeSidebarMessage] : [];
|
|
853
|
+
} else {
|
|
854
|
+
// Inline -> Wide: the last walkthrough that the user opened stays expanded
|
|
855
|
+
this.#walkthrough.activeSidebarMessage = this.#walkthrough.inlineExpandedMessages.at(-1) ?? null;
|
|
856
|
+
}
|
|
857
|
+
|
|
826
858
|
this.requestUpdate();
|
|
827
859
|
}
|
|
828
860
|
|
|
829
861
|
#openWalkthrough(message: ModelChatMessage): void {
|
|
830
|
-
this.#walkthrough.
|
|
862
|
+
if (!this.#walkthrough.inlineExpandedMessages.includes(message)) {
|
|
863
|
+
this.#walkthrough.inlineExpandedMessages.push(message);
|
|
864
|
+
}
|
|
865
|
+
this.#walkthrough.activeSidebarMessage = message;
|
|
831
866
|
this.#walkthrough.isExpanded = true;
|
|
832
867
|
this.requestUpdate();
|
|
833
868
|
}
|
|
834
869
|
|
|
835
|
-
|
|
836
|
-
|
|
870
|
+
/**
|
|
871
|
+
* Toggles the expanded state of a walkthrough.
|
|
872
|
+
*
|
|
873
|
+
* In Wide (sidebar) mode:
|
|
874
|
+
* - Opening a message's walkthrough shows the sidebar for that message.
|
|
875
|
+
* - Closing the sidebar hides the walkthrough for the currently active message.
|
|
876
|
+
*
|
|
877
|
+
* In Narrow (inline) mode:
|
|
878
|
+
* - Any number of walkthroughs can be open at once.
|
|
879
|
+
* - Opening/closing a message's walkthrough only affects that message's inline display.
|
|
880
|
+
*/
|
|
881
|
+
#toggleWalkthrough(isOpen: boolean, message: ModelChatMessage): void {
|
|
882
|
+
if (isOpen) { // If we are opening a walkthrough, ensure it's in our list of expanded messages.
|
|
883
|
+
this.#openWalkthrough(message);
|
|
884
|
+
return;
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
// If we are closing a walkthrough, remove it from the list of expanded messages.
|
|
888
|
+
this.#walkthrough.inlineExpandedMessages = this.#walkthrough.inlineExpandedMessages.filter(m => m !== message);
|
|
889
|
+
|
|
890
|
+
if (this.#walkthrough.isInlined) {
|
|
891
|
+
// In Narrow mode, the global expanded state tracks if at least one walkthrough is open.
|
|
892
|
+
this.#walkthrough.isExpanded = this.#walkthrough.inlineExpandedMessages.length > 0;
|
|
893
|
+
// If the message we just closed was the active one, we pick a new active message
|
|
894
|
+
// from the remaining open ones (if any). This ensures that if the user
|
|
895
|
+
// re-opens the sidebar later, it shows the most recently opened walkthrough.
|
|
896
|
+
if (this.#walkthrough.activeSidebarMessage === message) {
|
|
897
|
+
this.#walkthrough.activeSidebarMessage = this.#walkthrough.inlineExpandedMessages.at(-1) ?? null;
|
|
898
|
+
}
|
|
899
|
+
} else {
|
|
900
|
+
// In Wide mode, closing the sidebar means we are no longer expanded globally.
|
|
901
|
+
this.#walkthrough.isExpanded = false;
|
|
902
|
+
this.#walkthrough.activeSidebarMessage = null;
|
|
903
|
+
}
|
|
904
|
+
|
|
837
905
|
this.requestUpdate();
|
|
838
906
|
}
|
|
839
907
|
|
|
@@ -1563,9 +1631,10 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
1563
1631
|
this.#updateConversationState();
|
|
1564
1632
|
}
|
|
1565
1633
|
|
|
1566
|
-
#
|
|
1634
|
+
#resetWalkthrough(): void {
|
|
1567
1635
|
this.#walkthrough.isExpanded = false;
|
|
1568
|
-
this.#walkthrough.
|
|
1636
|
+
this.#walkthrough.activeSidebarMessage = null;
|
|
1637
|
+
this.#walkthrough.inlineExpandedMessages = [];
|
|
1569
1638
|
}
|
|
1570
1639
|
|
|
1571
1640
|
#onDeleteClicked(): void {
|
|
@@ -1574,7 +1643,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
1574
1643
|
}
|
|
1575
1644
|
|
|
1576
1645
|
// Ensure we clear the walkthrough so it doesn't hold onto a chat that is about to be deleted.
|
|
1577
|
-
this.#
|
|
1646
|
+
this.#resetWalkthrough();
|
|
1578
1647
|
|
|
1579
1648
|
void AiAssistanceModel.AiHistoryStorage.AiHistoryStorage.instance().deleteHistoryEntry(this.#conversation.id);
|
|
1580
1649
|
this.#updateConversationState();
|
|
@@ -1599,6 +1668,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
1599
1668
|
|
|
1600
1669
|
#handleNewChatRequest(): void {
|
|
1601
1670
|
this.#updateConversationState();
|
|
1671
|
+
this.#resetWalkthrough();
|
|
1602
1672
|
UI.ARIAUtils.LiveAnnouncer.alert(i18nString(UIStrings.newChatCreated));
|
|
1603
1673
|
|
|
1604
1674
|
if (Annotations.AnnotationRepository.annotationsEnabled()) {
|