chrome-devtools-frontend 1.0.1595925 → 1.0.1596260
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/.stylelintrc.json +3 -1
- package/docs/ui_engineering.md +0 -36
- package/front_end/core/host/UserMetrics.ts +0 -1
- package/front_end/core/root/ExperimentNames.ts +0 -1
- package/front_end/core/sdk/DOMModel.ts +206 -0
- package/front_end/core/sdk/SourceMapScopesInfo.ts +1 -1
- package/front_end/entrypoints/greendev_floaty/floaty.css +2 -2
- package/front_end/entrypoints/main/MainImpl.ts +0 -5
- package/front_end/models/ai_assistance/ConversationHandler.ts +1 -1
- package/front_end/models/ai_code_completion/AiCodeCompletion.ts +1 -1
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +2 -0
- package/front_end/panels/ai_assistance/components/ChatMessage.ts +48 -31
- package/front_end/panels/ai_assistance/components/WalkthroughView.ts +28 -4
- package/front_end/panels/ai_assistance/components/chatMessage.css +4 -2
- package/front_end/panels/application/IndexedDBModel.ts +2 -4
- package/front_end/panels/application/ServiceWorkersView.ts +3 -11
- package/front_end/panels/developer_resources/DeveloperResourcesListView.ts +1 -1
- package/front_end/panels/elements/ComputedStyleWidget.ts +25 -16
- package/front_end/panels/elements/ElementsPanel.ts +0 -1
- package/front_end/panels/elements/StylePropertyTreeElement.ts +11 -5
- package/front_end/panels/elements/nodeStackTraceWidget.css +1 -1
- package/front_end/panels/emulation/DeviceModeToolbar.ts +171 -89
- package/front_end/panels/greendev/GreenDevPanel.css +2 -2
- package/front_end/panels/issues/AffectedPermissionElementsView.ts +9 -6
- package/front_end/panels/profiler/HeapSnapshotGridNodes.ts +11 -3
- package/front_end/panels/settings/components/SyncSection.ts +4 -13
- package/front_end/panels/timeline/CompatibilityTracksAppender.ts +2 -15
- package/front_end/panels/timeline/RecordingMetadata.ts +1 -1
- package/front_end/panels/timeline/TimelineDetailsView.ts +2 -2
- package/front_end/panels/timeline/TimelineUIUtils.ts +7 -4
- package/front_end/panels/timeline/components/Utils.ts +2 -2
- package/front_end/panels/webauthn/webauthnPane.css +1 -1
- package/front_end/ui/components/tree_outline/TreeOutline.ts +1 -1
- package/front_end/ui/legacy/ProgressIndicator.ts +1 -1
- package/front_end/ui/legacy/Toolbar.ts +1 -1
- package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +14 -7
- package/front_end/ui/legacy/legacy.ts +0 -2
- package/front_end/ui/visual_logging/KnownContextValues.ts +4 -0
- package/inspector_overlay/loadCSS.rollup.js +2 -2
- package/inspector_overlay/tool_source_order.css +1 -0
- package/package.json +1 -1
- package/front_end/ui/legacy/Fragment.ts +0 -234
package/.stylelintrc.json
CHANGED
|
@@ -2,11 +2,13 @@
|
|
|
2
2
|
"extends": "stylelint-config-standard",
|
|
3
3
|
"plugins": [
|
|
4
4
|
"./scripts/stylelint_rules/lib/use_theme_colors.mjs",
|
|
5
|
-
"./scripts/stylelint_rules/lib/check_highlight_scope.mjs"
|
|
5
|
+
"./scripts/stylelint_rules/lib/check_highlight_scope.mjs",
|
|
6
|
+
"./scripts/stylelint_rules/lib/use_monospace_font.mjs"
|
|
6
7
|
],
|
|
7
8
|
"rules": {
|
|
8
9
|
"plugin/use_theme_colors": true,
|
|
9
10
|
"plugin/check_highlight_scope": true,
|
|
11
|
+
"plugin/use_monospace_font": true,
|
|
10
12
|
"alpha-value-notation": "percentage",
|
|
11
13
|
"color-function-notation": "modern",
|
|
12
14
|
"hue-degree-notation": "angle",
|
package/docs/ui_engineering.md
CHANGED
|
@@ -1183,42 +1183,6 @@ export const DEFAULT_VIEW = (input, _output, target) => {
|
|
|
1183
1183
|
};
|
|
1184
1184
|
```
|
|
1185
1185
|
|
|
1186
|
-
## Migrating `UI.Fragment`
|
|
1187
|
-
|
|
1188
|
-
Replace `UI.Fragment.Fragment.build` with a standard lit-html template. To get a reference to an element, use the `ref` directive.
|
|
1189
|
-
|
|
1190
|
-
**Before:**
|
|
1191
|
-
```typescript
|
|
1192
|
-
|
|
1193
|
-
class SomeWidget extends UI.Widget.Widget {
|
|
1194
|
-
constructor() {
|
|
1195
|
-
super();
|
|
1196
|
-
const contrastFragment = UI.Fragment.Fragment.build`
|
|
1197
|
-
<div class="contrast-container-in-grid" $="contrast-container-element">
|
|
1198
|
-
<span class="contrast-preview">Aa</span>
|
|
1199
|
-
<span>${contrastRatioString}</span>
|
|
1200
|
-
</div>`;
|
|
1201
|
-
this.contentElement.appendChild(contrastFragment.element());
|
|
1202
|
-
}
|
|
1203
|
-
}
|
|
1204
|
-
```
|
|
1205
|
-
|
|
1206
|
-
**After:**
|
|
1207
|
-
```typescript
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
export const DEFAULT_VIEW = (input, output, target) => {
|
|
1211
|
-
render(html`
|
|
1212
|
-
<div>
|
|
1213
|
-
<div class="contrast-container-in-grid" ${ref(e => { output.contrastContainerElement = e; })}>
|
|
1214
|
-
<span class="contrast-preview">Aa</span>
|
|
1215
|
-
<span>${contrastRatioString}</span>
|
|
1216
|
-
</div>
|
|
1217
|
-
</div>`,
|
|
1218
|
-
target, {host: input});
|
|
1219
|
-
};
|
|
1220
|
-
```
|
|
1221
|
-
|
|
1222
1186
|
## Migrating `UI.ARIAUtils` helpers
|
|
1223
1187
|
|
|
1224
1188
|
Replace calls to `UI.ARIAUtils` helper functions with the corresponding ARIA attributes directly in the lit-html template.
|
|
@@ -822,7 +822,6 @@ export enum DevtoolsExperiments {
|
|
|
822
822
|
'authored-deployed-grouping' = 63,
|
|
823
823
|
'just-my-code' = 65,
|
|
824
824
|
'use-source-map-scopes' = 76,
|
|
825
|
-
'timeline-show-postmessage-events' = 86,
|
|
826
825
|
'timeline-debug-mode' = 93,
|
|
827
826
|
'durable-messages' = 110,
|
|
828
827
|
'jpeg-xl' = 111,
|
|
@@ -20,7 +20,6 @@ export enum ExperimentName {
|
|
|
20
20
|
AUTHORED_DEPLOYED_GROUPING = 'authored-deployed-grouping',
|
|
21
21
|
JUST_MY_CODE = 'just-my-code',
|
|
22
22
|
USE_SOURCE_MAP_SCOPES = 'use-source-map-scopes',
|
|
23
|
-
TIMELINE_SHOW_POST_MESSAGE_EVENTS = 'timeline-show-postmessage-events',
|
|
24
23
|
TIMELINE_DEBUG_MODE = 'timeline-debug-mode',
|
|
25
24
|
DURABLE_MESSAGES = 'durable-messages',
|
|
26
25
|
JPEG_XL = 'jpeg-xl',
|
|
@@ -1223,6 +1223,122 @@ export class DOMNode extends Common.ObjectWrapper.ObjectWrapper<DOMNodeEventType
|
|
|
1223
1223
|
return this.domModel().nodeForId(response.nodeId);
|
|
1224
1224
|
}
|
|
1225
1225
|
|
|
1226
|
+
async takeSnapshot(ownerDocumentSnapshot?: DOMDocument): Promise<DOMNode> {
|
|
1227
|
+
const snapshot = (this instanceof DOMDocument) ? new DOMDocumentSnapshot(this.domModel(), {
|
|
1228
|
+
nodeId: this.id,
|
|
1229
|
+
backendNodeId: this.backendNodeId(),
|
|
1230
|
+
nodeType: this.nodeType(),
|
|
1231
|
+
nodeName: this.nodeName(),
|
|
1232
|
+
localName: this.localName(),
|
|
1233
|
+
nodeValue: this.nodeValueInternal,
|
|
1234
|
+
} as Protocol.DOM.Node) :
|
|
1235
|
+
new DOMNodeSnapshot(this.domModel());
|
|
1236
|
+
snapshot.id = this.id;
|
|
1237
|
+
snapshot.#backendNodeId = this.#backendNodeId;
|
|
1238
|
+
snapshot.#frameOwnerFrameId = this.#frameOwnerFrameId;
|
|
1239
|
+
snapshot.#nodeType = this.#nodeType;
|
|
1240
|
+
snapshot.#nodeName = this.#nodeName;
|
|
1241
|
+
snapshot.#localName = this.#localName;
|
|
1242
|
+
snapshot.nodeValueInternal = this.nodeValueInternal;
|
|
1243
|
+
snapshot.#pseudoType = this.#pseudoType;
|
|
1244
|
+
snapshot.#pseudoIdentifier = this.#pseudoIdentifier;
|
|
1245
|
+
snapshot.#shadowRootType = this.#shadowRootType;
|
|
1246
|
+
snapshot.#xmlVersion = this.#xmlVersion;
|
|
1247
|
+
snapshot.#isSVGNode = this.#isSVGNode;
|
|
1248
|
+
snapshot.#isScrollable = this.#isScrollable;
|
|
1249
|
+
snapshot.#affectedByStartingStyles = this.#affectedByStartingStyles;
|
|
1250
|
+
snapshot.ownerDocument =
|
|
1251
|
+
ownerDocumentSnapshot || ((snapshot instanceof DOMDocument) ? snapshot : this.ownerDocument);
|
|
1252
|
+
snapshot.#isInShadowTree = this.#isInShadowTree;
|
|
1253
|
+
snapshot.childNodeCountInternal = this.childNodeCountInternal;
|
|
1254
|
+
|
|
1255
|
+
if (snapshot instanceof DOMDocument && this instanceof DOMDocument) {
|
|
1256
|
+
snapshot.documentURL = this.documentURL;
|
|
1257
|
+
snapshot.baseURL = this.baseURL;
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1260
|
+
if (!this.childrenInternal && this.childNodeCountInternal > 0) {
|
|
1261
|
+
await this.getSubtree(1, false);
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1264
|
+
for (const [name, attr] of this.#attributes) {
|
|
1265
|
+
snapshot.#attributes.set(name, {name: attr.name, value: attr.value, _node: snapshot});
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1268
|
+
if (this.childrenInternal) {
|
|
1269
|
+
snapshot.childrenInternal = [];
|
|
1270
|
+
for (const child of this.childrenInternal) {
|
|
1271
|
+
const childSnapshot = await child.takeSnapshot(snapshot.ownerDocument || undefined);
|
|
1272
|
+
childSnapshot.parentNode = snapshot;
|
|
1273
|
+
childSnapshot.ownerDocument = (snapshot instanceof DOMDocument) ? snapshot : snapshot.ownerDocument;
|
|
1274
|
+
snapshot.childrenInternal.push(childSnapshot);
|
|
1275
|
+
if (childSnapshot.ownerDocument instanceof DOMDocument) {
|
|
1276
|
+
if (childSnapshot.nodeName() === 'HTML' && !childSnapshot.ownerDocument.documentElement) {
|
|
1277
|
+
childSnapshot.ownerDocument.documentElement = childSnapshot;
|
|
1278
|
+
}
|
|
1279
|
+
if (childSnapshot.nodeName() === 'BODY' && !childSnapshot.ownerDocument.body) {
|
|
1280
|
+
childSnapshot.ownerDocument.body = childSnapshot;
|
|
1281
|
+
}
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
for (const root of this.shadowRootsInternal) {
|
|
1287
|
+
const rootSnapshot = await root.takeSnapshot(snapshot.ownerDocument || undefined);
|
|
1288
|
+
rootSnapshot.parentNode = snapshot;
|
|
1289
|
+
rootSnapshot.ownerDocument = snapshot.ownerDocument;
|
|
1290
|
+
snapshot.shadowRootsInternal.push(rootSnapshot);
|
|
1291
|
+
}
|
|
1292
|
+
|
|
1293
|
+
if (this.templateContentInternal) {
|
|
1294
|
+
const templateSnapshot = await this.templateContentInternal.takeSnapshot(snapshot.ownerDocument || undefined);
|
|
1295
|
+
templateSnapshot.parentNode = snapshot;
|
|
1296
|
+
templateSnapshot.ownerDocument = snapshot.ownerDocument;
|
|
1297
|
+
snapshot.templateContentInternal = templateSnapshot;
|
|
1298
|
+
}
|
|
1299
|
+
|
|
1300
|
+
if (this.contentDocumentInternal) {
|
|
1301
|
+
const contentDocSnapshot = await this.contentDocumentInternal.takeSnapshot();
|
|
1302
|
+
contentDocSnapshot.parentNode = snapshot;
|
|
1303
|
+
snapshot.contentDocumentInternal = contentDocSnapshot as DOMDocumentSnapshot;
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1306
|
+
if (this.#importedDocument) {
|
|
1307
|
+
const importedDocSnapshot = await this.#importedDocument.takeSnapshot(snapshot.ownerDocument || undefined);
|
|
1308
|
+
importedDocSnapshot.parentNode = snapshot;
|
|
1309
|
+
importedDocSnapshot.ownerDocument = snapshot.ownerDocument;
|
|
1310
|
+
snapshot.#importedDocument = importedDocSnapshot;
|
|
1311
|
+
}
|
|
1312
|
+
|
|
1313
|
+
for (const [pseudoType, nodes] of this.#pseudoElements) {
|
|
1314
|
+
const snapshots = [];
|
|
1315
|
+
for (const node of nodes) {
|
|
1316
|
+
const pseudoSnapshot = await node.takeSnapshot(snapshot.ownerDocument || undefined);
|
|
1317
|
+
pseudoSnapshot.parentNode = snapshot;
|
|
1318
|
+
pseudoSnapshot.ownerDocument = snapshot.ownerDocument;
|
|
1319
|
+
snapshots.push(pseudoSnapshot);
|
|
1320
|
+
}
|
|
1321
|
+
snapshot.#pseudoElements.set(pseudoType, snapshots);
|
|
1322
|
+
}
|
|
1323
|
+
|
|
1324
|
+
// We intentionally preserve references to live nodes for assignedSlot and distributedNodes.
|
|
1325
|
+
// This allows slot adorners in the Elements panel to remain functional within the snapshot,
|
|
1326
|
+
// enabling users to resolve and jump to the actual nodes in the live DOM tree.
|
|
1327
|
+
if (this.#distributedNodes) {
|
|
1328
|
+
snapshot.#distributedNodes = [...this.#distributedNodes];
|
|
1329
|
+
}
|
|
1330
|
+
|
|
1331
|
+
snapshot.assignedSlot = this.assignedSlot;
|
|
1332
|
+
|
|
1333
|
+
snapshot.#retainedNodes = this.#retainedNodes;
|
|
1334
|
+
|
|
1335
|
+
if (this.#adoptedStyleSheets.length) {
|
|
1336
|
+
snapshot.setAdoptedStyleSheets(this.#adoptedStyleSheets.map(sheet => sheet.id));
|
|
1337
|
+
}
|
|
1338
|
+
|
|
1339
|
+
return snapshot;
|
|
1340
|
+
}
|
|
1341
|
+
|
|
1226
1342
|
classNames(): string[] {
|
|
1227
1343
|
const classes = this.getAttribute('class');
|
|
1228
1344
|
return classes ? classes.split(/\s+/) : [];
|
|
@@ -2176,6 +2292,96 @@ export class DOMModelUndoStack {
|
|
|
2176
2292
|
}
|
|
2177
2293
|
|
|
2178
2294
|
SDKModel.register(DOMModel, {capabilities: Capability.DOM, autostart: true});
|
|
2295
|
+
export class DOMNodeSnapshot extends DOMNode {
|
|
2296
|
+
override init(
|
|
2297
|
+
_doc: DOMDocument|null, _isInShadowTree: boolean, _payload: Protocol.DOM.Node,
|
|
2298
|
+
_retainedNodes?: Set<Protocol.DOM.BackendNodeId>|undefined): void {
|
|
2299
|
+
}
|
|
2300
|
+
|
|
2301
|
+
override setNodeName(_name: string, _callback?: ((arg0: string|null, arg1: DOMNode|null) => void)|undefined): void {
|
|
2302
|
+
}
|
|
2303
|
+
|
|
2304
|
+
override setNodeValue(_value: string, _callback?: ((arg0: string|null) => void)|undefined): void {
|
|
2305
|
+
}
|
|
2306
|
+
|
|
2307
|
+
override setAttribute(_name: string, _text: string, _callback?: ((arg0: string|null) => void)|undefined): void {
|
|
2308
|
+
}
|
|
2309
|
+
|
|
2310
|
+
override setAttributeValue(_name: string, _value: string, _callback?: ((arg0: string|null) => void)|undefined): void {
|
|
2311
|
+
}
|
|
2312
|
+
|
|
2313
|
+
override removeAttribute(_name: string): Promise<void> {
|
|
2314
|
+
return Promise.resolve();
|
|
2315
|
+
}
|
|
2316
|
+
|
|
2317
|
+
override setOuterHTML(_html: string, _callback?: ((arg0: string|null) => void)|undefined): void {
|
|
2318
|
+
}
|
|
2319
|
+
|
|
2320
|
+
override removeNode(_callback?: ((arg0: string|null, arg1?: Protocol.DOM.NodeId|undefined) => void)|undefined):
|
|
2321
|
+
Promise<void> {
|
|
2322
|
+
return Promise.resolve();
|
|
2323
|
+
}
|
|
2324
|
+
|
|
2325
|
+
override copyTo(
|
|
2326
|
+
_targetNode: DOMNode, _anchorNode: DOMNode|null,
|
|
2327
|
+
_callback?: ((arg0: string|null, arg1: DOMNode|null) => void)|undefined): void {
|
|
2328
|
+
}
|
|
2329
|
+
|
|
2330
|
+
override moveTo(
|
|
2331
|
+
_targetNode: DOMNode, _anchorNode: DOMNode|null,
|
|
2332
|
+
_callback?: ((arg0: string|null, arg1: DOMNode|null) => void)|undefined): void {
|
|
2333
|
+
}
|
|
2334
|
+
|
|
2335
|
+
override setAsInspectedNode(): Promise<void> {
|
|
2336
|
+
return Promise.resolve();
|
|
2337
|
+
}
|
|
2338
|
+
}
|
|
2339
|
+
|
|
2340
|
+
export class DOMDocumentSnapshot extends DOMDocument {
|
|
2341
|
+
override init(
|
|
2342
|
+
_doc: DOMDocument|null, _isInShadowTree: boolean, _payload: Protocol.DOM.Node,
|
|
2343
|
+
_retainedNodes?: Set<Protocol.DOM.BackendNodeId>|undefined): void {
|
|
2344
|
+
}
|
|
2345
|
+
|
|
2346
|
+
override setNodeName(_name: string, _callback?: ((arg0: string|null, arg1: DOMNode|null) => void)|undefined): void {
|
|
2347
|
+
}
|
|
2348
|
+
|
|
2349
|
+
override setNodeValue(_value: string, _callback?: ((arg0: string|null) => void)|undefined): void {
|
|
2350
|
+
}
|
|
2351
|
+
|
|
2352
|
+
override setAttribute(_name: string, _text: string, _callback?: ((arg0: string|null) => void)|undefined): void {
|
|
2353
|
+
}
|
|
2354
|
+
|
|
2355
|
+
override setAttributeValue(_name: string, _value: string, _callback?: ((arg0: string|null) => void)|undefined): void {
|
|
2356
|
+
}
|
|
2357
|
+
|
|
2358
|
+
override removeAttribute(_name: string): Promise<void> {
|
|
2359
|
+
return Promise.resolve();
|
|
2360
|
+
}
|
|
2361
|
+
|
|
2362
|
+
override setOuterHTML(_html: string, _callback?: ((arg0: string|null) => void)|undefined): void {
|
|
2363
|
+
}
|
|
2364
|
+
|
|
2365
|
+
override removeNode(_callback?: ((arg0: string|null, arg1?: Protocol.DOM.NodeId|undefined) => void)|undefined):
|
|
2366
|
+
Promise<void> {
|
|
2367
|
+
return Promise.resolve();
|
|
2368
|
+
}
|
|
2369
|
+
|
|
2370
|
+
override copyTo(
|
|
2371
|
+
_targetNode: DOMNode, _anchorNode: DOMNode|null,
|
|
2372
|
+
_callback?: ((arg0: string|null, arg1: DOMNode|null) => void)|undefined): void {
|
|
2373
|
+
}
|
|
2374
|
+
|
|
2375
|
+
override moveTo(
|
|
2376
|
+
_targetNode: DOMNode, _anchorNode: DOMNode|null,
|
|
2377
|
+
_callback?: ((arg0: string|null, arg1: DOMNode|null) => void)|undefined): void {
|
|
2378
|
+
}
|
|
2379
|
+
|
|
2380
|
+
override setAsInspectedNode(): Promise<void> {
|
|
2381
|
+
return Promise.resolve();
|
|
2382
|
+
}
|
|
2383
|
+
}
|
|
2384
|
+
|
|
2179
2385
|
export interface Attribute {
|
|
2180
2386
|
name: string;
|
|
2181
2387
|
value: string;
|
|
@@ -418,7 +418,7 @@ export class SourceMapScopesInfo {
|
|
|
418
418
|
* Returns the authored function name of the function containing the provided generated position.
|
|
419
419
|
*/
|
|
420
420
|
findOriginalFunctionName(position: ScopesCodec.Position): string|null {
|
|
421
|
-
const originalInnerMostScope = this.findOriginalFunctionScope(position)?.scope
|
|
421
|
+
const originalInnerMostScope = this.findOriginalFunctionScope(position)?.scope;
|
|
422
422
|
return this.#findFunctionNameInOriginalScopeChain(originalInnerMostScope);
|
|
423
423
|
}
|
|
424
424
|
|
|
@@ -134,7 +134,7 @@ html, body {
|
|
|
134
134
|
margin-top: 8px;
|
|
135
135
|
padding-top: 8px;
|
|
136
136
|
border-top: 1px solid #eee;
|
|
137
|
-
font-family: monospace;
|
|
137
|
+
font-family: var(--monospace-font-family);
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
.thought, .action {
|
|
@@ -186,7 +186,7 @@ html, body {
|
|
|
186
186
|
|
|
187
187
|
.green-dev-floaty-dialog-node-description {
|
|
188
188
|
font-size: 11px;
|
|
189
|
-
font-family: monospace;
|
|
189
|
+
font-family: var(--monospace-font-family);
|
|
190
190
|
color: #0b57d0;
|
|
191
191
|
background-color: #d3e3fd;
|
|
192
192
|
padding: 2px 8px;
|
|
@@ -413,11 +413,6 @@ export class MainImpl {
|
|
|
413
413
|
Root.Runtime.experiments.register(
|
|
414
414
|
Root.ExperimentNames.ExperimentName.JUST_MY_CODE, 'Hide ignore-listed code in Sources tree view');
|
|
415
415
|
|
|
416
|
-
Root.Runtime.experiments.register(
|
|
417
|
-
Root.ExperimentNames.ExperimentName.TIMELINE_SHOW_POST_MESSAGE_EVENTS,
|
|
418
|
-
'Performance panel: show postMessage dispatch and handling flows',
|
|
419
|
-
);
|
|
420
|
-
|
|
421
416
|
Root.Runtime.experiments.registerHostExperiment({
|
|
422
417
|
name: Root.ExperimentNames.ExperimentName.DURABLE_MESSAGES,
|
|
423
418
|
title: 'Durable Messages',
|
|
@@ -129,7 +129,7 @@ export class ConversationHandler extends Common.ObjectWrapper.ObjectWrapper<Even
|
|
|
129
129
|
}): ConversationHandler {
|
|
130
130
|
if (opts?.forceNew || conversationHandlerInstance === undefined) {
|
|
131
131
|
const aidaClient = opts?.aidaClient ?? new Host.AidaClient.AidaClient();
|
|
132
|
-
conversationHandlerInstance = new ConversationHandler(aidaClient, opts?.aidaAvailability
|
|
132
|
+
conversationHandlerInstance = new ConversationHandler(aidaClient, opts?.aidaAvailability);
|
|
133
133
|
}
|
|
134
134
|
return conversationHandlerInstance;
|
|
135
135
|
}
|
|
@@ -169,7 +169,7 @@ export class AiCodeCompletion {
|
|
|
169
169
|
// As a temporary fix for b/441221870 we are prepending a newline for each prefix.
|
|
170
170
|
prefix = '\n' + prefix;
|
|
171
171
|
|
|
172
|
-
let additionalContextFiles = additionalFiles
|
|
172
|
+
let additionalContextFiles = additionalFiles;
|
|
173
173
|
if (!additionalContextFiles) {
|
|
174
174
|
additionalContextFiles = this.#panel === ContextFlavor.CONSOLE ? [{
|
|
175
175
|
path: 'devtools-console-context.js',
|
|
@@ -761,6 +761,8 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
761
761
|
if (isNarrow === this.#walkthrough.isInlined) {
|
|
762
762
|
return;
|
|
763
763
|
}
|
|
764
|
+
// If the UI changed, we reset the visibility of the AI Walkthrough.
|
|
765
|
+
this.#clearWalkthrough();
|
|
764
766
|
this.#walkthrough.isInlined = isNarrow;
|
|
765
767
|
this.requestUpdate();
|
|
766
768
|
}
|
|
@@ -11,6 +11,7 @@ import * as i18n from '../../../core/i18n/i18n.js';
|
|
|
11
11
|
import type * as Platform from '../../../core/platform/platform.js';
|
|
12
12
|
import * as Root from '../../../core/root/root.js';
|
|
13
13
|
import * as SDK from '../../../core/sdk/sdk.js';
|
|
14
|
+
import type * as Protocol from '../../../generated/protocol.js';
|
|
14
15
|
import type {AiWidget, ComputedStyleAiWidget} from '../../../models/ai_assistance/agents/AiAgent.js';
|
|
15
16
|
import * as AiAssistanceModel from '../../../models/ai_assistance/ai_assistance.js';
|
|
16
17
|
import * as ComputedStyle from '../../../models/computed_style/computed_style.js';
|
|
@@ -278,6 +279,7 @@ export interface MessageInput {
|
|
|
278
279
|
isExpanded: boolean,
|
|
279
280
|
onToggle: (isOpen: boolean) => void,
|
|
280
281
|
isInlined: boolean,
|
|
282
|
+
activeMessage: ModelChatMessage|null,
|
|
281
283
|
};
|
|
282
284
|
}
|
|
283
285
|
|
|
@@ -483,14 +485,18 @@ function renderStepDetails({
|
|
|
483
485
|
|
|
484
486
|
function renderWalkthroughSidebarButton(
|
|
485
487
|
input: ChatMessageViewInput,
|
|
486
|
-
|
|
488
|
+
steps: Step[],
|
|
487
489
|
): Lit.LitTemplate {
|
|
488
490
|
const {message, walkthrough} = input;
|
|
489
|
-
|
|
491
|
+
const lastStep = steps.at(-1);
|
|
492
|
+
if (walkthrough.isInlined || !lastStep) {
|
|
490
493
|
return Lit.nothing;
|
|
491
494
|
}
|
|
495
|
+
|
|
496
|
+
const hasOneStepWithWidget = steps.some(step => step.widgets?.length);
|
|
492
497
|
const title = walkthroughTitle({
|
|
493
498
|
isLoading: input.isLoading,
|
|
499
|
+
hasWidgets: hasOneStepWithWidget,
|
|
494
500
|
lastStep,
|
|
495
501
|
});
|
|
496
502
|
|
|
@@ -505,7 +511,7 @@ function renderWalkthroughSidebarButton(
|
|
|
505
511
|
.jslogContext=${walkthrough.isExpanded ? 'ai-hide-walkthrough-sidebar' : 'ai-show-walkthrough-sidebar'}
|
|
506
512
|
data-show-walkthrough
|
|
507
513
|
@click=${() => {
|
|
508
|
-
if(walkthrough.isExpanded) {
|
|
514
|
+
if(walkthrough.activeMessage === input.message && walkthrough.isExpanded) {
|
|
509
515
|
walkthrough.onToggle(false);
|
|
510
516
|
} else {
|
|
511
517
|
// Can't just toggle the visibility here; we need to ensure we
|
|
@@ -535,7 +541,7 @@ function renderWalkthroughUI(input: ChatMessageViewInput, steps: Step[]): Lit.Li
|
|
|
535
541
|
// If the walkthrough is in the sidebar, we render a button into the
|
|
536
542
|
// ChatView to open it.
|
|
537
543
|
const openWalkThroughSidebarButton =
|
|
538
|
-
!input.walkthrough.isInlined ? renderWalkthroughSidebarButton(input,
|
|
544
|
+
!input.walkthrough.isInlined ? renderWalkthroughSidebarButton(input, steps) : Lit.nothing;
|
|
539
545
|
|
|
540
546
|
// If there are side-effect steps, and the walkthrough is not open, we render
|
|
541
547
|
// those inline so that the user can see them and approve them.
|
|
@@ -554,6 +560,9 @@ function renderWalkthroughUI(input: ChatMessageViewInput, steps: Step[]): Lit.Li
|
|
|
554
560
|
|
|
555
561
|
// If the walkthrough is inlined (narrow width screens), render it here.
|
|
556
562
|
// Note that we force it open if there is a side-effect.
|
|
563
|
+
|
|
564
|
+
const isExpanded = (input.walkthrough.isExpanded && input.walkthrough.activeMessage === input.message) ||
|
|
565
|
+
steps.some(s => s.requestApproval);
|
|
557
566
|
// clang-format off
|
|
558
567
|
const walkthroughInline = input.walkthrough.isInlined ? html`
|
|
559
568
|
<div class="walkthrough-container">
|
|
@@ -562,9 +571,9 @@ function renderWalkthroughUI(input: ChatMessageViewInput, steps: Step[]): Lit.Li
|
|
|
562
571
|
isLoading: input.isLoading && input.isLastMessage,
|
|
563
572
|
markdownRenderer: input.markdownRenderer,
|
|
564
573
|
isInlined: true,
|
|
565
|
-
isExpanded
|
|
566
|
-
(input.walkthrough.isExpanded || steps.some(step => Boolean(step.requestApproval))),
|
|
574
|
+
isExpanded,
|
|
567
575
|
onToggle: input.walkthrough.onToggle,
|
|
576
|
+
onOpen: input.walkthrough.onOpen,
|
|
568
577
|
})}></devtools-widget>
|
|
569
578
|
</div>
|
|
570
579
|
` : Lit.nothing;
|
|
@@ -649,37 +658,42 @@ interface WidgetMakerResponse {
|
|
|
649
658
|
revealable: unknown;
|
|
650
659
|
}
|
|
651
660
|
|
|
661
|
+
const computedStyleNodeCache = new Map<Protocol.DOM.BackendNodeId, SDK.DOMModel.DOMNode>();
|
|
662
|
+
|
|
652
663
|
async function makeComputedStyleWidget(widgetData: ComputedStyleAiWidget): Promise<WidgetMakerResponse|null> {
|
|
653
|
-
|
|
654
|
-
if (!
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
+
let domNodeForId = computedStyleNodeCache.get(widgetData.data.backendNodeId);
|
|
665
|
+
if (!domNodeForId) {
|
|
666
|
+
const target = SDK.TargetManager.TargetManager.instance().primaryPageTarget();
|
|
667
|
+
if (!target) {
|
|
668
|
+
return null;
|
|
669
|
+
}
|
|
670
|
+
const node = new SDK.DOMModel.DeferredDOMNode(
|
|
671
|
+
target,
|
|
672
|
+
widgetData.data.backendNodeId,
|
|
673
|
+
);
|
|
674
|
+
const resolved = await node.resolvePromise();
|
|
675
|
+
if (!resolved) {
|
|
676
|
+
return null;
|
|
677
|
+
}
|
|
678
|
+
domNodeForId = resolved;
|
|
679
|
+
computedStyleNodeCache.set(widgetData.data.backendNodeId, resolved);
|
|
664
680
|
}
|
|
665
|
-
const
|
|
666
|
-
const styles = new ComputedStyle.ComputedStyleModel.ComputedStyle(resolved, widgetData.data.computedStyles);
|
|
681
|
+
const styles = new ComputedStyle.ComputedStyleModel.ComputedStyle(domNodeForId, widgetData.data.computedStyles);
|
|
667
682
|
|
|
668
683
|
const widgetConfig = UI.Widget.widgetConfig(Elements.ComputedStyleWidget.ComputedStyleWidget, {
|
|
669
684
|
nodeStyle: styles,
|
|
670
685
|
matchedStyles: widgetData.data.matchedCascade,
|
|
671
686
|
// This disables showing the nested traces and detailed information in the widget.
|
|
672
687
|
propertyTraces: null,
|
|
673
|
-
computedStyleModel: model,
|
|
674
688
|
allowUserControl: false,
|
|
675
689
|
filterText: new RegExp(widgetData.data.properties.join('|'), 'i')
|
|
676
690
|
});
|
|
677
691
|
|
|
678
692
|
// clang-format off
|
|
679
|
-
|
|
693
|
+
const widget = html`<devtools-widget class="computed-styles-widget" .widgetConfig=${widgetConfig}></devtools-widget>`;
|
|
680
694
|
// clang-format on
|
|
681
695
|
|
|
682
|
-
return {renderedWidget: widget, revealable: new Elements.ElementsPanel.NodeComputedStyles(
|
|
696
|
+
return {renderedWidget: widget, revealable: new Elements.ElementsPanel.NodeComputedStyles(domNodeForId)};
|
|
683
697
|
}
|
|
684
698
|
|
|
685
699
|
function renderWidgetResponse(response: WidgetMakerResponse|null): Lit.LitTemplate {
|
|
@@ -696,15 +710,17 @@ function renderWidgetResponse(response: WidgetMakerResponse|null): Lit.LitTempla
|
|
|
696
710
|
|
|
697
711
|
// clang-format off
|
|
698
712
|
return html`
|
|
699
|
-
<div class="widget-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
<
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
713
|
+
<div class="widget-and-revealer-container">
|
|
714
|
+
<div class="widget-content-container">
|
|
715
|
+
${response.renderedWidget}
|
|
716
|
+
</div>
|
|
717
|
+
<div class="widget-reveal-container">
|
|
718
|
+
<devtools-button class="widget-reveal"
|
|
719
|
+
.iconName=${'tab-move'}
|
|
720
|
+
.variant=${Buttons.Button.Variant.TEXT}
|
|
721
|
+
@click=${onReveal}
|
|
722
|
+
>${lockedString(UIStringsNotTranslate.reveal)}</devtools-button>
|
|
723
|
+
</div>
|
|
708
724
|
</div>
|
|
709
725
|
`;
|
|
710
726
|
// clang-format on
|
|
@@ -994,6 +1010,7 @@ export class ChatMessage extends UI.Widget.Widget {
|
|
|
994
1010
|
onToggle: () => {},
|
|
995
1011
|
isInlined: false,
|
|
996
1012
|
isExpanded: false,
|
|
1013
|
+
activeMessage: null,
|
|
997
1014
|
};
|
|
998
1015
|
|
|
999
1016
|
#suggestionsResizeObserver = new ResizeObserver(() => this.#handleSuggestionsScrollOrResize());
|
|
@@ -27,9 +27,13 @@ const UIStrings = {
|
|
|
27
27
|
*/
|
|
28
28
|
title: 'Investigation steps',
|
|
29
29
|
/**
|
|
30
|
-
* @description Title for the button that shows the
|
|
30
|
+
* @description Title for the button that shows the walkthrough when there are no widgets in the walkthrough.
|
|
31
31
|
*/
|
|
32
32
|
showThinking: 'Show thinking',
|
|
33
|
+
/**
|
|
34
|
+
* @description Title for the button that shows the walkthrough when there are widgets in the walkthrough.
|
|
35
|
+
*/
|
|
36
|
+
showAgentWalkthrough: 'Show agent walkthrough',
|
|
33
37
|
} as const;
|
|
34
38
|
const str_ = i18n.i18n.registerUIStrings('panels/ai_assistance/components/WalkthroughView.ts', UIStrings);
|
|
35
39
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
@@ -41,14 +45,21 @@ export interface ViewInput {
|
|
|
41
45
|
isInlined: boolean;
|
|
42
46
|
isExpanded: boolean;
|
|
43
47
|
onToggle: (isOpen: boolean) => void;
|
|
48
|
+
onOpen: (message: ModelChatMessage) => void;
|
|
44
49
|
}
|
|
45
50
|
|
|
46
51
|
export function walkthroughTitle(input: {
|
|
47
52
|
isLoading: boolean,
|
|
53
|
+
hasWidgets: boolean,
|
|
48
54
|
lastStep: Step,
|
|
49
55
|
}): string {
|
|
50
|
-
|
|
51
|
-
|
|
56
|
+
if (input.isLoading) {
|
|
57
|
+
return titleForStep(input.lastStep);
|
|
58
|
+
}
|
|
59
|
+
if (input.hasWidgets) {
|
|
60
|
+
return lockedString(UIStrings.showAgentWalkthrough);
|
|
61
|
+
}
|
|
62
|
+
return lockedString(UIStrings.showThinking);
|
|
52
63
|
}
|
|
53
64
|
|
|
54
65
|
function renderInlineWalkthrough(input: ViewInput, stepsOutput: Lit.LitTemplate, steps: Step[]): Lit.LitTemplate {
|
|
@@ -61,12 +72,14 @@ function renderInlineWalkthrough(input: ViewInput, stepsOutput: Lit.LitTemplate,
|
|
|
61
72
|
input.onToggle((event.target as HTMLDetailsElement).open);
|
|
62
73
|
}
|
|
63
74
|
|
|
75
|
+
const hasWidgets = steps.some(s => s.widgets?.length);
|
|
76
|
+
|
|
64
77
|
// clang-format off
|
|
65
78
|
return html`
|
|
66
79
|
<details class="walkthrough-inline" ?open=${input.isExpanded} @toggle=${onToggle}>
|
|
67
80
|
<summary>
|
|
68
81
|
${input.isLoading ? html`<devtools-spinner></devtools-spinner>` : Lit.nothing}
|
|
69
|
-
${walkthroughTitle({isLoading: input.isLoading, lastStep,})}
|
|
82
|
+
${walkthroughTitle({isLoading: input.isLoading, lastStep, hasWidgets})}
|
|
70
83
|
<devtools-icon name="chevron-down"></devtools-icon>
|
|
71
84
|
</summary>
|
|
72
85
|
${stepsOutput}
|
|
@@ -155,6 +168,7 @@ export class WalkthroughView extends UI.Widget.Widget {
|
|
|
155
168
|
#isLoading = false;
|
|
156
169
|
#markdownRenderer: MarkdownLitRenderer|null = null;
|
|
157
170
|
#onToggle: (isOpen: boolean) => void = () => {};
|
|
171
|
+
#onOpen: (message: ModelChatMessage) => void = () => {};
|
|
158
172
|
#isInlined = false;
|
|
159
173
|
#isExpanded = false;
|
|
160
174
|
|
|
@@ -185,6 +199,15 @@ export class WalkthroughView extends UI.Widget.Widget {
|
|
|
185
199
|
return this.#message;
|
|
186
200
|
}
|
|
187
201
|
|
|
202
|
+
get onOpen(): (message: ModelChatMessage) => void {
|
|
203
|
+
return this.#onOpen;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
set onOpen(onOpen: (message: ModelChatMessage) => void) {
|
|
207
|
+
this.#onOpen = onOpen;
|
|
208
|
+
this.requestUpdate();
|
|
209
|
+
}
|
|
210
|
+
|
|
188
211
|
set message(message: ModelChatMessage|null) {
|
|
189
212
|
this.#message = message;
|
|
190
213
|
this.requestUpdate();
|
|
@@ -214,6 +237,7 @@ export class WalkthroughView extends UI.Widget.Widget {
|
|
|
214
237
|
isLoading: this.#isLoading,
|
|
215
238
|
markdownRenderer: this.#markdownRenderer,
|
|
216
239
|
onToggle: this.#onToggle,
|
|
240
|
+
onOpen: this.#onOpen,
|
|
217
241
|
isInlined: this.#isInlined,
|
|
218
242
|
isExpanded: this.#isExpanded,
|
|
219
243
|
message: this.#message,
|
|
@@ -364,10 +364,13 @@
|
|
|
364
364
|
|
|
365
365
|
.step-widgets-wrapper {
|
|
366
366
|
width: fit-content;
|
|
367
|
+
display: flex;
|
|
368
|
+
flex-direction: column;
|
|
369
|
+
align-items: flex-start;
|
|
370
|
+
gap: var(--sys-size-5);
|
|
367
371
|
}
|
|
368
372
|
|
|
369
373
|
.widget-reveal-container {
|
|
370
|
-
width: 100%;
|
|
371
374
|
background: var(--sys-color-surface5);
|
|
372
375
|
border-bottom-right-radius: var(--sys-shape-corner-medium);
|
|
373
376
|
border-bottom-left-radius: var(--sys-shape-corner-medium);
|
|
@@ -378,7 +381,6 @@
|
|
|
378
381
|
padding: var(--sys-size-4);
|
|
379
382
|
border-top-left-radius: var(--sys-shape-corner-medium);
|
|
380
383
|
border-top-right-radius: var(--sys-shape-corner-medium);
|
|
381
|
-
width: 100%;
|
|
382
384
|
overflow-x: auto;
|
|
383
385
|
background-color: var(--sys-color-surface3);
|
|
384
386
|
|
|
@@ -143,8 +143,7 @@ export class IndexedDBModel extends SDK.SDKModel.SDKModel<EventTypes> implements
|
|
|
143
143
|
}
|
|
144
144
|
|
|
145
145
|
for (const [storageBucketName] of this.databaseNamesByStorageKeyAndBucket.get(storageKey) || []) {
|
|
146
|
-
const storageBucket =
|
|
147
|
-
this.storageBucketModel?.getBucketByName(storageKey, storageBucketName ?? undefined)?.bucket;
|
|
146
|
+
const storageBucket = this.storageBucketModel?.getBucketByName(storageKey, storageBucketName)?.bucket;
|
|
148
147
|
if (storageBucket) {
|
|
149
148
|
this.removeStorageBucket(storageBucket);
|
|
150
149
|
}
|
|
@@ -169,8 +168,7 @@ export class IndexedDBModel extends SDK.SDKModel.SDKModel<EventTypes> implements
|
|
|
169
168
|
for (const [storageKey] of this.databaseNamesByStorageKeyAndBucket) {
|
|
170
169
|
const storageBucketNames = this.databaseNamesByStorageKeyAndBucket.get(storageKey)?.keys() || [];
|
|
171
170
|
for (const storageBucketName of storageBucketNames) {
|
|
172
|
-
const storageBucket =
|
|
173
|
-
this.storageBucketModel?.getBucketByName(storageKey, storageBucketName ?? undefined)?.bucket;
|
|
171
|
+
const storageBucket = this.storageBucketModel?.getBucketByName(storageKey, storageBucketName)?.bucket;
|
|
174
172
|
if (storageBucket) {
|
|
175
173
|
await this.loadDatabaseNamesByStorageBucket(storageBucket);
|
|
176
174
|
}
|