chrome-devtools-frontend 1.0.1581708 → 1.0.1582745
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/RemoteObject.ts +7 -1
- package/front_end/entrypoint_template.html +5 -1
- package/front_end/entrypoints/greendev_floaty/FloatyEntrypoint.ts +9 -24
- package/front_end/entrypoints/greendev_floaty/floaty.css +1 -1
- package/front_end/entrypoints/greendev_floaty/greendev_floaty.ts +1 -1
- package/front_end/generated/InspectorBackendCommands.ts +1 -1
- package/front_end/generated/SupportedCSSProperties.js +2 -0
- package/front_end/generated/protocol.ts +0 -6
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.snapshot.txt +6 -6
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +17 -9
- package/front_end/models/ai_assistance/agents/NetworkAgent.ts +2 -6
- package/front_end/models/ai_assistance/data_formatters/NetworkRequestFormatter.ts +66 -2
- package/front_end/models/greendev/Prototypes.ts +1 -10
- package/front_end/models/issues_manager/ConnectionAllowlistIssue.ts +75 -0
- package/front_end/models/issues_manager/FederatedAuthRequestIssue.ts +0 -30
- package/front_end/models/issues_manager/IssuesManager.ts +5 -0
- package/front_end/models/issues_manager/descriptions/connectionAllowlistInvalidAllowlistItemType.md +12 -0
- package/front_end/models/issues_manager/descriptions/connectionAllowlistInvalidHeader.md +12 -0
- package/front_end/models/issues_manager/descriptions/connectionAllowlistInvalidUrlPattern.md +8 -0
- package/front_end/models/issues_manager/descriptions/connectionAllowlistItemNotInnerList.md +12 -0
- package/front_end/models/issues_manager/descriptions/connectionAllowlistMoreThanOneList.md +7 -0
- package/front_end/models/issues_manager/descriptions/connectionAllowlistReportingEndpointNotToken.md +10 -0
- package/front_end/models/issues_manager/issues_manager.ts +2 -0
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +7 -1
- package/front_end/panels/ai_assistance/components/ChatInput.ts +7 -3
- package/front_end/panels/application/preloading/PreloadingView.ts +8 -1
- package/front_end/panels/application/preloading/components/PreloadingDetailsReportView.ts +4 -1
- package/front_end/panels/application/preloading/components/PreloadingGrid.ts +2 -1
- package/front_end/panels/application/preloading/components/PreloadingString.ts +12 -3
- package/front_end/panels/application/preloading/helper/PreloadingForward.ts +14 -0
- package/front_end/panels/browser_debugger/CategorizedBreakpointsSidebarPane.ts +37 -3
- package/front_end/panels/changes/ChangesSidebar.ts +2 -6
- package/front_end/panels/console/ConsoleSidebar.ts +3 -11
- package/front_end/panels/lighthouse/LighthouseStartView.ts +3 -5
- package/front_end/panels/lighthouse/lighthouseStartView.css +6 -0
- package/front_end/panels/network/NetworkLogView.ts +6 -6
- package/front_end/panels/network/RequestInitiatorView.ts +19 -8
- package/front_end/panels/settings/AISettingsTab.ts +1 -5
- package/front_end/panels/settings/SettingsScreen.ts +0 -51
- package/front_end/panels/timeline/AnimationsTrackAppender.ts +4 -1
- package/front_end/panels/timeline/InteractionsTrackAppender.ts +1 -1
- package/front_end/panels/timeline/TimelineUIUtils.ts +13 -16
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/ui/components/markdown_view/MarkdownLinksMap.ts +5 -1
- package/front_end/ui/legacy/Toolbar.ts +4 -4
- package/front_end/ui/legacy/Treeoutline.ts +4 -4
- package/front_end/ui/legacy/UIUtils.ts +9 -3
- package/front_end/ui/legacy/components/utils/JSPresentationUtils.ts +6 -11
- package/front_end/ui/legacy/components/utils/Linkifier.ts +4 -7
- package/package.json +1 -1
- package/front_end/models/issues_manager/descriptions/federatedAuthRequestClientMetadataHttpNotFound.md +0 -1
- package/front_end/models/issues_manager/descriptions/federatedAuthRequestClientMetadataInvalidResponse.md +0 -1
- package/front_end/models/issues_manager/descriptions/federatedAuthRequestClientMetadataNoResponse.md +0 -1
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# An item in the `Connection-Allowlist` header is not an Inner List.
|
|
2
|
+
|
|
3
|
+
Responses' `Connection-Allowlist` header should be formatted as a [List](sfList)
|
|
4
|
+
containing a single [Inner List](sfInnerList) that declares the allowed set of
|
|
5
|
+
[URL Patterns](urlPatternSpec) for a given context.
|
|
6
|
+
|
|
7
|
+
For example, the following header allows connections to (only)
|
|
8
|
+
`https://example.com/`:
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
Connection-Allowlist: ("https://example.com")
|
|
12
|
+
```
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# `Connection-Allowlist` has multiple items.
|
|
2
|
+
|
|
3
|
+
Responses' `Connection-Allowlist` header should be formatted as a [List](sfList)
|
|
4
|
+
containing a single [Inner List](sfInnerList) that declares the allowed set of
|
|
5
|
+
[URL Patterns](urlPatternSpec) for a given context. This response was a
|
|
6
|
+
[List](sfList) containing more than one item: all but the first have been
|
|
7
|
+
ignored.
|
package/front_end/models/issues_manager/descriptions/connectionAllowlistReportingEndpointNotToken.md
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# The `report-to` parameter in the `Connection-Allowlist` header is not a token.
|
|
2
|
+
|
|
3
|
+
If provided, the `report-to` parameter must be a [Token](sfToken)
|
|
4
|
+
naming a reporting endpoint.
|
|
5
|
+
|
|
6
|
+
For example:
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
Connection-Allowlist: ("https://example.com");report-to=endpoint
|
|
10
|
+
```
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import * as AttributionReportingIssue from './AttributionReportingIssue.js';
|
|
6
6
|
import * as CheckFormsIssuesTrigger from './CheckFormsIssuesTrigger.js';
|
|
7
7
|
import * as ClientHintIssue from './ClientHintIssue.js';
|
|
8
|
+
import * as ConnectionAllowlistIssue from './ConnectionAllowlistIssue.js';
|
|
8
9
|
import * as ContentSecurityPolicyIssue from './ContentSecurityPolicyIssue.js';
|
|
9
10
|
import * as ContrastCheckTrigger from './ContrastCheckTrigger.js';
|
|
10
11
|
import * as CookieDeprecationMetadataIssue from './CookieDeprecationMetadataIssue.js';
|
|
@@ -39,6 +40,7 @@ export {
|
|
|
39
40
|
AttributionReportingIssue,
|
|
40
41
|
CheckFormsIssuesTrigger,
|
|
41
42
|
ClientHintIssue,
|
|
43
|
+
ConnectionAllowlistIssue,
|
|
42
44
|
ContentSecurityPolicyIssue,
|
|
43
45
|
ContrastCheckTrigger,
|
|
44
46
|
CookieDeprecationMetadataIssue,
|
|
@@ -1417,7 +1417,13 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
1417
1417
|
});
|
|
1418
1418
|
|
|
1419
1419
|
void this.#toggleSearchElementAction.execute();
|
|
1420
|
-
|
|
1420
|
+
try {
|
|
1421
|
+
return await result;
|
|
1422
|
+
} finally {
|
|
1423
|
+
if (this.#toggleSearchElementAction.toggled()) {
|
|
1424
|
+
void this.#toggleSearchElementAction.execute();
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1421
1427
|
}
|
|
1422
1428
|
|
|
1423
1429
|
async #startConversation(
|
|
@@ -42,7 +42,11 @@ const UIStrings = {
|
|
|
42
42
|
/**
|
|
43
43
|
* @description Label added to the button that remove the currently selected context in AI Assistance panel.
|
|
44
44
|
*/
|
|
45
|
-
removeContext: 'Remove
|
|
45
|
+
removeContext: 'Remove from context',
|
|
46
|
+
/**
|
|
47
|
+
* @description Label added to the button that add selected context from the current panel in AI Assistance panel.
|
|
48
|
+
*/
|
|
49
|
+
addContext: 'Add selected item as context',
|
|
46
50
|
} as const;
|
|
47
51
|
|
|
48
52
|
/*
|
|
@@ -387,8 +391,8 @@ export const
|
|
|
387
391
|
:
|
|
388
392
|
input.onContextAdd ? html`
|
|
389
393
|
<devtools-button
|
|
390
|
-
title=${i18nString(UIStrings.
|
|
391
|
-
aria-label=${i18nString(UIStrings.
|
|
394
|
+
title=${i18nString(UIStrings.addContext)}
|
|
395
|
+
aria-label=${i18nString(UIStrings.addContext)}
|
|
392
396
|
class="add-context"
|
|
393
397
|
.iconName=${'plus'}
|
|
394
398
|
.size=${Buttons.Button.Size.SMALL}
|
|
@@ -22,7 +22,7 @@ import * as VisualLogging from '../../../ui/visual_logging/visual_logging.js';
|
|
|
22
22
|
|
|
23
23
|
import * as PreloadingComponents from './components/components.js';
|
|
24
24
|
import {ruleSetTagOrLocationShort} from './components/PreloadingString.js';
|
|
25
|
-
import
|
|
25
|
+
import * as PreloadingHelper from './helper/helper.js';
|
|
26
26
|
import preloadingViewStyles from './preloadingView.css.js';
|
|
27
27
|
import preloadingViewDropDownStyles from './preloadingViewDropDown.css.js';
|
|
28
28
|
|
|
@@ -501,10 +501,17 @@ export class PreloadingAttemptView extends UI.Widget.VBox {
|
|
|
501
501
|
const ruleSet = this.model.getRuleSetById(id);
|
|
502
502
|
return ruleSet === null ? [] : [ruleSet];
|
|
503
503
|
});
|
|
504
|
+
|
|
505
|
+
// Lookup status code for prefetch attempts
|
|
506
|
+
const statusCode = attempt.action === Protocol.Preload.SpeculationAction.Prefetch ?
|
|
507
|
+
PreloadingHelper.PreloadingForward.prefetchStatusCode(attempt.requestId) :
|
|
508
|
+
undefined;
|
|
509
|
+
|
|
504
510
|
return {
|
|
505
511
|
id,
|
|
506
512
|
pipeline,
|
|
507
513
|
ruleSets,
|
|
514
|
+
statusCode,
|
|
508
515
|
};
|
|
509
516
|
});
|
|
510
517
|
this.preloadingGrid.rows = rows;
|
|
@@ -349,7 +349,10 @@ export class PreloadingDetailsReportView extends LegacyWrapper.LegacyWrapper.Wra
|
|
|
349
349
|
return Lit.nothing;
|
|
350
350
|
}
|
|
351
351
|
|
|
352
|
-
|
|
352
|
+
// Lookup status code for Non2XX failures
|
|
353
|
+
const statusCode = PreloadingHelper.PreloadingForward.prefetchStatusCode(attempt.requestId);
|
|
354
|
+
|
|
355
|
+
const failureDescription = prefetchFailureReason(attempt, statusCode);
|
|
353
356
|
if (failureDescription === null) {
|
|
354
357
|
return Lit.nothing;
|
|
355
358
|
}
|
|
@@ -51,6 +51,7 @@ export interface PreloadingGridRow {
|
|
|
51
51
|
id: string;
|
|
52
52
|
pipeline: SDK.PreloadingModel.PreloadPipeline;
|
|
53
53
|
ruleSets: Protocol.Preload.RuleSet[];
|
|
54
|
+
statusCode?: number;
|
|
54
55
|
}
|
|
55
56
|
|
|
56
57
|
export interface ViewInput {
|
|
@@ -107,7 +108,7 @@ export const PRELOADING_GRID_DEFAULT_VIEW: View = (input, _output, target): void
|
|
|
107
108
|
'vertical-align': 'sub',
|
|
108
109
|
})}
|
|
109
110
|
></devtools-icon>` : ''}
|
|
110
|
-
${hasWarning ? i18nString(UIStrings.prefetchFallbackReady) : composedStatus(attempt)}
|
|
111
|
+
${hasWarning ? i18nString(UIStrings.prefetchFallbackReady) : composedStatus(attempt, row.statusCode)}
|
|
111
112
|
</div>
|
|
112
113
|
</td>
|
|
113
114
|
</tr>`;
|
|
@@ -31,6 +31,11 @@ const UIStrings = {
|
|
|
31
31
|
* @description Description text for Prefetch status PrefetchFailedNon2XX.
|
|
32
32
|
*/
|
|
33
33
|
PrefetchFailedNon2XX: 'The prefetch failed because of a non-2xx HTTP response status code.',
|
|
34
|
+
/**
|
|
35
|
+
* @description Description text for Prefetch status PrefetchFailedNon2XX when the HTTP status code is known.
|
|
36
|
+
* @example {404} PH1
|
|
37
|
+
*/
|
|
38
|
+
PrefetchFailedNon2XXWithStatusCode: 'The prefetch failed because of a non-2xx HTTP response status code ({PH1}).',
|
|
34
39
|
/**
|
|
35
40
|
* @description Description text for Prefetch status PrefetchIneligibleRetryAfter.
|
|
36
41
|
*/
|
|
@@ -446,7 +451,8 @@ export const PrefetchReasonDescription: Record<string, {name: () => Platform.UIS
|
|
|
446
451
|
};
|
|
447
452
|
|
|
448
453
|
/** Decoding PrefetchFinalStatus prefetchAttempt to failure description. **/
|
|
449
|
-
export function prefetchFailureReason(
|
|
454
|
+
export function prefetchFailureReason(
|
|
455
|
+
{prefetchStatus}: SDK.PreloadingModel.PrefetchAttempt, statusCode?: number): string|null {
|
|
450
456
|
// If you face an error on rolling CDP changes, see
|
|
451
457
|
// https://docs.google.com/document/d/1PnrfowsZMt62PX1EvvTp2Nqs3ji1zrklrAEe1JYbkTk
|
|
452
458
|
switch (prefetchStatus) {
|
|
@@ -478,6 +484,9 @@ export function prefetchFailureReason({prefetchStatus}: SDK.PreloadingModel.Pref
|
|
|
478
484
|
case Protocol.Preload.PrefetchStatus.PrefetchFailedNetError:
|
|
479
485
|
return PrefetchReasonDescription['PrefetchFailedNetError'].name();
|
|
480
486
|
case Protocol.Preload.PrefetchStatus.PrefetchFailedNon2XX:
|
|
487
|
+
if (statusCode !== undefined) {
|
|
488
|
+
return i18nString(UIStrings.PrefetchFailedNon2XXWithStatusCode, {PH1: String(statusCode)});
|
|
489
|
+
}
|
|
481
490
|
return PrefetchReasonDescription['PrefetchFailedNon2XX'].name();
|
|
482
491
|
case Protocol.Preload.PrefetchStatus.PrefetchIneligibleRetryAfter:
|
|
483
492
|
return PrefetchReasonDescription['PrefetchIneligibleRetryAfter'].name();
|
|
@@ -795,7 +804,7 @@ export function status(status: SDK.PreloadingModel.PreloadingStatus): string {
|
|
|
795
804
|
}
|
|
796
805
|
}
|
|
797
806
|
|
|
798
|
-
export function composedStatus(attempt: SDK.PreloadingModel.PreloadingAttempt): string {
|
|
807
|
+
export function composedStatus(attempt: SDK.PreloadingModel.PreloadingAttempt, statusCode?: number): string {
|
|
799
808
|
const short = status(attempt.status);
|
|
800
809
|
|
|
801
810
|
if (attempt.status !== SDK.PreloadingModel.PreloadingStatus.FAILURE) {
|
|
@@ -804,7 +813,7 @@ export function composedStatus(attempt: SDK.PreloadingModel.PreloadingAttempt):
|
|
|
804
813
|
|
|
805
814
|
switch (attempt.action) {
|
|
806
815
|
case Protocol.Preload.SpeculationAction.Prefetch: {
|
|
807
|
-
const detail = prefetchFailureReason(attempt) ?? i18n.i18n.lockedString('Internal error');
|
|
816
|
+
const detail = prefetchFailureReason(attempt, statusCode) ?? i18n.i18n.lockedString('Internal error');
|
|
808
817
|
return short + ' - ' + detail;
|
|
809
818
|
}
|
|
810
819
|
case Protocol.Preload.SpeculationAction.Prerender:
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// found in the LICENSE file.
|
|
4
4
|
|
|
5
5
|
import type * as Protocol from '../../../../generated/protocol.js';
|
|
6
|
+
import * as Logs from '../../../../models/logs/logs.js';
|
|
6
7
|
|
|
7
8
|
export class RuleSetView {
|
|
8
9
|
readonly ruleSetId: Protocol.Preload.RuleSetId|null;
|
|
@@ -19,3 +20,16 @@ export class AttemptViewWithFilter {
|
|
|
19
20
|
this.ruleSetId = ruleSetId;
|
|
20
21
|
}
|
|
21
22
|
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Retrieves the HTTP status code for a prefetch attempt by looking up its
|
|
26
|
+
* network request in the network log.
|
|
27
|
+
*/
|
|
28
|
+
export function prefetchStatusCode(requestId: Protocol.Network.RequestId): number|undefined {
|
|
29
|
+
const networkLog = Logs.NetworkLog.NetworkLog.instance();
|
|
30
|
+
const requests = networkLog.requestsForId(requestId);
|
|
31
|
+
if (requests.length > 0) {
|
|
32
|
+
return requests[requests.length - 1].statusCode;
|
|
33
|
+
}
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
@@ -134,6 +134,9 @@ interface ViewOutput {
|
|
|
134
134
|
interface ViewInput {
|
|
135
135
|
onFilterChanged: (filterText: string|null) => void;
|
|
136
136
|
onBreakpointChange: (breakpoint: SDK.CategorizedBreakpoint.CategorizedBreakpoint, enabled: boolean) => void;
|
|
137
|
+
onItemSelected: (item: SDK.CategorizedBreakpoint.Category|SDK.CategorizedBreakpoint.CategorizedBreakpoint|
|
|
138
|
+
null) => void;
|
|
139
|
+
onSpaceKeyDown: () => void;
|
|
137
140
|
|
|
138
141
|
filterText: string|null;
|
|
139
142
|
userExpandedCategories: Set<SDK.CategorizedBreakpoint.Category>;
|
|
@@ -200,6 +203,13 @@ export const DEFAULT_VIEW = (input: ViewInput, output: ViewOutput, target: HTMLE
|
|
|
200
203
|
}
|
|
201
204
|
};
|
|
202
205
|
|
|
206
|
+
const onKeyDown = (e: KeyboardEvent): void => {
|
|
207
|
+
if (e.key === ' ') {
|
|
208
|
+
input.onSpaceKeyDown();
|
|
209
|
+
e.preventDefault();
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
|
|
203
213
|
render(
|
|
204
214
|
// clang-format off
|
|
205
215
|
html`
|
|
@@ -210,10 +220,11 @@ export const DEFAULT_VIEW = (input: ViewInput, output: ViewOutput, target: HTMLE
|
|
|
210
220
|
style="flex: 1;"
|
|
211
221
|
></devtools-toolbar-input>
|
|
212
222
|
</devtools-toolbar>
|
|
213
|
-
<devtools-tree autofocus .template=${html`
|
|
223
|
+
<devtools-tree autofocus @keydown=${onKeyDown} .template=${html`
|
|
214
224
|
<ul role="tree">
|
|
215
225
|
${filteredCategories.map(([category, breakpoints]) => html`
|
|
216
|
-
<li @
|
|
226
|
+
<li @select=${() => input.onItemSelected(category)}
|
|
227
|
+
@expand=${(e: UI.TreeOutline.TreeViewElement.ExpandEvent) => onExpand(category, e)}
|
|
217
228
|
role="treeitem"
|
|
218
229
|
jslog-context=${category}
|
|
219
230
|
aria-checked=${breakpoints.some(breakpoint => breakpoint.enabled())
|
|
@@ -233,7 +244,7 @@ export const DEFAULT_VIEW = (input: ViewInput, output: ViewOutput, target: HTMLE
|
|
|
233
244
|
role="group"
|
|
234
245
|
?hidden=${!shouldExpandCategory(breakpoints) && !input.userExpandedCategories.has(category)}>
|
|
235
246
|
${breakpoints.map(breakpoint => html`
|
|
236
|
-
<li
|
|
247
|
+
<li @select=${() => input.onItemSelected(breakpoint)}
|
|
237
248
|
role="treeitem"
|
|
238
249
|
aria-checked=${breakpoint.enabled()}
|
|
239
250
|
jslog-context=${Platform.StringUtilities.toKebabCase(breakpoint.name)}>
|
|
@@ -265,6 +276,7 @@ export abstract class CategorizedBreakpointsSidebarPane extends UI.Widget.VBox {
|
|
|
265
276
|
#filterText: string|null = null;
|
|
266
277
|
#view: View;
|
|
267
278
|
#userExpandedCategories = new Set<SDK.CategorizedBreakpoint.Category>();
|
|
279
|
+
#selectedItem: SDK.CategorizedBreakpoint.Category|SDK.CategorizedBreakpoint.CategorizedBreakpoint|null = null;
|
|
268
280
|
constructor(
|
|
269
281
|
breakpoints: SDK.CategorizedBreakpoint.CategorizedBreakpoint[], jslog: string, viewId: string,
|
|
270
282
|
view = DEFAULT_VIEW) {
|
|
@@ -321,6 +333,26 @@ export abstract class CategorizedBreakpointsSidebarPane extends UI.Widget.VBox {
|
|
|
321
333
|
this.requestUpdate();
|
|
322
334
|
}
|
|
323
335
|
|
|
336
|
+
#onItemSelected(item: SDK.CategorizedBreakpoint.Category|SDK.CategorizedBreakpoint.CategorizedBreakpoint|null): void {
|
|
337
|
+
this.#selectedItem = item;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
#onSpaceKeyDown(): void {
|
|
341
|
+
const selected = this.#selectedItem;
|
|
342
|
+
if (!selected) {
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
if (selected instanceof SDK.CategorizedBreakpoint.CategorizedBreakpoint) {
|
|
346
|
+
this.onBreakpointChanged(selected, !selected.enabled());
|
|
347
|
+
} else {
|
|
348
|
+
const breakpoints = this.categories.get(selected);
|
|
349
|
+
if (breakpoints) {
|
|
350
|
+
const newEnabled = breakpoints.some(bp => !bp.enabled());
|
|
351
|
+
breakpoints.forEach(bp => this.onBreakpointChanged(bp, newEnabled));
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
324
356
|
protected onBreakpointChanged(breakpoint: SDK.CategorizedBreakpoint.CategorizedBreakpoint, enabled: boolean): void {
|
|
325
357
|
breakpoint.setEnabled(enabled);
|
|
326
358
|
this.requestUpdate();
|
|
@@ -331,6 +363,8 @@ export abstract class CategorizedBreakpointsSidebarPane extends UI.Widget.VBox {
|
|
|
331
363
|
filterText: this.#filterText,
|
|
332
364
|
onFilterChanged: this.#onFilterChanged.bind(this),
|
|
333
365
|
onBreakpointChange: this.onBreakpointChanged.bind(this),
|
|
366
|
+
onItemSelected: this.#onItemSelected.bind(this),
|
|
367
|
+
onSpaceKeyDown: this.#onSpaceKeyDown.bind(this),
|
|
334
368
|
sortedCategoryNames: this.#sortedCategories,
|
|
335
369
|
categories: this.categories,
|
|
336
370
|
highlightedItem: this.#highlightedItem,
|
|
@@ -24,7 +24,7 @@ const UIStrings = {
|
|
|
24
24
|
} as const;
|
|
25
25
|
const str_ = i18n.i18n.registerUIStrings('panels/changes/ChangesSidebar.ts', UIStrings);
|
|
26
26
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
27
|
-
const {render, html
|
|
27
|
+
const {render, html} = Lit;
|
|
28
28
|
interface ViewInput {
|
|
29
29
|
selectedSourceCode: Workspace.UISourceCode.UISourceCode|null;
|
|
30
30
|
onSelect: (uiSourceCode: Workspace.UISourceCode.UISourceCode|null) => void;
|
|
@@ -38,20 +38,16 @@ export const DEFAULT_VIEW: View = (input, output, target) => {
|
|
|
38
38
|
uiSourceCode.url();
|
|
39
39
|
const icon = (uiSourceCode: Workspace.UISourceCode.UISourceCode): string =>
|
|
40
40
|
Snippets.ScriptSnippetFileSystem.isSnippetsUISourceCode(uiSourceCode) ? 'snippet' : 'document';
|
|
41
|
-
const configElements = new WeakMap<HTMLLIElement, Workspace.UISourceCode.UISourceCode>();
|
|
42
|
-
const onSelect = (e: UI.TreeOutline.TreeViewElement.SelectEvent): void =>
|
|
43
|
-
input.onSelect(configElements.get(e.detail) ?? null);
|
|
44
41
|
render(
|
|
45
42
|
// clang-format off
|
|
46
43
|
html`<devtools-tree
|
|
47
|
-
@selected=${onSelect}
|
|
48
44
|
navigation-variant
|
|
49
45
|
hide-overflow .template=${html`
|
|
50
46
|
<ul role="tree">
|
|
51
47
|
${input.sourceCodes.values().map(uiSourceCode => html`
|
|
52
48
|
<li
|
|
53
49
|
role="treeitem"
|
|
54
|
-
|
|
50
|
+
@select=${() => input.onSelect(uiSourceCode)}
|
|
55
51
|
?selected=${uiSourceCode === input.selectedSourceCode}>
|
|
56
52
|
<style>${changesSidebarStyles}</style>
|
|
57
53
|
<div class=${'navigator-' + uiSourceCode.contentType().name() + '-tree-item'}>
|
|
@@ -50,7 +50,7 @@ const UIStrings = {
|
|
|
50
50
|
} as const;
|
|
51
51
|
const str_ = i18n.i18n.registerUIStrings('panels/console/ConsoleSidebar.ts', UIStrings);
|
|
52
52
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
53
|
-
const {render, html, nothing
|
|
53
|
+
const {render, html, nothing} = Lit;
|
|
54
54
|
|
|
55
55
|
export const enum GroupName {
|
|
56
56
|
CONSOLE_API = 'user message',
|
|
@@ -78,18 +78,10 @@ interface ViewInput {
|
|
|
78
78
|
|
|
79
79
|
export type View = (input: ViewInput, output: object, target: HTMLElement) => void;
|
|
80
80
|
export const DEFAULT_VIEW: View = (input, output, target) => {
|
|
81
|
-
const nodeFilterMap = new WeakMap<Element, ConsoleFilter>();
|
|
82
|
-
const onSelectionChanged = (event: UI.TreeOutline.TreeViewElement.SelectEvent): void => {
|
|
83
|
-
const filter = nodeFilterMap.get(event.detail);
|
|
84
|
-
if (filter) {
|
|
85
|
-
input.onSelectionChanged(filter);
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
81
|
render(
|
|
89
82
|
html`<devtools-tree
|
|
90
83
|
navigation-variant
|
|
91
84
|
hide-overflow
|
|
92
|
-
@select=${onSelectionChanged}
|
|
93
85
|
.template=${
|
|
94
86
|
html`
|
|
95
87
|
<ul role="tree">
|
|
@@ -98,7 +90,7 @@ export const DEFAULT_VIEW: View = (input, output, target) => {
|
|
|
98
90
|
group => html`
|
|
99
91
|
<li
|
|
100
92
|
role="treeitem"
|
|
101
|
-
|
|
93
|
+
@select=${() => input.onSelectionChanged(group.filter)}
|
|
102
94
|
?selected=${group.filter === input.selectedFilter}>
|
|
103
95
|
<style>${consoleSidebarStyles}</style>
|
|
104
96
|
<devtools-icon name=${GROUP_ICONS[group.name].icon}></devtools-icon>
|
|
@@ -112,7 +104,7 @@ export const DEFAULT_VIEW: View = (input, output, target) => {
|
|
|
112
104
|
<ul role="group" hidden>
|
|
113
105
|
${group.urlGroups.values().map(urlGroup => html`
|
|
114
106
|
<li
|
|
115
|
-
|
|
107
|
+
@select=${() => input.onSelectionChanged(urlGroup.filter)}
|
|
116
108
|
role="treeitem"
|
|
117
109
|
?selected=${urlGroup.filter === input.selectedFilter}
|
|
118
110
|
title=${urlGroup.url ?? ''}>
|
|
@@ -166,8 +166,6 @@ export class StartView extends UI.Widget.Widget {
|
|
|
166
166
|
checkbox.setIndeterminate(true);
|
|
167
167
|
}
|
|
168
168
|
}
|
|
169
|
-
UI.ARIAUtils.markAsGroup(categoryFormElements);
|
|
170
|
-
UI.ARIAUtils.setLabel(categoryFormElements, i18nString(UIStrings.categories));
|
|
171
169
|
}
|
|
172
170
|
|
|
173
171
|
private render(): void {
|
|
@@ -194,10 +192,10 @@ export class StartView extends UI.Widget.Widget {
|
|
|
194
192
|
<div class="lighthouse-form-elements" $="device-type-form-elements"></div>
|
|
195
193
|
</div>
|
|
196
194
|
<div class="lighthouse-form-categories">
|
|
197
|
-
<
|
|
198
|
-
<
|
|
195
|
+
<fieldset class="lighthouse-form-section lighthouse-form-categories-fieldset">
|
|
196
|
+
<legend class="lighthouse-form-section-label">${i18nString(UIStrings.categories)}</legend>
|
|
199
197
|
<div class="lighthouse-form-elements" $="categories-form-elements"></div>
|
|
200
|
-
</
|
|
198
|
+
</fieldset>
|
|
201
199
|
</div>
|
|
202
200
|
</div>
|
|
203
201
|
<div $="warning-text" class="lighthouse-warning-text hidden"></div>
|
|
@@ -1933,14 +1933,14 @@ export class NetworkLogView extends Common.ObjectWrapper.eventMixin<EventTypes,
|
|
|
1933
1933
|
const isThrottling = existingConditions &&
|
|
1934
1934
|
existingConditions.conditions !== SDK.NetworkManager.BlockingConditions &&
|
|
1935
1935
|
existingConditions.conditions !== SDK.NetworkManager.NoThrottlingConditions;
|
|
1936
|
+
const croppedURL = Platform.StringUtilities.trimMiddle(urlPattern.constructorString, maxBlockedURLLength);
|
|
1936
1937
|
blockingMenu.debugSection().appendItem(
|
|
1937
|
-
isBlocking ? i18nString(UIStrings.unblockS, {PH1:
|
|
1938
|
-
i18nString(UIStrings.blockRequestUrl),
|
|
1938
|
+
isBlocking ? i18nString(UIStrings.unblockS, {PH1: croppedURL}) : i18nString(UIStrings.blockRequestUrl),
|
|
1939
1939
|
() => isBlocking ? removeRequestCondition(urlPattern) :
|
|
1940
1940
|
addRequestCondition(urlPattern, SDK.NetworkManager.BlockingConditions),
|
|
1941
1941
|
{jslogContext: 'block-request-url'});
|
|
1942
1942
|
throttlingMenu.debugSection().appendItem(
|
|
1943
|
-
isThrottling ? i18nString(UIStrings.unthrottleS, {PH1:
|
|
1943
|
+
isThrottling ? i18nString(UIStrings.unthrottleS, {PH1: croppedURL}) :
|
|
1944
1944
|
i18nString(UIStrings.throttleRequestUrl),
|
|
1945
1945
|
() => isThrottling ? removeRequestCondition(urlPattern) :
|
|
1946
1946
|
addRequestCondition(urlPattern, SDK.NetworkManager.Slow3GConditions),
|
|
@@ -1959,14 +1959,14 @@ export class NetworkLogView extends Common.ObjectWrapper.eventMixin<EventTypes,
|
|
|
1959
1959
|
const isThrottling = existingConditions &&
|
|
1960
1960
|
existingConditions.conditions !== SDK.NetworkManager.BlockingConditions &&
|
|
1961
1961
|
existingConditions.conditions !== SDK.NetworkManager.NoThrottlingConditions;
|
|
1962
|
+
const croppedURL = Platform.StringUtilities.trimMiddle(domainPattern.constructorString, maxBlockedURLLength);
|
|
1962
1963
|
blockingMenu.debugSection().appendItem(
|
|
1963
|
-
isBlocking ? i18nString(UIStrings.unblockS, {PH1:
|
|
1964
|
-
i18nString(UIStrings.blockRequestDomain),
|
|
1964
|
+
isBlocking ? i18nString(UIStrings.unblockS, {PH1: croppedURL}) : i18nString(UIStrings.blockRequestDomain),
|
|
1965
1965
|
() => isBlocking ? removeRequestCondition(domainPattern) :
|
|
1966
1966
|
addRequestCondition(domainPattern, SDK.NetworkManager.BlockingConditions),
|
|
1967
1967
|
{jslogContext: 'block-request-domain'});
|
|
1968
1968
|
throttlingMenu.debugSection().appendItem(
|
|
1969
|
-
isThrottling ? i18nString(UIStrings.unthrottleS, {PH1:
|
|
1969
|
+
isThrottling ? i18nString(UIStrings.unthrottleS, {PH1: croppedURL}) :
|
|
1970
1970
|
i18nString(UIStrings.throttleRequestDomain),
|
|
1971
1971
|
() => isThrottling ? removeRequestCondition(domainPattern) :
|
|
1972
1972
|
addRequestCondition(domainPattern, SDK.NetworkManager.Slow3GConditions),
|
|
@@ -37,7 +37,7 @@ const str_ = i18n.i18n.registerUIStrings('panels/network/RequestInitiatorView.ts
|
|
|
37
37
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
38
38
|
export interface ViewInput {
|
|
39
39
|
initiatorGraph: Logs.NetworkLog.InitiatorGraph;
|
|
40
|
-
|
|
40
|
+
stackTrace: StackTrace.StackTrace.StackTrace|null;
|
|
41
41
|
request: SDK.NetworkRequest.NetworkRequest;
|
|
42
42
|
linkifier: Components.Linkifier.Linkifier;
|
|
43
43
|
target?: SDK.Target.Target;
|
|
@@ -45,7 +45,7 @@ export interface ViewInput {
|
|
|
45
45
|
|
|
46
46
|
export const DEFAULT_VIEW = (input: ViewInput, _output: undefined, target: HTMLElement): void => {
|
|
47
47
|
const hasInitiatorData =
|
|
48
|
-
input.initiatorGraph.initiators.size > 1 || input.initiatorGraph.initiated.size > 1 || input.
|
|
48
|
+
input.initiatorGraph.initiators.size > 1 || input.initiatorGraph.initiated.size > 1 || input.stackTrace;
|
|
49
49
|
|
|
50
50
|
if (!hasInitiatorData) {
|
|
51
51
|
render(
|
|
@@ -59,6 +59,9 @@ export const DEFAULT_VIEW = (input: ViewInput, _output: undefined, target: HTMLE
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
const renderStackTraceSection = (): Lit.TemplateResult => {
|
|
62
|
+
if (!input.stackTrace) {
|
|
63
|
+
return html`${nothing}`;
|
|
64
|
+
}
|
|
62
65
|
return html`
|
|
63
66
|
<li role="treeitem" class="request-initiator-view-section-title" aria-expanded="true">
|
|
64
67
|
${i18nString(UIStrings.requestCallStack)}
|
|
@@ -67,7 +70,8 @@ export const DEFAULT_VIEW = (input: ViewInput, _output: undefined, target: HTMLE
|
|
|
67
70
|
<devtools-widget .widgetConfig=${widgetConfig(Components.JSPresentationUtils.StackTracePreviewContent, {
|
|
68
71
|
target: input.target,
|
|
69
72
|
linkifier: input.linkifier,
|
|
70
|
-
options: {
|
|
73
|
+
options: {tabStops: true},
|
|
74
|
+
stackTrace: input.stackTrace,
|
|
71
75
|
})}></devtools-widget>
|
|
72
76
|
</li>
|
|
73
77
|
</ul>
|
|
@@ -146,7 +150,7 @@ export const DEFAULT_VIEW = (input: ViewInput, _output: undefined, target: HTMLE
|
|
|
146
150
|
${requestInitiatorViewTreeStyles}
|
|
147
151
|
</style>
|
|
148
152
|
<ul role="tree">
|
|
149
|
-
${
|
|
153
|
+
${renderStackTraceSection()}
|
|
150
154
|
${
|
|
151
155
|
(input.initiatorGraph.initiators.size > 1 || input.initiatorGraph.initiated.size > 1) ?
|
|
152
156
|
renderInitiatorChain(input.initiatorGraph) :
|
|
@@ -198,15 +202,22 @@ export class RequestInitiatorView extends UI.Widget.VBox {
|
|
|
198
202
|
return {preview, stackTrace};
|
|
199
203
|
}
|
|
200
204
|
|
|
201
|
-
override performUpdate(): void {
|
|
205
|
+
override async performUpdate(): Promise<void> {
|
|
202
206
|
const initiatorGraph = Logs.NetworkLog.NetworkLog.instance().initiatorGraphForRequest(this.request);
|
|
203
|
-
const
|
|
207
|
+
const targetManager = SDK.TargetManager.TargetManager.instance();
|
|
204
208
|
const networkManager = SDK.NetworkManager.NetworkManager.forRequest(this.request);
|
|
205
|
-
const target = networkManager
|
|
209
|
+
const target = networkManager?.target() ?? targetManager.primaryPageTarget() ?? targetManager.rootTarget();
|
|
210
|
+
|
|
211
|
+
const rawStack = this.request.initiator()?.stack;
|
|
212
|
+
let stackTrace: StackTrace.StackTrace.StackTrace|null = null;
|
|
213
|
+
if (rawStack && target) {
|
|
214
|
+
stackTrace = await Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance()
|
|
215
|
+
.createStackTraceFromProtocolRuntime(rawStack, target);
|
|
216
|
+
}
|
|
206
217
|
|
|
207
218
|
const viewInput: ViewInput = {
|
|
208
219
|
initiatorGraph,
|
|
209
|
-
|
|
220
|
+
stackTrace,
|
|
210
221
|
request: this.request,
|
|
211
222
|
linkifier: this.linkifier,
|
|
212
223
|
target: target || undefined,
|
|
@@ -10,7 +10,6 @@ import * as i18n from '../../core/i18n/i18n.js';
|
|
|
10
10
|
import type * as Platform from '../../core/platform/platform.js';
|
|
11
11
|
import * as Root from '../../core/root/root.js';
|
|
12
12
|
import * as AiAssistanceModel from '../../models/ai_assistance/ai_assistance.js';
|
|
13
|
-
import * as AiCodeGeneration from '../../models/ai_code_generation/ai_code_generation.js';
|
|
14
13
|
import * as Buttons from '../../ui/components/buttons/buttons.js';
|
|
15
14
|
import * as Input from '../../ui/components/input/input.js';
|
|
16
15
|
import * as Switch from '../../ui/components/switch/switch.js';
|
|
@@ -537,10 +536,7 @@ export class AISettingsTab extends UI.Widget.VBox {
|
|
|
537
536
|
}
|
|
538
537
|
|
|
539
538
|
if (this.#aiCodeCompletionSetting) {
|
|
540
|
-
const
|
|
541
|
-
const isAiCodeGenerationEnabled =
|
|
542
|
-
AiCodeGeneration.AiCodeGeneration.AiCodeGeneration.isAiCodeGenerationEnabled(devtoolsLocale.locale);
|
|
543
|
-
const settingItems = isAiCodeGenerationEnabled ?
|
|
539
|
+
const settingItems = Root.Runtime.hostConfig.devToolsAiCodeGeneration?.enabled ?
|
|
544
540
|
[
|
|
545
541
|
{iconName: 'code', text: i18nString(UIStrings.asYouTypeRelevantDataIsBeingSentToGoogle)}, {
|
|
546
542
|
iconName: 'text-analysis',
|
|
@@ -631,16 +631,6 @@ const GREENDEV_VIEW: View = (input, _output, target) => {
|
|
|
631
631
|
${renderPrototypeCheckboxes(input.settings, ['aiAnnotations', 'inDevToolsFloaty', 'copyToGemini'])}
|
|
632
632
|
</div>
|
|
633
633
|
</devtools-card>
|
|
634
|
-
|
|
635
|
-
<devtools-card .heading=${'GreenDev widgets'}>
|
|
636
|
-
<div class="experiments-warning-subsection">
|
|
637
|
-
<devtools-icon .name=${'warning'}></devtools-icon>
|
|
638
|
-
<span>${i18nString(UIStrings.greenDevUnstable)}</span>
|
|
639
|
-
</div>
|
|
640
|
-
<div class="settings-experiments-block greendev-widgets">
|
|
641
|
-
${renderWidgetOptions(input.settings)}
|
|
642
|
-
</div>
|
|
643
|
-
</devtools-card>
|
|
644
634
|
</div>
|
|
645
635
|
`, target);
|
|
646
636
|
// clang-format on
|
|
@@ -649,50 +639,9 @@ const GREENDEV_VIEW: View = (input, _output, target) => {
|
|
|
649
639
|
const GREENDEV_PROTOTYPE_NAMES: Record<keyof GreenDev.GreenDevSettings, string> = {
|
|
650
640
|
inDevToolsFloaty: 'In DevTools context picker',
|
|
651
641
|
aiAnnotations: 'AI auto-annotations',
|
|
652
|
-
inlineWidgets: 'Inline widgets in AI Assistance',
|
|
653
|
-
artifactViewer: 'Widgets in the Artifact viewer',
|
|
654
642
|
copyToGemini: 'Copy changes to AI Prompt'
|
|
655
643
|
};
|
|
656
644
|
|
|
657
|
-
function renderWidgetOptions(settings: GreenDev.GreenDevSettings): TemplateResult {
|
|
658
|
-
function onChange(nowActiveRadio: 'inlineWidgets'|'artifactViewer'|'none') {
|
|
659
|
-
return () => {
|
|
660
|
-
switch (nowActiveRadio) {
|
|
661
|
-
case 'inlineWidgets': {
|
|
662
|
-
settings.artifactViewer.set(false);
|
|
663
|
-
settings.inlineWidgets.set(true);
|
|
664
|
-
break;
|
|
665
|
-
}
|
|
666
|
-
case 'artifactViewer': {
|
|
667
|
-
settings.artifactViewer.set(true);
|
|
668
|
-
settings.inlineWidgets.set(false);
|
|
669
|
-
break;
|
|
670
|
-
}
|
|
671
|
-
case 'none': {
|
|
672
|
-
settings.artifactViewer.set(false);
|
|
673
|
-
settings.inlineWidgets.set(false);
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
UI.InspectorView.InspectorView.instance().displayReloadRequiredWarning(
|
|
678
|
-
i18nString(UIStrings.settingsChangedReloadDevTools));
|
|
679
|
-
};
|
|
680
|
-
}
|
|
681
|
-
// clang-format off
|
|
682
|
-
return html`
|
|
683
|
-
<p class="settings-experiment">
|
|
684
|
-
<label><input type="radio" name="widgets-choice" @change=${onChange('inlineWidgets')}>${GREENDEV_PROTOTYPE_NAMES['inlineWidgets']}</label>
|
|
685
|
-
</p>
|
|
686
|
-
<p class="settings-experiment">
|
|
687
|
-
<label><input type="radio" name="widgets-choice" @change=${onChange('artifactViewer')}>${GREENDEV_PROTOTYPE_NAMES['artifactViewer']}</label>
|
|
688
|
-
</p>
|
|
689
|
-
<p class="settings-experiment">
|
|
690
|
-
<label><input type="radio" name="widgets-choice" @change=${onChange('none')}>None</label>
|
|
691
|
-
</p>
|
|
692
|
-
`;
|
|
693
|
-
// clang-format on
|
|
694
|
-
}
|
|
695
|
-
|
|
696
645
|
function renderPrototypeCheckboxes(
|
|
697
646
|
settings: GreenDev.GreenDevSettings,
|
|
698
647
|
keys: Array<keyof GreenDev.GreenDevSettings>,
|
|
@@ -48,7 +48,10 @@ export class AnimationsTrackAppender implements TrackAppender {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
#appendTrackHeaderAtLevel(currentLevel: number, expanded?: boolean): void {
|
|
51
|
-
const style = buildGroupStyle({
|
|
51
|
+
const style = buildGroupStyle({
|
|
52
|
+
useFirstLineForOverview: false,
|
|
53
|
+
collapsible: PerfUI.FlameChart.GroupCollapsibleState.IF_MULTI_ROW,
|
|
54
|
+
});
|
|
52
55
|
const group = buildTrackHeader(
|
|
53
56
|
VisualLoggingTrackName.ANIMATIONS, currentLevel, i18nString(UIStrings.animations), style,
|
|
54
57
|
/* selectable= */ true, expanded);
|
|
@@ -71,7 +71,7 @@ export class InteractionsTrackAppender implements TrackAppender {
|
|
|
71
71
|
#appendTrackHeaderAtLevel(currentLevel: number, expanded?: boolean): void {
|
|
72
72
|
const trackIsCollapsible = this.#parsedTrace.data.UserInteractions.interactionEvents.length > 0;
|
|
73
73
|
const style = buildGroupStyle({
|
|
74
|
-
collapsible: trackIsCollapsible ? PerfUI.FlameChart.GroupCollapsibleState.
|
|
74
|
+
collapsible: trackIsCollapsible ? PerfUI.FlameChart.GroupCollapsibleState.IF_MULTI_ROW :
|
|
75
75
|
PerfUI.FlameChart.GroupCollapsibleState.NEVER,
|
|
76
76
|
useDecoratorsForOverview: true,
|
|
77
77
|
});
|