chrome-devtools-frontend 1.0.1611099 → 1.0.1611825
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/front_end/core/host/AidaClientTypes.ts +5 -0
- package/front_end/core/host/AidaGcaTranslation.ts +2 -1
- package/front_end/core/sdk/ResourceTreeModel.ts +2 -1
- package/front_end/core/sdk/Target.ts +1 -3
- package/front_end/generated/InspectorBackendCommands.ts +1 -1
- package/front_end/generated/SupportedCSSProperties.js +4 -0
- package/front_end/generated/protocol.ts +0 -8
- package/front_end/models/web_mcp/WebMCPModel.ts +73 -18
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +2 -3
- package/front_end/panels/ai_assistance/components/ChatMessage.ts +30 -7
- package/front_end/panels/ai_assistance/components/ExportForAgentsDialog.ts +8 -4
- package/front_end/panels/ai_assistance/components/WalkthroughView.ts +6 -2
- package/front_end/panels/ai_assistance/components/exportForAgentsDialog.css +1 -1
- package/front_end/panels/ai_assistance/components/walkthroughView.css +18 -17
- package/front_end/panels/application/WebMCPView.ts +97 -6
- package/front_end/panels/application/webMCPView.css +7 -1
- package/front_end/panels/console/ConsolePinPane.ts +6 -2
- package/front_end/panels/sources/BreakpointEditDialog.ts +6 -0
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/third_party/lighthouse/README.chromium +2 -2
- package/front_end/third_party/lighthouse/lighthouse-dt-bundle.js +5635 -1498
- package/front_end/third_party/lighthouse/locales/en-GB.json +2 -2
- package/front_end/third_party/lighthouse/locales/en-US.json +14 -2
- package/front_end/third_party/lighthouse/locales/en-XL.json +12 -0
- package/front_end/third_party/lighthouse/report/bundle.d.ts +4 -4
- package/front_end/third_party/lighthouse/report/bundle.js +30 -3
- package/front_end/third_party/lighthouse/report-assets/report-generator.mjs +2 -2
- package/front_end/ui/components/markdown_view/CodeBlock.ts +6 -0
- package/front_end/ui/legacy/components/settings_ui/SettingsUI.ts +83 -68
- package/front_end/ui/visual_logging/KnownContextValues.ts +5 -0
- package/front_end/ui/visual_logging/LoggingDriver.ts +3 -3
- package/mcp/mcp.ts +2 -1
- package/package.json +1 -1
|
@@ -384,10 +384,15 @@ export interface FactualityMetadata {
|
|
|
384
384
|
facts: FactualityFact[];
|
|
385
385
|
}
|
|
386
386
|
|
|
387
|
+
export interface InferenceOptionMetadata {
|
|
388
|
+
modelId: string;
|
|
389
|
+
}
|
|
390
|
+
|
|
387
391
|
export interface ResponseMetadata {
|
|
388
392
|
rpcGlobalId?: RpcGlobalId;
|
|
389
393
|
attributionMetadata?: AttributionMetadata;
|
|
390
394
|
factualityMetadata?: FactualityMetadata;
|
|
395
|
+
inferenceOptionMetadata?: InferenceOptionMetadata;
|
|
391
396
|
}
|
|
392
397
|
|
|
393
398
|
export interface DoConversationResponse {
|
|
@@ -360,7 +360,7 @@ function gcaCandidateToAidaGenerationSample(candidate: GCA.Candidate): AIDA.Gene
|
|
|
360
360
|
|
|
361
361
|
function convertAidaFactsToGcaContent(facts: AIDA.RequestFact[]): GCA.Content {
|
|
362
362
|
return {
|
|
363
|
-
role: '
|
|
363
|
+
role: 'user',
|
|
364
364
|
parts: facts.map(fact => {
|
|
365
365
|
return {text: `[source: ${fact.metadata.source}] ${fact.text}`};
|
|
366
366
|
}),
|
|
@@ -454,6 +454,7 @@ export function gcaChunkResponseToAidaChunkResponse(response: GCA.GenerateConten
|
|
|
454
454
|
const parts = candidate?.content?.parts || [];
|
|
455
455
|
const metadata: AIDA.ResponseMetadata = {
|
|
456
456
|
rpcGlobalId: response.responseId,
|
|
457
|
+
inferenceOptionMetadata: {modelId: response.modelVersion}
|
|
457
458
|
};
|
|
458
459
|
|
|
459
460
|
if (candidate?.citationMetadata?.citations) {
|
|
@@ -858,7 +858,8 @@ export class ResourceTreeFrame {
|
|
|
858
858
|
* https://chromium.googlesource.com/chromium/src/+/HEAD/docs/frame_trees.md
|
|
859
859
|
*/
|
|
860
860
|
isPrimaryFrame(): boolean {
|
|
861
|
-
return !this.#sameTargetParentFrame &&
|
|
861
|
+
return !this.#sameTargetParentFrame &&
|
|
862
|
+
this.#model.target() === this.#model.target().targetManager().primaryPageTarget();
|
|
862
863
|
}
|
|
863
864
|
|
|
864
865
|
removeChildFrame(frame: ResourceTreeFrame, isSwap: boolean): void {
|
|
@@ -70,9 +70,7 @@ export class Target extends ProtocolClient.InspectorBackend.TargetBase {
|
|
|
70
70
|
this.#capabilitiesMask = Capability.JS | Capability.LOG | Capability.NETWORK | Capability.TARGET |
|
|
71
71
|
Capability.INSPECTOR | Capability.IO | Capability.EVENT_BREAKPOINTS;
|
|
72
72
|
if (parentTarget?.type() !== Type.FRAME) {
|
|
73
|
-
|
|
74
|
-
// crashers in https://crbug.com/466134219 have to be resolved.
|
|
75
|
-
this.#capabilitiesMask |= Capability.BROWSER;
|
|
73
|
+
this.#capabilitiesMask |= Capability.BROWSER | Capability.STORAGE;
|
|
76
74
|
}
|
|
77
75
|
break;
|
|
78
76
|
case Type.SHARED_WORKER:
|
|
@@ -895,7 +895,7 @@ inspectorBackend.registerCommand("Network.enableReportingApi", [{"name": "enable
|
|
|
895
895
|
inspectorBackend.registerCommand("Network.enableDeviceBoundSessions", [{"name": "enable", "type": "boolean", "optional": false, "description": "Whether to enable or disable events.", "typeRef": null}], [], "Sets up tracking device bound sessions and fetching of initial set of sessions.");
|
|
896
896
|
inspectorBackend.registerCommand("Network.fetchSchemefulSite", [{"name": "origin", "type": "string", "optional": false, "description": "The URL origin.", "typeRef": null}], ["schemefulSite"], "Fetches the schemeful site for a specific origin.");
|
|
897
897
|
inspectorBackend.registerCommand("Network.loadNetworkResource", [{"name": "frameId", "type": "string", "optional": true, "description": "Frame id to get the resource for. Mandatory for frame targets, and should be omitted for worker targets.", "typeRef": "Page.FrameId"}, {"name": "url", "type": "string", "optional": false, "description": "URL of the resource to get content for.", "typeRef": null}, {"name": "options", "type": "object", "optional": false, "description": "Options for the request.", "typeRef": "Network.LoadNetworkResourceOptions"}], ["resource"], "Fetches the resource and returns the content.");
|
|
898
|
-
inspectorBackend.registerCommand("Network.setCookieControls", [{"name": "enableThirdPartyCookieRestriction", "type": "boolean", "optional": false, "description": "Whether 3pc restriction is enabled.", "typeRef": null}
|
|
898
|
+
inspectorBackend.registerCommand("Network.setCookieControls", [{"name": "enableThirdPartyCookieRestriction", "type": "boolean", "optional": false, "description": "Whether 3pc restriction is enabled.", "typeRef": null}], [], "Sets Controls for third-party cookie access Page reload is required before the new cookie behavior will be observed");
|
|
899
899
|
inspectorBackend.registerType("Network.ResourceTiming", [{"name": "requestTime", "type": "number", "optional": false, "description": "Timing's requestTime is a baseline in seconds, while the other numbers are ticks in milliseconds relatively to this requestTime.", "typeRef": null}, {"name": "proxyStart", "type": "number", "optional": false, "description": "Started resolving proxy.", "typeRef": null}, {"name": "proxyEnd", "type": "number", "optional": false, "description": "Finished resolving proxy.", "typeRef": null}, {"name": "dnsStart", "type": "number", "optional": false, "description": "Started DNS address resolve.", "typeRef": null}, {"name": "dnsEnd", "type": "number", "optional": false, "description": "Finished DNS address resolve.", "typeRef": null}, {"name": "connectStart", "type": "number", "optional": false, "description": "Started connecting to the remote host.", "typeRef": null}, {"name": "connectEnd", "type": "number", "optional": false, "description": "Connected to the remote host.", "typeRef": null}, {"name": "sslStart", "type": "number", "optional": false, "description": "Started SSL handshake.", "typeRef": null}, {"name": "sslEnd", "type": "number", "optional": false, "description": "Finished SSL handshake.", "typeRef": null}, {"name": "workerStart", "type": "number", "optional": false, "description": "Started running ServiceWorker.", "typeRef": null}, {"name": "workerReady", "type": "number", "optional": false, "description": "Finished Starting ServiceWorker.", "typeRef": null}, {"name": "workerFetchStart", "type": "number", "optional": false, "description": "Started fetch event.", "typeRef": null}, {"name": "workerRespondWithSettled", "type": "number", "optional": false, "description": "Settled fetch event respondWith promise.", "typeRef": null}, {"name": "workerRouterEvaluationStart", "type": "number", "optional": true, "description": "Started ServiceWorker static routing source evaluation.", "typeRef": null}, {"name": "workerCacheLookupStart", "type": "number", "optional": true, "description": "Started cache lookup when the source was evaluated to `cache`.", "typeRef": null}, {"name": "sendStart", "type": "number", "optional": false, "description": "Started sending request.", "typeRef": null}, {"name": "sendEnd", "type": "number", "optional": false, "description": "Finished sending request.", "typeRef": null}, {"name": "pushStart", "type": "number", "optional": false, "description": "Time the server started pushing request.", "typeRef": null}, {"name": "pushEnd", "type": "number", "optional": false, "description": "Time the server finished pushing request.", "typeRef": null}, {"name": "receiveHeadersStart", "type": "number", "optional": false, "description": "Started receiving response headers.", "typeRef": null}, {"name": "receiveHeadersEnd", "type": "number", "optional": false, "description": "Finished receiving response headers.", "typeRef": null}]);
|
|
900
900
|
inspectorBackend.registerType("Network.PostDataEntry", [{"name": "bytes", "type": "string", "optional": true, "description": "", "typeRef": null}]);
|
|
901
901
|
inspectorBackend.registerType("Network.Request", [{"name": "url", "type": "string", "optional": false, "description": "Request URL (without fragment).", "typeRef": null}, {"name": "urlFragment", "type": "string", "optional": true, "description": "Fragment of the requested URL starting with hash, if present.", "typeRef": null}, {"name": "method", "type": "string", "optional": false, "description": "HTTP request method.", "typeRef": null}, {"name": "headers", "type": "object", "optional": false, "description": "HTTP request headers.", "typeRef": "Network.Headers"}, {"name": "postData", "type": "string", "optional": true, "description": "HTTP POST request data. Use postDataEntries instead.", "typeRef": null}, {"name": "hasPostData", "type": "boolean", "optional": true, "description": "True when the request has POST data. Note that postData might still be omitted when this flag is true when the data is too long.", "typeRef": null}, {"name": "postDataEntries", "type": "array", "optional": true, "description": "Request body elements (post data broken into individual entries).", "typeRef": "Network.PostDataEntry"}, {"name": "mixedContentType", "type": "string", "optional": true, "description": "The mixed content type of the request.", "typeRef": "Security.MixedContentType"}, {"name": "initialPriority", "type": "string", "optional": false, "description": "Priority of the resource request at the time request is sent.", "typeRef": "Network.ResourcePriority"}, {"name": "referrerPolicy", "type": "string", "optional": false, "description": "The referrer policy of the request, as defined in https://www.w3.org/TR/referrer-policy/", "typeRef": null}, {"name": "isLinkPreload", "type": "boolean", "optional": true, "description": "Whether is loaded via link preload.", "typeRef": null}, {"name": "trustTokenParams", "type": "object", "optional": true, "description": "Set for requests when the TrustToken API is used. Contains the parameters passed by the developer (e.g. via \\\"fetch\\\") as understood by the backend.", "typeRef": "Network.TrustTokenParams"}, {"name": "isSameSite", "type": "boolean", "optional": true, "description": "True if this resource request is considered to be the 'same site' as the request corresponding to the main frame.", "typeRef": null}, {"name": "isAdRelated", "type": "boolean", "optional": true, "description": "True when the resource request is ad-related.", "typeRef": null}]);
|
|
@@ -3493,6 +3493,7 @@ export const generatedProperties = [
|
|
|
3493
3493
|
{
|
|
3494
3494
|
"keywords": [
|
|
3495
3495
|
"auto",
|
|
3496
|
+
"chain",
|
|
3496
3497
|
"contain",
|
|
3497
3498
|
"none"
|
|
3498
3499
|
],
|
|
@@ -3501,6 +3502,7 @@ export const generatedProperties = [
|
|
|
3501
3502
|
{
|
|
3502
3503
|
"keywords": [
|
|
3503
3504
|
"auto",
|
|
3505
|
+
"chain",
|
|
3504
3506
|
"contain",
|
|
3505
3507
|
"none"
|
|
3506
3508
|
],
|
|
@@ -6635,6 +6637,7 @@ export const generatedPropertyValues = {
|
|
|
6635
6637
|
"overscroll-behavior-x": {
|
|
6636
6638
|
"values": [
|
|
6637
6639
|
"auto",
|
|
6640
|
+
"chain",
|
|
6638
6641
|
"contain",
|
|
6639
6642
|
"none"
|
|
6640
6643
|
]
|
|
@@ -6642,6 +6645,7 @@ export const generatedPropertyValues = {
|
|
|
6642
6645
|
"overscroll-behavior-y": {
|
|
6643
6646
|
"values": [
|
|
6644
6647
|
"auto",
|
|
6648
|
+
"chain",
|
|
6645
6649
|
"contain",
|
|
6646
6650
|
"none"
|
|
6647
6651
|
]
|
|
@@ -12584,14 +12584,6 @@ export namespace Network {
|
|
|
12584
12584
|
* Whether 3pc restriction is enabled.
|
|
12585
12585
|
*/
|
|
12586
12586
|
enableThirdPartyCookieRestriction: boolean;
|
|
12587
|
-
/**
|
|
12588
|
-
* Whether 3pc grace period exception should be enabled; false by default.
|
|
12589
|
-
*/
|
|
12590
|
-
disableThirdPartyCookieMetadata: boolean;
|
|
12591
|
-
/**
|
|
12592
|
-
* Whether 3pc heuristics exceptions should be enabled; false by default.
|
|
12593
|
-
*/
|
|
12594
|
-
disableThirdPartyCookieHeuristics: boolean;
|
|
12595
12587
|
}
|
|
12596
12588
|
|
|
12597
12589
|
/**
|
|
@@ -7,7 +7,7 @@ import * as SDK from '../../core/sdk/sdk.js';
|
|
|
7
7
|
import type * as ProtocolProxyApi from '../../generated/protocol-proxy-api.js';
|
|
8
8
|
import type * as Protocol from '../../generated/protocol.js';
|
|
9
9
|
import * as Bindings from '../bindings/bindings.js';
|
|
10
|
-
import
|
|
10
|
+
import * as StackTrace from '../stack_trace/stack_trace.js';
|
|
11
11
|
|
|
12
12
|
export const enum Events {
|
|
13
13
|
TOOLS_ADDED = 'ToolsAdded',
|
|
@@ -16,16 +16,78 @@ export const enum Events {
|
|
|
16
16
|
TOOL_RESPONDED = 'ToolResponded',
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
export interface ExceptionDetails {
|
|
20
|
+
readonly error: SDK.RemoteObject.RemoteObject;
|
|
21
|
+
readonly description: string;
|
|
22
|
+
readonly frames: StackTrace.ErrorStackParser.ParsedErrorFrame[];
|
|
23
|
+
readonly cause?: ExceptionDetails;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export class Result {
|
|
27
|
+
readonly status: Protocol.WebMCP.InvocationStatus;
|
|
28
|
+
readonly output?: unknown;
|
|
29
|
+
readonly errorText?: string;
|
|
30
|
+
// TODO(crbug.com/494516094) Clean this up if the target disappears?
|
|
31
|
+
readonly #exception?: SDK.RemoteObject.RemoteObject;
|
|
32
|
+
#exceptionDetails?: Promise<ExceptionDetails|undefined>;
|
|
33
|
+
|
|
34
|
+
constructor(
|
|
35
|
+
status: Protocol.WebMCP.InvocationStatus, output: unknown|undefined, errorText: string|undefined,
|
|
36
|
+
exception: SDK.RemoteObject.RemoteObject|undefined) {
|
|
37
|
+
this.status = status;
|
|
38
|
+
this.errorText = errorText;
|
|
39
|
+
this.#exception = exception;
|
|
40
|
+
this.output = output;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
get exceptionDetails(): Promise<ExceptionDetails|undefined>|undefined {
|
|
44
|
+
if (!this.#exceptionDetails) {
|
|
45
|
+
this.#exceptionDetails = this.#resolveExceptionDetails(this.#exception);
|
|
46
|
+
}
|
|
47
|
+
return this.#exceptionDetails;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async #resolveExceptionDetails(errorObj: SDK.RemoteObject.RemoteObject|undefined):
|
|
51
|
+
Promise<ExceptionDetails|undefined> {
|
|
52
|
+
if (!errorObj) {
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
const error = SDK.RemoteObject.RemoteError.objectAsError(errorObj);
|
|
56
|
+
const [details, cause] = await Promise.all([error.exceptionDetails(), error.cause()]);
|
|
57
|
+
const description = error.errorStack;
|
|
58
|
+
|
|
59
|
+
const frames =
|
|
60
|
+
StackTrace.ErrorStackParser.parseSourcePositionsFromErrorStack(errorObj.runtimeModel(), error.errorStack) || [];
|
|
61
|
+
if (details?.stackTrace) {
|
|
62
|
+
StackTrace.ErrorStackParser.augmentErrorStackWithScriptIds(frames, details.stackTrace);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (cause?.subtype === 'error') {
|
|
66
|
+
return {error: errorObj, description, frames, cause: await this.#resolveExceptionDetails(cause)};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (cause?.type === 'string') {
|
|
70
|
+
return {
|
|
71
|
+
error: errorObj,
|
|
72
|
+
description,
|
|
73
|
+
frames,
|
|
74
|
+
cause: {
|
|
75
|
+
error: cause,
|
|
76
|
+
description: cause.value as string,
|
|
77
|
+
frames: [],
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return {error: errorObj, description, frames};
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
19
86
|
export interface Call {
|
|
20
87
|
invocationId: string;
|
|
21
88
|
tool: Tool;
|
|
22
89
|
input: string;
|
|
23
|
-
result?:
|
|
24
|
-
status: Protocol.WebMCP.InvocationStatus,
|
|
25
|
-
output?: unknown,
|
|
26
|
-
errorText?: string,
|
|
27
|
-
exception?: Protocol.Runtime.RemoteObject,
|
|
28
|
-
};
|
|
90
|
+
result?: Result;
|
|
29
91
|
}
|
|
30
92
|
|
|
31
93
|
export class Tool {
|
|
@@ -160,11 +222,7 @@ export class WebMCPModel extends SDK.SDKModel.SDKModel<EventTypes> implements Pr
|
|
|
160
222
|
if (!tool) {
|
|
161
223
|
return;
|
|
162
224
|
}
|
|
163
|
-
const call: Call = {
|
|
164
|
-
invocationId: params.invocationId,
|
|
165
|
-
input: params.input,
|
|
166
|
-
tool,
|
|
167
|
-
};
|
|
225
|
+
const call: Call = {tool, input: params.input, invocationId: params.invocationId};
|
|
168
226
|
this.#calls.set(params.invocationId, call);
|
|
169
227
|
this.dispatchEventToListeners(Events.TOOL_INVOKED, call);
|
|
170
228
|
}
|
|
@@ -174,12 +232,9 @@ export class WebMCPModel extends SDK.SDKModel.SDKModel<EventTypes> implements Pr
|
|
|
174
232
|
if (!call) {
|
|
175
233
|
return;
|
|
176
234
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
errorText: params.errorText,
|
|
181
|
-
exception: params.exception,
|
|
182
|
-
};
|
|
235
|
+
const exception =
|
|
236
|
+
params.exception && this.target().model(SDK.RuntimeModel.RuntimeModel)?.createRemoteObject(params.exception);
|
|
237
|
+
call.result = new Result(params.status, params.output, params.errorText, exception);
|
|
183
238
|
this.dispatchEventToListeners(Events.TOOL_RESPONDED, call);
|
|
184
239
|
}
|
|
185
240
|
}
|
|
@@ -306,9 +306,8 @@ async function getEmptyStateSuggestions(conversation?: AiAssistanceModel.AiConve
|
|
|
306
306
|
];
|
|
307
307
|
case AiAssistanceModel.AiHistoryStorage.ConversationType.ACCESSIBILITY:
|
|
308
308
|
return [
|
|
309
|
-
{title: '
|
|
310
|
-
{title: '
|
|
311
|
-
{title: 'What does this Lighthouse report say about accessibility?', jslogContext: 'accessibility-default'},
|
|
309
|
+
{title: 'How can I fix accessibility issues on my page?', jslogContext: 'accessibility-default'},
|
|
310
|
+
{title: 'What accessibility issues exist on my page?', jslogContext: 'accessibility-default'},
|
|
312
311
|
];
|
|
313
312
|
case AiAssistanceModel.AiHistoryStorage.ConversationType.NETWORK:
|
|
314
313
|
|
|
@@ -157,9 +157,13 @@ const UIStringsNotTranslate = {
|
|
|
157
157
|
*/
|
|
158
158
|
completed: 'Completed',
|
|
159
159
|
/**
|
|
160
|
-
* @description Aria label for the
|
|
160
|
+
* @description Aria label for the spinner to be read by screen reader when a step is in progress.
|
|
161
161
|
*/
|
|
162
|
-
|
|
162
|
+
inProgress: 'In progress',
|
|
163
|
+
/**
|
|
164
|
+
* @description Aria label for the aborted icon to be read by screen reader
|
|
165
|
+
*/
|
|
166
|
+
aborted: 'Aborted',
|
|
163
167
|
/**
|
|
164
168
|
* @description Alt text for the image input (displayed in the chat messages) that has been sent to the model.
|
|
165
169
|
*/
|
|
@@ -204,6 +208,14 @@ const UIStringsNotTranslate = {
|
|
|
204
208
|
* @description Title for the bottom up thread activity widget.
|
|
205
209
|
*/
|
|
206
210
|
bottomUpTree: 'Bottom-up thread activity',
|
|
211
|
+
/**
|
|
212
|
+
* @description Accessilility label for the button that shows the walkthrough when there are no widgets in the walkthrough.
|
|
213
|
+
*/
|
|
214
|
+
showThinking: 'Show thinking',
|
|
215
|
+
/**
|
|
216
|
+
* @description Accessilility label for the button that hides the walkthrough when there are no widgets in the walkthrough.
|
|
217
|
+
*/
|
|
218
|
+
hideThinking: 'Hide thinking',
|
|
207
219
|
} as const;
|
|
208
220
|
|
|
209
221
|
export interface Step {
|
|
@@ -463,7 +475,7 @@ function renderTitle(step: Step): Lit.LitTemplate {
|
|
|
463
475
|
html`<span class="paused">${lockedString(UIStringsNotTranslate.paused)}: </span>` :
|
|
464
476
|
Lit.nothing;
|
|
465
477
|
|
|
466
|
-
return html`<span class="title">${paused}${titleForStep(step)}</span>`;
|
|
478
|
+
return html`<span class="title" aria-label=${titleForStep(step)}>${paused}${titleForStep(step)}</span>`;
|
|
467
479
|
}
|
|
468
480
|
|
|
469
481
|
function renderStepCode(step: Step): Lit.LitTemplate {
|
|
@@ -571,6 +583,14 @@ function renderWalkthroughSidebarButton(
|
|
|
571
583
|
// We only apply the widget styling when loading is complete
|
|
572
584
|
'has-widgets': hasOneStepWithWidget && !input.isLoading,
|
|
573
585
|
});
|
|
586
|
+
|
|
587
|
+
let accessibleLabel = title;
|
|
588
|
+
// If the agent is still thinking we want the accessibility label to include the current step title followed by Show/Hide thinking.
|
|
589
|
+
if (input.isLoading) {
|
|
590
|
+
const suffix = isExpanded ? UIStringsNotTranslate.hideThinking : UIStringsNotTranslate.showThinking;
|
|
591
|
+
accessibleLabel = `${titleForStep(lastStep)} ${i18n.i18n.lockedString(suffix)}`;
|
|
592
|
+
}
|
|
593
|
+
|
|
574
594
|
// clang-format off
|
|
575
595
|
return html`
|
|
576
596
|
<div class=${toggleContainerClasses}>
|
|
@@ -581,6 +601,7 @@ function renderWalkthroughSidebarButton(
|
|
|
581
601
|
.variant=${variant}
|
|
582
602
|
.size=${Buttons.Button.Size.SMALL}
|
|
583
603
|
.title=${lastStep.isLoading ? titleForStep(lastStep) : title}
|
|
604
|
+
.accessibleLabel=${accessibleLabel}
|
|
584
605
|
.jslogContext=${walkthrough.isExpanded ? 'ai-hide-walkthrough-sidebar' : 'ai-show-walkthrough-sidebar'}
|
|
585
606
|
data-show-walkthrough
|
|
586
607
|
@click=${() => {
|
|
@@ -670,7 +691,7 @@ function renderStepBadge({step, isLoading, isLast}: {
|
|
|
670
691
|
isLast: boolean,
|
|
671
692
|
}): Lit.LitTemplate {
|
|
672
693
|
if (isLoading && isLast && !step.requestApproval) {
|
|
673
|
-
return html`<devtools-spinner></devtools-spinner>`;
|
|
694
|
+
return html`<devtools-spinner aria-label=${lockedString(UIStringsNotTranslate.inProgress)}></devtools-spinner>`;
|
|
674
695
|
}
|
|
675
696
|
|
|
676
697
|
let iconName = 'checkmark';
|
|
@@ -678,10 +699,10 @@ function renderStepBadge({step, isLoading, isLast}: {
|
|
|
678
699
|
let role: 'button'|undefined = 'button';
|
|
679
700
|
if (isLast && step.requestApproval) {
|
|
680
701
|
role = undefined;
|
|
681
|
-
ariaLabel =
|
|
702
|
+
ariaLabel = lockedString(UIStringsNotTranslate.paused);
|
|
682
703
|
iconName = 'pause-circle';
|
|
683
704
|
} else if (step.canceled) {
|
|
684
|
-
ariaLabel = lockedString(UIStringsNotTranslate.
|
|
705
|
+
ariaLabel = lockedString(UIStringsNotTranslate.aborted);
|
|
685
706
|
iconName = 'cross';
|
|
686
707
|
}
|
|
687
708
|
|
|
@@ -925,6 +946,7 @@ function renderWidgetResponse(response: WidgetMakerResponse|null): Lit.LitTempla
|
|
|
925
946
|
const revealButton = html`
|
|
926
947
|
<devtools-button class="widget-reveal-button"
|
|
927
948
|
.variant=${Buttons.Button.Variant.TEXT}
|
|
949
|
+
.accessibleLabel=${lockedString(UIStringsNotTranslate.reveal)}
|
|
928
950
|
@click=${onReveal}
|
|
929
951
|
>
|
|
930
952
|
${response.customRevealTitle ?? lockedString(UIStringsNotTranslate.reveal)}
|
|
@@ -937,7 +959,7 @@ function renderWidgetResponse(response: WidgetMakerResponse|null): Lit.LitTempla
|
|
|
937
959
|
<div class=${classes}>
|
|
938
960
|
${response.title ? html`
|
|
939
961
|
<div class="widget-header">
|
|
940
|
-
<
|
|
962
|
+
<h3 class="widget-name">${response.title}</h3>
|
|
941
963
|
<div class="widget-reveal-container">
|
|
942
964
|
${revealButton}
|
|
943
965
|
</div>
|
|
@@ -1242,6 +1264,7 @@ function renderActions(input: ChatMessageViewInput, output: ViewOutput): Lit.Lit
|
|
|
1242
1264
|
.jslogContext=${'ai-export-for-agents'}
|
|
1243
1265
|
.variant=${Buttons.Button.Variant.OUTLINED}
|
|
1244
1266
|
.iconName=${'copy'}
|
|
1267
|
+
aria-label=${lockedString(UIStringsNotTranslate.exportForAgents)}
|
|
1245
1268
|
@click=${input.onExportClick}
|
|
1246
1269
|
>${lockedString(UIStringsNotTranslate.exportForAgents)}</devtools-button>
|
|
1247
1270
|
${input.suggestions ? html`<div class="vertical-separator"></div>` : Lit.nothing}
|
|
@@ -87,17 +87,18 @@ export const DEFAULT_VIEW: View = (input, _output, target): void => {
|
|
|
87
87
|
<style>${styles}</style>
|
|
88
88
|
<div class="export-for-agents-dialog">
|
|
89
89
|
<header>
|
|
90
|
-
<
|
|
90
|
+
<h1 id="export-for-agents-dialog-title" tabindex="-1">
|
|
91
91
|
${i18nString(UIStrings.exportForAgents)}
|
|
92
|
-
</
|
|
92
|
+
</h1>
|
|
93
93
|
</header>
|
|
94
|
-
<div class="state-selection">
|
|
94
|
+
<div class="state-selection" role="radiogroup" aria-labelledby="export-for-agents-dialog-title">
|
|
95
95
|
<label>
|
|
96
96
|
<input
|
|
97
97
|
type="radio"
|
|
98
98
|
value="prompt"
|
|
99
99
|
name="export-state"
|
|
100
100
|
.checked=${isPrompt}
|
|
101
|
+
aria-label=${i18nString(UIStrings.asPrompt)}
|
|
101
102
|
@change=${() => input.onStateChange(StateType.PROMPT)}
|
|
102
103
|
>
|
|
103
104
|
${i18nString(UIStrings.asPrompt)}
|
|
@@ -108,6 +109,7 @@ export const DEFAULT_VIEW: View = (input, _output, target): void => {
|
|
|
108
109
|
value="conversation"
|
|
109
110
|
name="export-state"
|
|
110
111
|
.checked=${!isPrompt}
|
|
112
|
+
aria-label=${i18nString(UIStrings.asMarkdown)}
|
|
111
113
|
@change=${() => input.onStateChange(StateType.CONVERSATION)}
|
|
112
114
|
>
|
|
113
115
|
${i18nString(UIStrings.asMarkdown)}
|
|
@@ -130,6 +132,7 @@ export const DEFAULT_VIEW: View = (input, _output, target): void => {
|
|
|
130
132
|
.jslogContext=${input.jslogContext}
|
|
131
133
|
.variant=${Buttons.Button.Variant.PRIMARY}
|
|
132
134
|
.disabled=${isPrompt && input.state.isPromptLoading}
|
|
135
|
+
.accessibleLabel=${buttonText}
|
|
133
136
|
>
|
|
134
137
|
${buttonText}
|
|
135
138
|
</devtools-button>
|
|
@@ -191,9 +194,10 @@ export class ExportForAgentsDialog extends UI.Widget.VBox {
|
|
|
191
194
|
onButtonClick = (event: Event): void => {
|
|
192
195
|
event.preventDefault();
|
|
193
196
|
Host.InspectorFrontendHost.InspectorFrontendHostInstance.copyText(this.#state.promptText);
|
|
194
|
-
Snackbars.Snackbar.Snackbar.show({
|
|
197
|
+
const snackbar = Snackbars.Snackbar.Snackbar.show({
|
|
195
198
|
message: i18nString(UIStrings.copiedToClipboard),
|
|
196
199
|
});
|
|
200
|
+
snackbar.setAttribute('aria-label', i18nString(UIStrings.copiedToClipboard));
|
|
197
201
|
this.#dialog.hide();
|
|
198
202
|
};
|
|
199
203
|
break;
|
|
@@ -45,6 +45,10 @@ const UIStrings = {
|
|
|
45
45
|
* @description Title for the button that hides the walkthrough when there are widgets in the walkthrough.
|
|
46
46
|
*/
|
|
47
47
|
hideAgentWalkthrough: 'Hide agent walkthrough',
|
|
48
|
+
/**
|
|
49
|
+
* @description Aria label for the spinner to be read by screen reader when a step is in progress.
|
|
50
|
+
*/
|
|
51
|
+
inProgress: 'In progress',
|
|
48
52
|
} as const;
|
|
49
53
|
const str_ = i18n.i18n.registerUIStrings('panels/ai_assistance/components/WalkthroughView.ts', UIStrings);
|
|
50
54
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
@@ -118,7 +122,7 @@ function renderInlineWalkthrough(input: ViewInput, stepsOutput: Lit.LitTemplate,
|
|
|
118
122
|
<div class="inline-wrapper" ?data-open=${input.isExpanded}>
|
|
119
123
|
<span class="inline-icon">
|
|
120
124
|
${input.isLoading ?
|
|
121
|
-
html`<devtools-spinner></devtools-spinner>` :
|
|
125
|
+
html`<devtools-spinner aria-label=${lockedString(UIStrings.inProgress)}></devtools-spinner>` :
|
|
122
126
|
html`<devtools-icon name=${icon}></devtools-icon>`
|
|
123
127
|
}
|
|
124
128
|
</span>
|
|
@@ -149,7 +153,7 @@ function renderSidebarWalkthrough(input: ViewInput, stepsOutput: Lit.LitTemplate
|
|
|
149
153
|
return html`
|
|
150
154
|
<div class="walkthrough-view">
|
|
151
155
|
<div class="walkthrough-header">
|
|
152
|
-
<
|
|
156
|
+
<h2 class="walkthrough-title">${i18nString(UIStrings.title)}</h2>
|
|
153
157
|
<devtools-button
|
|
154
158
|
.data=${{
|
|
155
159
|
variant: Buttons.Button.Variant.TOOLBAR,
|
|
@@ -118,21 +118,9 @@
|
|
|
118
118
|
&[open] {
|
|
119
119
|
border-radius: var(--sys-size-5);
|
|
120
120
|
width: auto;
|
|
121
|
-
background-color: var(--sys-color-
|
|
121
|
+
background-color: var(--sys-color-surface2);
|
|
122
122
|
margin-left: calc(var(--sys-size-6) / 2);
|
|
123
123
|
flex-grow: 1;
|
|
124
|
-
|
|
125
|
-
> summary {
|
|
126
|
-
border-radius: var(--sys-shape-corner-medium-small);
|
|
127
|
-
border-bottom-right-radius: 0;
|
|
128
|
-
border-bottom-left-radius: 0;
|
|
129
|
-
background: var(--sys-color-surface5);
|
|
130
|
-
color: var(--sys-color-on-surface);
|
|
131
|
-
|
|
132
|
-
&[data-has-widgets] {
|
|
133
|
-
margin-left: 0;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
124
|
}
|
|
137
125
|
}
|
|
138
126
|
|
|
@@ -177,6 +165,23 @@
|
|
|
177
165
|
}
|
|
178
166
|
}
|
|
179
167
|
|
|
168
|
+
.walkthrough-inline[open] > summary {
|
|
169
|
+
border-radius: var(--sys-shape-corner-medium-small);
|
|
170
|
+
border-bottom-right-radius: 0;
|
|
171
|
+
border-bottom-left-radius: 0;
|
|
172
|
+
background: var(--sys-color-surface5);
|
|
173
|
+
color: var(--sys-color-on-surface);
|
|
174
|
+
|
|
175
|
+
&[data-has-widgets] {
|
|
176
|
+
margin-left: 0;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
> devtools-icon[name='chevron-right'] {
|
|
180
|
+
transform: rotate(270deg);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
}
|
|
184
|
+
|
|
180
185
|
.walkthrough-inline > summary::-webkit-details-marker {
|
|
181
186
|
display: none;
|
|
182
187
|
}
|
|
@@ -201,8 +206,4 @@
|
|
|
201
206
|
.walkthrough-inline .step {
|
|
202
207
|
background-color: var(--sys-color-surface5);
|
|
203
208
|
}
|
|
204
|
-
|
|
205
|
-
.walkthrough-inline[open] > summary > devtools-icon[name='chevron-right'] {
|
|
206
|
-
transform: rotate(270deg);
|
|
207
|
-
}
|
|
208
209
|
}
|