chrome-devtools-frontend 1.0.1586699 → 1.0.1587905
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/sdk/ScopeTreeCache.ts +4 -0
- package/front_end/entrypoint_template.html +5 -1
- package/front_end/generated/Deprecation.ts +21 -0
- package/front_end/generated/InspectorBackendCommands.ts +1 -1
- package/front_end/generated/protocol.ts +2 -0
- package/front_end/models/ai_assistance/AiConversation.ts +5 -1
- package/front_end/models/ai_assistance/agents/AiAgent.ts +16 -4
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +7 -1
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +0 -2
- package/front_end/panels/ai_assistance/components/ChatInput.ts +36 -31
- package/front_end/panels/ai_assistance/components/chatInput.css +6 -9
- package/front_end/panels/application/ServiceWorkerCacheViews.ts +3 -6
- package/front_end/panels/browser_debugger/CategorizedBreakpointsSidebarPane.ts +11 -3
- package/front_end/panels/common/DOMLinkifier.ts +6 -1
- package/front_end/panels/elements/ComputedStyleWidget.ts +25 -2
- package/front_end/panels/elements/ElementsPanel.ts +114 -15
- package/front_end/panels/elements/PropertiesWidget.ts +40 -2
- package/front_end/panels/elements/StylesSidebarPane.ts +26 -3
- package/front_end/panels/network/NetworkDataGridNode.ts +4 -0
- package/front_end/panels/network/NetworkItemView.ts +6 -44
- package/front_end/panels/network/RequestHeadersView.ts +499 -0
- package/front_end/panels/network/components/RequestHeaderSection.ts +3 -0
- package/front_end/panels/network/components/components.ts +0 -2
- package/front_end/panels/network/network.ts +3 -0
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/third_party/puppeteer/README.chromium +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +3 -3
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.js +1 -1
- package/front_end/third_party/puppeteer/package/package.json +1 -1
- package/front_end/third_party/puppeteer/package/src/revisions.ts +2 -2
- package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
- package/front_end/ui/legacy/Toolbar.ts +37 -5
- package/front_end/ui/legacy/UIUtils.ts +35 -5
- package/front_end/ui/legacy/components/utils/JSPresentationUtils.ts +113 -133
- package/package.json +1 -1
- package/front_end/panels/network/components/RequestHeadersView.ts +0 -569
|
@@ -25,6 +25,10 @@ const scopeTrees = new WeakMap<Script, Promise<{scopeTree: ScopeTreeNode, text:
|
|
|
25
25
|
* and the text allows conversion from/to line/column numbers.
|
|
26
26
|
*/
|
|
27
27
|
export function scopeTreeForScript(script: Script): Promise<{scopeTree: ScopeTreeNode, text: Text}|null> {
|
|
28
|
+
if (script.isWasm()) {
|
|
29
|
+
return Promise.resolve(null);
|
|
30
|
+
}
|
|
31
|
+
|
|
28
32
|
let promise = scopeTrees.get(script);
|
|
29
33
|
if (promise === undefined) {
|
|
30
34
|
promise = script.requestContentData().then(content => {
|
|
@@ -14,7 +14,11 @@
|
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
</style>
|
|
17
|
-
<meta
|
|
17
|
+
<meta
|
|
18
|
+
http-equiv="Content-Security-Policy"
|
|
19
|
+
content="default-src 'self' devtools: data:; style-src 'self' 'unsafe-inline' devtools:; object-src 'none'; script-src
|
|
20
|
+
'self' https://chrome-devtools-frontend.appspot.com; img-src 'self' data:; frame-src * data:; connect-src data:
|
|
21
|
+
https://chromeuxreport.googleapis.com 'self' devtools:;">
|
|
18
22
|
<meta name="referrer" content="no-referrer">
|
|
19
23
|
<script type="module" src="./entrypoints/%ENTRYPOINT_NAME%/%ENTRYPOINT_NAME%.js"></script>
|
|
20
24
|
<link href="./application_tokens.css" rel="stylesheet">
|
|
@@ -94,6 +94,18 @@ export const UIStrings = {
|
|
|
94
94
|
* @description Warning displayed to developers that instead of calling the `Intl.v8BreakIterator` constructor, which is not a standard JavaScript API, use ECMA402 standard API Intl.Segmenter shipped in end of 2020 instead.
|
|
95
95
|
*/
|
|
96
96
|
IntlV8BreakIterator: "`Intl.v8BreakIterator` is deprecated. Please use `Intl.Segmenter` instead.",
|
|
97
|
+
/**
|
|
98
|
+
* @description Warning for using deprecated 'inputQuota' attribute.
|
|
99
|
+
*/
|
|
100
|
+
LanguageModel_InputQuota: "LanguageModel.inputQuota is deprecated. Please use LanguageModel.contextWindow instead. This alias is only available in extensions.",
|
|
101
|
+
/**
|
|
102
|
+
* @description Warning for using deprecated 'inputUsage' attribute.
|
|
103
|
+
*/
|
|
104
|
+
LanguageModel_InputUsage: "LanguageModel.inputUsage is deprecated. Please use LanguageModel.contextUsage instead. This alias is only available in extensions.",
|
|
105
|
+
/**
|
|
106
|
+
* @description Warning for using deprecated 'measureInputUsage' method.
|
|
107
|
+
*/
|
|
108
|
+
LanguageModel_MeasureInputUsage: "LanguageModel.measureInputUsage() is deprecated. Please use LanguageModel.measureContextUsage() instead. This alias is only available in extensions.",
|
|
97
109
|
/**
|
|
98
110
|
* @description Warning message for web developers when they call the deprecated LanguageModel.params() method.
|
|
99
111
|
*/
|
|
@@ -313,6 +325,15 @@ export const DEPRECATIONS_METADATA: Partial<Record<string, DeprecationDescriptor
|
|
|
313
325
|
"LanguageModelTopK": {
|
|
314
326
|
"chromeStatusFeature": 5134603979063296
|
|
315
327
|
},
|
|
328
|
+
"LanguageModel_InputQuota": {
|
|
329
|
+
"chromeStatusFeature": 5134603979063296
|
|
330
|
+
},
|
|
331
|
+
"LanguageModel_InputUsage": {
|
|
332
|
+
"chromeStatusFeature": 5134603979063296
|
|
333
|
+
},
|
|
334
|
+
"LanguageModel_MeasureInputUsage": {
|
|
335
|
+
"chromeStatusFeature": 5134603979063296
|
|
336
|
+
},
|
|
316
337
|
"LocalCSSFileExtensionRejected": {
|
|
317
338
|
"milestone": 64
|
|
318
339
|
},
|
|
@@ -857,7 +857,7 @@ inspectorBackend.registerCommand("Network.disable", [], [], "Disables network tr
|
|
|
857
857
|
inspectorBackend.registerCommand("Network.emulateNetworkConditions", [{"name": "offline", "type": "boolean", "optional": false, "description": "True to emulate internet disconnection.", "typeRef": null}, {"name": "latency", "type": "number", "optional": false, "description": "Minimum latency from request sent to response headers received (ms).", "typeRef": null}, {"name": "downloadThroughput", "type": "number", "optional": false, "description": "Maximal aggregated download throughput (bytes/sec). -1 disables download throttling.", "typeRef": null}, {"name": "uploadThroughput", "type": "number", "optional": false, "description": "Maximal aggregated upload throughput (bytes/sec). -1 disables upload throttling.", "typeRef": null}, {"name": "connectionType", "type": "string", "optional": true, "description": "Connection type if known.", "typeRef": "Network.ConnectionType"}, {"name": "packetLoss", "type": "number", "optional": true, "description": "WebRTC packet loss (percent, 0-100). 0 disables packet loss emulation, 100 drops all the packets.", "typeRef": null}, {"name": "packetQueueLength", "type": "number", "optional": true, "description": "WebRTC packet queue length (packet). 0 removes any queue length limitations.", "typeRef": null}, {"name": "packetReordering", "type": "boolean", "optional": true, "description": "WebRTC packetReordering feature.", "typeRef": null}], [], "Activates emulation of network conditions. This command is deprecated in favor of the emulateNetworkConditionsByRule and overrideNetworkState commands, which can be used together to the same effect.");
|
|
858
858
|
inspectorBackend.registerCommand("Network.emulateNetworkConditionsByRule", [{"name": "offline", "type": "boolean", "optional": false, "description": "True to emulate internet disconnection.", "typeRef": null}, {"name": "matchedNetworkConditions", "type": "array", "optional": false, "description": "Configure conditions for matching requests. If multiple entries match a request, the first entry wins. Global conditions can be configured by leaving the urlPattern for the conditions empty. These global conditions are also applied for throttling of p2p connections.", "typeRef": "Network.NetworkConditions"}], ["ruleIds"], "Activates emulation of network conditions for individual requests using URL match patterns. Unlike the deprecated Network.emulateNetworkConditions this method does not affect `navigator` state. Use Network.overrideNetworkState to explicitly modify `navigator` behavior.");
|
|
859
859
|
inspectorBackend.registerCommand("Network.overrideNetworkState", [{"name": "offline", "type": "boolean", "optional": false, "description": "True to emulate internet disconnection.", "typeRef": null}, {"name": "latency", "type": "number", "optional": false, "description": "Minimum latency from request sent to response headers received (ms).", "typeRef": null}, {"name": "downloadThroughput", "type": "number", "optional": false, "description": "Maximal aggregated download throughput (bytes/sec). -1 disables download throttling.", "typeRef": null}, {"name": "uploadThroughput", "type": "number", "optional": false, "description": "Maximal aggregated upload throughput (bytes/sec). -1 disables upload throttling.", "typeRef": null}, {"name": "connectionType", "type": "string", "optional": true, "description": "Connection type if known.", "typeRef": "Network.ConnectionType"}], [], "Override the state of navigator.onLine and navigator.connection.");
|
|
860
|
-
inspectorBackend.registerCommand("Network.enable", [{"name": "maxTotalBufferSize", "type": "number", "optional": true, "description": "Buffer size in bytes to use when preserving network payloads (XHRs, etc).", "typeRef": null}, {"name": "maxResourceBufferSize", "type": "number", "optional": true, "description": "Per-resource buffer size in bytes to use when preserving network payloads (XHRs, etc).", "typeRef": null}, {"name": "maxPostDataSize", "type": "number", "optional": true, "description": "Longest post body size (in bytes) that would be included in requestWillBeSent notification", "typeRef": null}, {"name": "reportDirectSocketTraffic", "type": "boolean", "optional": true, "description": "Whether DirectSocket chunk send/receive events should be reported.", "typeRef": null}, {"name": "enableDurableMessages", "type": "boolean", "optional": true, "description": "Enable storing response bodies outside of renderer, so that these survive a cross-process navigation. Requires maxTotalBufferSize to be set. Currently defaults to false. This field is being deprecated in favor of the dedicated configureDurableMessages command, due to the possibility of deadlocks when awaiting Network.enable before issuing Runtime.runIfWaitingForDebugger.", "typeRef": null}], [], "Enables network tracking, network events will now be delivered to the client.");
|
|
860
|
+
inspectorBackend.registerCommand("Network.enable", [{"name": "maxTotalBufferSize", "type": "number", "optional": true, "description": "Buffer size in bytes to use when preserving network payloads (XHRs, etc). This is the maximum number of bytes that will be collected by this DevTools session.", "typeRef": null}, {"name": "maxResourceBufferSize", "type": "number", "optional": true, "description": "Per-resource buffer size in bytes to use when preserving network payloads (XHRs, etc).", "typeRef": null}, {"name": "maxPostDataSize", "type": "number", "optional": true, "description": "Longest post body size (in bytes) that would be included in requestWillBeSent notification", "typeRef": null}, {"name": "reportDirectSocketTraffic", "type": "boolean", "optional": true, "description": "Whether DirectSocket chunk send/receive events should be reported.", "typeRef": null}, {"name": "enableDurableMessages", "type": "boolean", "optional": true, "description": "Enable storing response bodies outside of renderer, so that these survive a cross-process navigation. Requires maxTotalBufferSize to be set. Currently defaults to false. This field is being deprecated in favor of the dedicated configureDurableMessages command, due to the possibility of deadlocks when awaiting Network.enable before issuing Runtime.runIfWaitingForDebugger.", "typeRef": null}], [], "Enables network tracking, network events will now be delivered to the client.");
|
|
861
861
|
inspectorBackend.registerCommand("Network.configureDurableMessages", [{"name": "maxTotalBufferSize", "type": "number", "optional": true, "description": "Buffer size in bytes to use when preserving network payloads (XHRs, etc).", "typeRef": null}, {"name": "maxResourceBufferSize", "type": "number", "optional": true, "description": "Per-resource buffer size in bytes to use when preserving network payloads (XHRs, etc).", "typeRef": null}], [], "Configures storing response bodies outside of renderer, so that these survive a cross-process navigation. If maxTotalBufferSize is not set, durable messages are disabled.");
|
|
862
862
|
inspectorBackend.registerCommand("Network.getAllCookies", [], ["cookies"], "Returns all browser cookies. Depending on the backend support, will return detailed cookie information in the `cookies` field. Deprecated. Use Storage.getCookies instead.");
|
|
863
863
|
inspectorBackend.registerCommand("Network.getCertificate", [{"name": "origin", "type": "string", "optional": false, "description": "Origin to get certificate for.", "typeRef": null}], ["tableNames"], "Returns the DER-encoded certificate.");
|
|
@@ -11896,6 +11896,8 @@ export namespace Network {
|
|
|
11896
11896
|
export interface EnableRequest {
|
|
11897
11897
|
/**
|
|
11898
11898
|
* Buffer size in bytes to use when preserving network payloads (XHRs, etc).
|
|
11899
|
+
* This is the maximum number of bytes that will be collected by this
|
|
11900
|
+
* DevTools session.
|
|
11899
11901
|
*/
|
|
11900
11902
|
maxTotalBufferSize?: integer;
|
|
11901
11903
|
/**
|
|
@@ -425,6 +425,10 @@ Time: ${micros(time)}`;
|
|
|
425
425
|
yield* this.#runAgent(initialQuery, options);
|
|
426
426
|
}
|
|
427
427
|
|
|
428
|
+
#getQueryAfterSelection(initialQuery: string, selection: string): string {
|
|
429
|
+
return `${selection}\nOriginal user query: ${initialQuery}`;
|
|
430
|
+
}
|
|
431
|
+
|
|
428
432
|
async *
|
|
429
433
|
#runAgent(
|
|
430
434
|
initialQuery: string,
|
|
@@ -467,7 +471,7 @@ Time: ${micros(time)}`;
|
|
|
467
471
|
// requery with the specialized agent.
|
|
468
472
|
if (data.type === ResponseType.CONTEXT_CHANGE) {
|
|
469
473
|
this.setContext(data.context);
|
|
470
|
-
yield* this.#runAgent(initialQuery, options);
|
|
474
|
+
yield* this.#runAgent(this.#getQueryAfterSelection(initialQuery, data.description), options);
|
|
471
475
|
return;
|
|
472
476
|
}
|
|
473
477
|
}
|
|
@@ -88,6 +88,12 @@ export interface SideEffectResponse {
|
|
|
88
88
|
}
|
|
89
89
|
export interface ContextChangeResponse {
|
|
90
90
|
type: ResponseType.CONTEXT_CHANGE;
|
|
91
|
+
/**
|
|
92
|
+
* Information to pass down what was selected
|
|
93
|
+
* Use to make the LLM understand the the user
|
|
94
|
+
* already selected something.
|
|
95
|
+
*/
|
|
96
|
+
description: string;
|
|
91
97
|
context: ConversationContext<unknown>;
|
|
92
98
|
}
|
|
93
99
|
|
|
@@ -212,7 +218,8 @@ export type FunctionCallHandlerResult<Result> = {
|
|
|
212
218
|
}|{
|
|
213
219
|
result: Result,
|
|
214
220
|
}|{
|
|
215
|
-
context: unknown
|
|
221
|
+
context: ConversationContext<unknown>,
|
|
222
|
+
description: string,
|
|
216
223
|
}|{
|
|
217
224
|
error: string,
|
|
218
225
|
};
|
|
@@ -484,7 +491,9 @@ export abstract class AiAgent<T> {
|
|
|
484
491
|
* called with one object with `foo` and `bar` keys.
|
|
485
492
|
*/
|
|
486
493
|
protected declareFunction<Args extends Record<string, unknown>, ReturnType = unknown>(
|
|
487
|
-
name: string,
|
|
494
|
+
name: string,
|
|
495
|
+
declaration: FunctionDeclaration<Args, ReturnType>,
|
|
496
|
+
): void {
|
|
488
497
|
if (this.#functionDeclarations.has(name)) {
|
|
489
498
|
throw new Error(`Duplicate function declaration ${name}`);
|
|
490
499
|
}
|
|
@@ -609,6 +618,7 @@ export abstract class AiAgent<T> {
|
|
|
609
618
|
if ('context' in result) {
|
|
610
619
|
yield {
|
|
611
620
|
type: ResponseType.CONTEXT_CHANGE,
|
|
621
|
+
description: result.description,
|
|
612
622
|
context: result.context,
|
|
613
623
|
};
|
|
614
624
|
|
|
@@ -643,7 +653,9 @@ export abstract class AiAgent<T> {
|
|
|
643
653
|
name: string,
|
|
644
654
|
args: Record<string, unknown>,
|
|
645
655
|
options?: FunctionHandlerOptions&{explanation?: string},
|
|
646
|
-
): AsyncGenerator<FunctionCallResponseData, {
|
|
656
|
+
): AsyncGenerator<FunctionCallResponseData, {
|
|
657
|
+
result: unknown,
|
|
658
|
+
}|{context: ConversationContext<unknown>, description: string}> {
|
|
647
659
|
const call = this.#functionDeclarations.get(name);
|
|
648
660
|
if (!call) {
|
|
649
661
|
throw new Error(`Function ${name} is not found.`);
|
|
@@ -755,7 +767,7 @@ export abstract class AiAgent<T> {
|
|
|
755
767
|
}
|
|
756
768
|
|
|
757
769
|
if ('context' in result) {
|
|
758
|
-
return result
|
|
770
|
+
return result;
|
|
759
771
|
}
|
|
760
772
|
|
|
761
773
|
return result as {result: unknown};
|
|
@@ -169,6 +169,7 @@ export class ContextSelectionAgent extends AiAgent<never> {
|
|
|
169
169
|
const calculator = this.#networkTimeCalculator ?? new NetworkTimeCalculator.NetworkTransferTimeCalculator();
|
|
170
170
|
return {
|
|
171
171
|
context: new RequestContext(request, calculator),
|
|
172
|
+
description: 'User selected a network request',
|
|
172
173
|
};
|
|
173
174
|
}
|
|
174
175
|
|
|
@@ -231,11 +232,14 @@ export class ContextSelectionAgent extends AiAgent<never> {
|
|
|
231
232
|
if (file.fullDisplayName() === params.name) {
|
|
232
233
|
return {
|
|
233
234
|
context: new FileContext(file),
|
|
235
|
+
description: 'User selected a source file',
|
|
234
236
|
};
|
|
235
237
|
}
|
|
236
238
|
}
|
|
237
239
|
|
|
238
|
-
return {
|
|
240
|
+
return {
|
|
241
|
+
error: 'Unable to find file.',
|
|
242
|
+
};
|
|
239
243
|
},
|
|
240
244
|
});
|
|
241
245
|
|
|
@@ -264,6 +268,7 @@ export class ContextSelectionAgent extends AiAgent<never> {
|
|
|
264
268
|
|
|
265
269
|
return {
|
|
266
270
|
context: PerformanceTraceContext.fromParsedTrace(result),
|
|
271
|
+
description: 'User recorded a performance trace',
|
|
267
272
|
};
|
|
268
273
|
}
|
|
269
274
|
});
|
|
@@ -292,6 +297,7 @@ export class ContextSelectionAgent extends AiAgent<never> {
|
|
|
292
297
|
if (node) {
|
|
293
298
|
return {
|
|
294
299
|
context: new NodeContext(node),
|
|
300
|
+
description: 'User selected an element',
|
|
295
301
|
};
|
|
296
302
|
}
|
|
297
303
|
return {
|
|
@@ -1426,8 +1426,6 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
1426
1426
|
// Cancel any previous in-flight conversation.
|
|
1427
1427
|
this.#cancel();
|
|
1428
1428
|
const signal = this.#runAbortController.signal;
|
|
1429
|
-
const context = this.#getConversationContext(this.#conversation.type);
|
|
1430
|
-
this.#conversation.setContext(context);
|
|
1431
1429
|
|
|
1432
1430
|
// If a different context is provided, it must be from the same origin.
|
|
1433
1431
|
if (this.#conversation.isBlockedByOrigin) {
|
|
@@ -202,7 +202,8 @@ export const DEFAULT_VIEW = (input: ViewInput, _output: ViewOutput, target: HTML
|
|
|
202
202
|
jslog=${VisualLogging.link('open-ai-settings').track({
|
|
203
203
|
click: true,
|
|
204
204
|
})}
|
|
205
|
-
@click=${() => {
|
|
205
|
+
@click=${(ev: Event) => {
|
|
206
|
+
ev.preventDefault();
|
|
206
207
|
void UI.ViewManager.ViewManager.instance().showView('chrome-ai');
|
|
207
208
|
}}
|
|
208
209
|
>${lockedString('Relevant data')}</button> ${lockedString('is sent to Google')}
|
|
@@ -320,42 +321,46 @@ export const DEFAULT_VIEW = (input: ViewInput, _output: ViewOutput, target: HTML
|
|
|
320
321
|
></devtools-button>`
|
|
321
322
|
: Lit.nothing}
|
|
322
323
|
<div
|
|
323
|
-
role=button
|
|
324
324
|
class=${Lit.Directives.classMap({
|
|
325
325
|
'resource-link': true,
|
|
326
326
|
'has-picker-behavior': input.conversationType === AiAssistanceModel.AiHistoryStorage.ConversationType.STYLING,
|
|
327
|
-
disabled: input.isTextInputDisabled,
|
|
328
327
|
})}
|
|
329
|
-
tabindex=${(input.conversationType === AiAssistanceModel.AiHistoryStorage.ConversationType.STYLING || input.isTextInputDisabled) ? '-1' : '0'}
|
|
330
|
-
@click=${input.onContextClick}
|
|
331
|
-
@keydown=${(ev: KeyboardEvent) => {
|
|
332
|
-
if (ev.key === 'Enter' || ev.key === ' ') {
|
|
333
|
-
void input.onContextClick();
|
|
334
|
-
}
|
|
335
|
-
}}
|
|
336
|
-
aria-description=${i18nString(UIStrings.revealContextDescription)}
|
|
337
328
|
>
|
|
338
|
-
${
|
|
339
|
-
|
|
340
|
-
input.selectedContext instanceof AiAssistanceModel.FileAgent.FileContext ?
|
|
341
|
-
PanelUtils.PanelUtils.getIconForSourceFile(input.selectedContext.getItem()) :
|
|
342
|
-
input.selectedContext instanceof AiAssistanceModel.PerformanceAgent.PerformanceTraceContext ?
|
|
343
|
-
html`<devtools-icon name="performance" title="Performance"></devtools-icon>` :
|
|
344
|
-
Lit.nothing}
|
|
345
|
-
<span class="title">
|
|
346
|
-
${input.selectedContext instanceof AiAssistanceModel.StylingAgent.NodeContext ?
|
|
329
|
+
${
|
|
330
|
+
input.selectedContext instanceof AiAssistanceModel.StylingAgent.NodeContext ?
|
|
347
331
|
html`
|
|
348
|
-
<devtools-widget
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
332
|
+
<devtools-widget
|
|
333
|
+
class="title"
|
|
334
|
+
.widgetConfig=${UI.Widget.widgetConfig(PanelsCommon.DOMLinkifier.DOMNodeLink, {
|
|
335
|
+
node: input.selectedContext.getItem(),
|
|
336
|
+
options: {
|
|
337
|
+
hiddenClassList: input.selectedContext.getItem().classNames().filter(
|
|
338
|
+
className => className.startsWith(AiAssistanceModel.Injected.AI_ASSISTANCE_CSS_CLASS_NAME)),
|
|
339
|
+
ariaDescription: i18nString(UIStrings.revealContextDescription),
|
|
340
|
+
},
|
|
341
|
+
})}
|
|
342
|
+
></devtools-widget>` :
|
|
343
|
+
html`
|
|
344
|
+
${input.selectedContext instanceof AiAssistanceModel.NetworkAgent.RequestContext ?
|
|
345
|
+
PanelUtils.PanelUtils.getIconForNetworkRequest(input.selectedContext.getItem()) :
|
|
346
|
+
input.selectedContext instanceof AiAssistanceModel.FileAgent.FileContext ?
|
|
347
|
+
PanelUtils.PanelUtils.getIconForSourceFile(input.selectedContext.getItem()) :
|
|
348
|
+
input.selectedContext instanceof AiAssistanceModel.PerformanceAgent.PerformanceTraceContext ?
|
|
349
|
+
html`<devtools-icon name="performance" title="Performance"></devtools-icon>` :
|
|
350
|
+
Lit.nothing}
|
|
351
|
+
<span
|
|
352
|
+
role="button"
|
|
353
|
+
class="title"
|
|
354
|
+
tabindex="0"
|
|
355
|
+
@click=${input.onContextClick}
|
|
356
|
+
@keydown=${(ev: KeyboardEvent) => {
|
|
357
|
+
if (ev.key === 'Enter' || ev.key === ' ') {
|
|
358
|
+
void input.onContextClick();
|
|
359
|
+
}
|
|
360
|
+
}}
|
|
361
|
+
aria-description=${i18nString(UIStrings.revealContextDescription)}
|
|
362
|
+
>${input.selectedContext.getTitle()}</span>`
|
|
363
|
+
}
|
|
359
364
|
${input.onContextRemoved ? html`
|
|
360
365
|
<devtools-button
|
|
361
366
|
title=${getContextRemoveLabel(input.selectedContext)}
|
|
@@ -218,9 +218,9 @@
|
|
|
218
218
|
gap: var(--sys-size-3);
|
|
219
219
|
align-items: center;
|
|
220
220
|
|
|
221
|
-
.resource-link
|
|
222
|
-
.resource-task {
|
|
221
|
+
.resource-link {
|
|
223
222
|
display: flex;
|
|
223
|
+
background-color: var(--sys-color-cdt-base-container);
|
|
224
224
|
align-items: center;
|
|
225
225
|
cursor: pointer;
|
|
226
226
|
padding: var(--sys-size-2) var(--sys-size-3);
|
|
@@ -250,6 +250,10 @@
|
|
|
250
250
|
|
|
251
251
|
&.has-picker-behavior {
|
|
252
252
|
overflow: visible;
|
|
253
|
+
|
|
254
|
+
.title {
|
|
255
|
+
overflow: visible;
|
|
256
|
+
}
|
|
253
257
|
}
|
|
254
258
|
|
|
255
259
|
&:focus-visible {
|
|
@@ -301,13 +305,6 @@
|
|
|
301
305
|
}
|
|
302
306
|
}
|
|
303
307
|
}
|
|
304
|
-
|
|
305
|
-
.resource-link.disabled,
|
|
306
|
-
.resource-task.disabled {
|
|
307
|
-
color: var(--sys-color-state-disabled);
|
|
308
|
-
border-color: var(--sys-color-neutral-outline);
|
|
309
|
-
pointer-events: none;
|
|
310
|
-
}
|
|
311
308
|
}
|
|
312
309
|
|
|
313
310
|
.link {
|
|
@@ -11,11 +11,9 @@ import * as Platform from '../../core/platform/platform.js';
|
|
|
11
11
|
import * as SDK from '../../core/sdk/sdk.js';
|
|
12
12
|
import type * as Protocol from '../../generated/protocol.js';
|
|
13
13
|
import * as TextUtils from '../../models/text_utils/text_utils.js';
|
|
14
|
-
import * as LegacyWrapper from '../../ui/components/legacy_wrapper/legacy_wrapper.js';
|
|
15
14
|
import * as DataGrid from '../../ui/legacy/components/data_grid/data_grid.js';
|
|
16
15
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
17
16
|
import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
|
|
18
|
-
import * as NetworkComponents from '../network/components/components.js';
|
|
19
17
|
import * as Network from '../network/network.js';
|
|
20
18
|
|
|
21
19
|
import * as ApplicationComponents from './components/components.js';
|
|
@@ -542,10 +540,9 @@ export class RequestView extends UI.Widget.VBox {
|
|
|
542
540
|
this.resourceViewTabSetting =
|
|
543
541
|
Common.Settings.Settings.instance().createSetting('cache-storage-view-tab', 'preview');
|
|
544
542
|
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
UI.Widget.VBox, new NetworkComponents.RequestHeadersView.RequestHeadersView(request)));
|
|
543
|
+
const requestHeadersView = new Network.RequestHeadersView.RequestHeadersView();
|
|
544
|
+
requestHeadersView.request = request;
|
|
545
|
+
this.tabbedPane.appendTab('headers', i18nString(UIStrings.headers), requestHeadersView);
|
|
549
546
|
this.tabbedPane.appendTab(
|
|
550
547
|
'preview', i18nString(UIStrings.preview), new Network.RequestPreviewView.RequestPreviewView(request));
|
|
551
548
|
this.tabbedPane.show(this.element);
|
|
@@ -150,12 +150,20 @@ export const DEFAULT_VIEW = (input: ViewInput, output: ViewOutput, target: HTMLE
|
|
|
150
150
|
const shouldExpandCategory = (breakpoints: SDK.CategorizedBreakpoint.CategorizedBreakpoint[]): boolean =>
|
|
151
151
|
Boolean(input.filterText) || (input.highlightedItem && breakpoints.includes(input.highlightedItem)) ||
|
|
152
152
|
breakpoints.some(breakpoint => breakpoint.enabled());
|
|
153
|
-
const
|
|
154
|
-
|
|
153
|
+
const filterRegex =
|
|
154
|
+
input.filterText ? new RegExp(Platform.StringUtilities.escapeForRegExp(input.filterText), 'i') : null;
|
|
155
|
+
const filter = (breakpoint: SDK.CategorizedBreakpoint.CategorizedBreakpoint): boolean => !filterRegex ||
|
|
156
|
+
Boolean(Sources.CategorizedBreakpointL10n.getLocalizedBreakpointName(breakpoint.name).match(filterRegex)) ||
|
|
155
157
|
breakpoint === input.highlightedItem;
|
|
156
158
|
const filteredCategories =
|
|
157
159
|
input.sortedCategoryNames.values()
|
|
158
|
-
.map(category =>
|
|
160
|
+
.map(category => {
|
|
161
|
+
const breakpoints = input.categories.get(category);
|
|
162
|
+
if (filterRegex && getLocalizedCategory(category).match(filterRegex)) {
|
|
163
|
+
return [category, breakpoints];
|
|
164
|
+
}
|
|
165
|
+
return [category, breakpoints?.filter(filter)];
|
|
166
|
+
})
|
|
159
167
|
.filter(
|
|
160
168
|
(filteredCategory): filteredCategory is
|
|
161
169
|
[SDK.CategorizedBreakpoint.Category, SDK.CategorizedBreakpoint.CategorizedBreakpoint[]] =>
|
|
@@ -12,7 +12,7 @@ import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
|
|
|
12
12
|
|
|
13
13
|
import domLinkifierStyles from './domLinkifier.css.js';
|
|
14
14
|
|
|
15
|
-
const {classMap} = Directives;
|
|
15
|
+
const {classMap, ifDefined} = Directives;
|
|
16
16
|
|
|
17
17
|
const UIStrings = {
|
|
18
18
|
/**
|
|
@@ -33,6 +33,7 @@ export interface Options {
|
|
|
33
33
|
isDynamicLink?: boolean;
|
|
34
34
|
hiddenClassList?: string[];
|
|
35
35
|
disabled?: boolean;
|
|
36
|
+
ariaDescription?: string;
|
|
36
37
|
}
|
|
37
38
|
|
|
38
39
|
interface ViewInput {
|
|
@@ -43,6 +44,7 @@ interface ViewInput {
|
|
|
43
44
|
id?: string;
|
|
44
45
|
classes: string[];
|
|
45
46
|
pseudo?: string;
|
|
47
|
+
ariaDescription?: string;
|
|
46
48
|
onClick: () => void;
|
|
47
49
|
onMouseOver: () => void;
|
|
48
50
|
onMouseLeave: () => void;
|
|
@@ -59,6 +61,7 @@ const DEFAULT_VIEW: View = (input, _output, target: HTMLElement) => {
|
|
|
59
61
|
'dynamic-link': Boolean(input.dynamic),
|
|
60
62
|
disabled: Boolean(input.disabled)
|
|
61
63
|
})}"
|
|
64
|
+
aria-description=${ifDefined(input.ariaDescription)}
|
|
62
65
|
jslog=${VisualLogging.link('node').track({click: true, keydown: 'Enter'})}
|
|
63
66
|
tabindex=${input.preventKeyboardFocus ? -1 : 0}
|
|
64
67
|
@click=${input.onClick}
|
|
@@ -112,6 +115,7 @@ export class DOMNodeLink extends UI.Widget.Widget {
|
|
|
112
115
|
textContent: undefined,
|
|
113
116
|
isDynamicLink: false,
|
|
114
117
|
disabled: false,
|
|
118
|
+
ariaDescription: undefined,
|
|
115
119
|
};
|
|
116
120
|
const viewInput: ViewInput = {
|
|
117
121
|
dynamic: options.isDynamicLink,
|
|
@@ -129,6 +133,7 @@ export class DOMNodeLink extends UI.Widget.Widget {
|
|
|
129
133
|
onMouseLeave: () => {
|
|
130
134
|
SDK.OverlayModel.OverlayModel.hideDOMNodeHighlight();
|
|
131
135
|
},
|
|
136
|
+
ariaDescription: options.ariaDescription,
|
|
132
137
|
};
|
|
133
138
|
if (!this.#node) {
|
|
134
139
|
this.#view(viewInput, {}, this.contentElement);
|
|
@@ -270,6 +270,7 @@ interface ComputedStyleWidgetInput {
|
|
|
270
270
|
groupComputedStylesSetting: Common.Settings.Setting<boolean>;
|
|
271
271
|
onFilterChanged: (event: CustomEvent<string>) => void;
|
|
272
272
|
filterText: string;
|
|
273
|
+
onRegexToggled: () => void;
|
|
273
274
|
}
|
|
274
275
|
|
|
275
276
|
type View = (input: ComputedStyleWidgetInput, output: null, target: HTMLElement) => void;
|
|
@@ -283,8 +284,10 @@ export const DEFAULT_VIEW: View = (input, _output, target) => {
|
|
|
283
284
|
<devtools-toolbar-input
|
|
284
285
|
type="filter"
|
|
285
286
|
autofocus
|
|
287
|
+
?regex=${true}
|
|
286
288
|
value=${input.filterText}
|
|
287
289
|
@change=${input.onFilterChanged}
|
|
290
|
+
@regextoggle=${input.onRegexToggled}
|
|
288
291
|
></devtools-toolbar-input>
|
|
289
292
|
<devtools-checkbox
|
|
290
293
|
title=${i18nString(UIStrings.showAll)}
|
|
@@ -317,6 +320,7 @@ export class ComputedStyleWidget extends UI.Widget.VBox {
|
|
|
317
320
|
#treeData?: TreeOutline.TreeOutline.TreeOutlineData<ComputedStyleData>;
|
|
318
321
|
readonly #view: View;
|
|
319
322
|
#filterText = '';
|
|
323
|
+
#isRegex = false;
|
|
320
324
|
|
|
321
325
|
constructor() {
|
|
322
326
|
super({useShadowDom: true});
|
|
@@ -374,6 +378,7 @@ export class ComputedStyleWidget extends UI.Widget.VBox {
|
|
|
374
378
|
groupComputedStylesSetting: this.groupComputedStylesSetting,
|
|
375
379
|
onFilterChanged: this.onFilterChanged.bind(this),
|
|
376
380
|
filterText: this.#filterText,
|
|
381
|
+
onRegexToggled: this.onRegexToggled.bind(this),
|
|
377
382
|
},
|
|
378
383
|
null, this.contentElement);
|
|
379
384
|
}
|
|
@@ -654,10 +659,28 @@ export class ComputedStyleWidget extends UI.Widget.VBox {
|
|
|
654
659
|
return result;
|
|
655
660
|
}
|
|
656
661
|
|
|
662
|
+
#buildFilterRegex(text: string): RegExp|null {
|
|
663
|
+
if (!text) {
|
|
664
|
+
return null;
|
|
665
|
+
}
|
|
666
|
+
if (this.#isRegex) {
|
|
667
|
+
try {
|
|
668
|
+
return new RegExp(text, 'i');
|
|
669
|
+
} catch {
|
|
670
|
+
// Invalid regex: fall through to plain-text matching.
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
return new RegExp(Platform.StringUtilities.escapeForRegExp(text), 'i');
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
private async onRegexToggled(): Promise<void> {
|
|
677
|
+
this.#isRegex = !this.#isRegex;
|
|
678
|
+
await this.filterComputedStyles(this.#buildFilterRegex(this.#filterText));
|
|
679
|
+
}
|
|
680
|
+
|
|
657
681
|
private async onFilterChanged(event: CustomEvent<string>): Promise<void> {
|
|
658
682
|
this.#filterText = event.detail;
|
|
659
|
-
await this.filterComputedStyles(
|
|
660
|
-
event.detail ? new RegExp(Platform.StringUtilities.escapeForRegExp(event.detail), 'i') : null);
|
|
683
|
+
await this.filterComputedStyles(this.#buildFilterRegex(event.detail));
|
|
661
684
|
|
|
662
685
|
if (event.detail && this.#computedStylesTree.data && this.#computedStylesTree.data.tree) {
|
|
663
686
|
UI.ARIAUtils.LiveAnnouncer.alert(i18nString(
|