chrome-devtools-frontend 1.0.1530564 → 1.0.1532228
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/AUTHORS +2 -0
- package/front_end/core/protocol_client/InspectorBackend.ts +15 -6
- package/front_end/core/protocol_client/protocol_client.ts +0 -10
- package/front_end/core/sdk/NetworkManager.ts +155 -41
- package/front_end/core/sdk/SourceMap.ts +6 -1
- package/front_end/core/sdk/SourceMapScopesInfo.ts +73 -7
- package/front_end/generated/ARIAProperties.js +1301 -174
- package/front_end/generated/Deprecation.ts +7 -0
- package/front_end/generated/InspectorBackendCommands.js +1 -0
- package/front_end/generated/protocol-mapping.d.ts +4 -0
- package/front_end/generated/protocol-proxy-api.d.ts +5 -0
- package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.snapshot.txt +1 -1
- package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.ts +1 -1
- package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatterBounds.snapshot.txt +4 -0
- package/front_end/models/bindings/CompilerScriptMapping.ts +16 -14
- package/front_end/models/issues_manager/AttributionReportingIssue.ts +4 -3
- package/front_end/models/issues_manager/BounceTrackingIssue.ts +4 -3
- package/front_end/models/issues_manager/ClientHintIssue.ts +4 -3
- package/front_end/models/issues_manager/ContentSecurityPolicyIssue.ts +4 -3
- package/front_end/models/issues_manager/CookieDeprecationMetadataIssue.ts +5 -3
- package/front_end/models/issues_manager/CookieIssue.ts +4 -4
- package/front_end/models/issues_manager/CorsIssue.ts +3 -3
- package/front_end/models/issues_manager/CrossOriginEmbedderPolicyIssue.ts +2 -1
- package/front_end/models/issues_manager/DeprecationIssue.ts +4 -3
- package/front_end/models/issues_manager/ElementAccessibilityIssue.ts +4 -3
- package/front_end/models/issues_manager/FederatedAuthRequestIssue.ts +4 -3
- package/front_end/models/issues_manager/GenericIssue.ts +3 -3
- package/front_end/models/issues_manager/HeavyAdIssue.ts +3 -3
- package/front_end/models/issues_manager/IssuesManager.ts +3 -3
- package/front_end/models/issues_manager/LowTextContrastIssue.ts +5 -3
- package/front_end/models/issues_manager/MixedContentIssue.ts +4 -3
- package/front_end/models/issues_manager/PartitioningBlobURLIssue.ts +5 -3
- package/front_end/models/issues_manager/PropertyRuleIssue.ts +4 -3
- package/front_end/models/issues_manager/QuirksModeIssue.ts +4 -3
- package/front_end/models/issues_manager/SRIMessageSignatureIssue.ts +5 -3
- package/front_end/models/issues_manager/SharedArrayBufferIssue.ts +5 -3
- package/front_end/models/issues_manager/SharedDictionaryIssue.ts +5 -3
- package/front_end/models/issues_manager/StylesheetLoadingIssue.ts +5 -3
- package/front_end/models/issues_manager/UnencodedDigestIssue.ts +5 -3
- package/front_end/models/issues_manager/UserReidentificationIssue.ts +4 -3
- package/front_end/models/javascript_metadata/NativeFunctions.js +8 -2
- package/front_end/models/trace/insights/ForcedReflow.ts +1 -1
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +17 -4
- package/front_end/panels/console/ConsoleInsightTeaser.ts +111 -60
- package/front_end/panels/console/ConsoleSidebar.ts +3 -3
- package/front_end/panels/network/NetworkLogView.ts +135 -33
- package/front_end/panels/network/{BlockedURLsPane.ts → RequestConditionsDrawer.ts} +64 -23
- package/front_end/panels/network/network-meta.ts +33 -9
- package/front_end/panels/network/network.ts +3 -3
- package/front_end/panels/network/{blockedURLsPane.css → requestConditionsDrawer.css} +5 -0
- package/front_end/panels/recorder/components/stepView.css +2 -2
- package/front_end/panels/sources/SourcesSearchScope.ts +5 -0
- package/front_end/panels/sources/sources-meta.ts +1 -0
- package/front_end/panels/timeline/components/insights/ForcedReflow.ts +2 -2
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/ui/legacy/components/cookie_table/CookiesTable.ts +31 -5
- package/front_end/ui/legacy/components/utils/TargetDetachedDialog.ts +3 -0
- package/front_end/ui/visual_logging/KnownContextValues.ts +5 -0
- package/package.json +1 -1
|
@@ -15,7 +15,8 @@ export const lateImportStylesheetLoadingCode = [
|
|
|
15
15
|
|
|
16
16
|
export class StylesheetLoadingIssue extends Issue {
|
|
17
17
|
#issueDetails: Protocol.Audits.StylesheetLoadingIssueDetails;
|
|
18
|
-
constructor(
|
|
18
|
+
constructor(
|
|
19
|
+
issueDetails: Protocol.Audits.StylesheetLoadingIssueDetails, issuesModel: SDK.IssuesModel.IssuesModel|null) {
|
|
19
20
|
const code =
|
|
20
21
|
`${Protocol.Audits.InspectorIssueCode.StylesheetLoadingIssue}::${issueDetails.styleSheetLoadingIssueReason}`;
|
|
21
22
|
super(code, issuesModel);
|
|
@@ -67,8 +68,9 @@ export class StylesheetLoadingIssue extends Issue {
|
|
|
67
68
|
return IssueKind.PAGE_ERROR;
|
|
68
69
|
}
|
|
69
70
|
|
|
70
|
-
static fromInspectorIssue(
|
|
71
|
-
|
|
71
|
+
static fromInspectorIssue(
|
|
72
|
+
issueModel: SDK.IssuesModel.IssuesModel|null,
|
|
73
|
+
inspectorIssue: Protocol.Audits.InspectorIssue): StylesheetLoadingIssue[] {
|
|
72
74
|
const stylesheetLoadingDetails = inspectorIssue.details.stylesheetLoadingIssueDetails;
|
|
73
75
|
if (!stylesheetLoadingDetails) {
|
|
74
76
|
console.warn('Stylesheet loading issue without details received');
|
|
@@ -29,7 +29,8 @@ const i18nLazyString = i18n.i18n.getLazilyComputedLocalizedString.bind(undefined
|
|
|
29
29
|
export class UnencodedDigestIssue extends Issue<string> {
|
|
30
30
|
readonly #issueDetails: Protocol.Audits.UnencodedDigestIssueDetails;
|
|
31
31
|
|
|
32
|
-
constructor(
|
|
32
|
+
constructor(
|
|
33
|
+
issueDetails: Protocol.Audits.UnencodedDigestIssueDetails, issuesModel: SDK.IssuesModel.IssuesModel|null) {
|
|
33
34
|
super(
|
|
34
35
|
{
|
|
35
36
|
code: `${Protocol.Audits.InspectorIssueCode.UnencodedDigestIssue}::${issueDetails.error}`,
|
|
@@ -76,8 +77,9 @@ export class UnencodedDigestIssue extends Issue<string> {
|
|
|
76
77
|
return this.details().request ? [this.details().request] : [];
|
|
77
78
|
}
|
|
78
79
|
|
|
79
|
-
static fromInspectorIssue(
|
|
80
|
-
|
|
80
|
+
static fromInspectorIssue(
|
|
81
|
+
issuesModel: SDK.IssuesModel.IssuesModel|null,
|
|
82
|
+
inspectorIssue: Protocol.Audits.InspectorIssue): UnencodedDigestIssue[] {
|
|
81
83
|
const details = inspectorIssue.details.unencodedDigestIssueDetails;
|
|
82
84
|
if (!details) {
|
|
83
85
|
console.warn('Unencoded-Digest issue without details received.');
|
|
@@ -16,7 +16,7 @@ export class UserReidentificationIssue extends Issue {
|
|
|
16
16
|
#issueDetails: Protocol.Audits.UserReidentificationIssueDetails;
|
|
17
17
|
|
|
18
18
|
constructor(
|
|
19
|
-
issueDetails: Protocol.Audits.UserReidentificationIssueDetails, issuesModel: SDK.IssuesModel.IssuesModel) {
|
|
19
|
+
issueDetails: Protocol.Audits.UserReidentificationIssueDetails, issuesModel: SDK.IssuesModel.IssuesModel|null) {
|
|
20
20
|
super('UserReidentificationIssue', issuesModel);
|
|
21
21
|
this.#issueDetails = issueDetails;
|
|
22
22
|
}
|
|
@@ -46,8 +46,9 @@ export class UserReidentificationIssue extends Issue {
|
|
|
46
46
|
return IssueKind.IMPROVEMENT;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
static fromInspectorIssue(
|
|
50
|
-
|
|
49
|
+
static fromInspectorIssue(
|
|
50
|
+
issuesModel: SDK.IssuesModel.IssuesModel|null,
|
|
51
|
+
inspectorIssue: Protocol.Audits.InspectorIssue): UserReidentificationIssue[] {
|
|
51
52
|
const userReidentificationIssueDetails = inspectorIssue.details.userReidentificationIssueDetails;
|
|
52
53
|
if (!userReidentificationIssueDetails) {
|
|
53
54
|
console.warn('User Reidentification issue without details received.');
|
|
@@ -6041,7 +6041,13 @@ export const NativeFunctions = [
|
|
|
6041
6041
|
},
|
|
6042
6042
|
{
|
|
6043
6043
|
name: "waitUntil",
|
|
6044
|
-
signatures: [["f"]]
|
|
6044
|
+
signatures: [["f"]],
|
|
6045
|
+
receivers: ["ExtendableEvent"]
|
|
6046
|
+
},
|
|
6047
|
+
{
|
|
6048
|
+
name: "waitUntil",
|
|
6049
|
+
signatures: [["promise"]],
|
|
6050
|
+
receivers: ["ViewTransition"]
|
|
6045
6051
|
},
|
|
6046
6052
|
{
|
|
6047
6053
|
name: "respondWith",
|
|
@@ -8237,7 +8243,7 @@ export const NativeFunctions = [
|
|
|
8237
8243
|
},
|
|
8238
8244
|
{
|
|
8239
8245
|
name: "softmax",
|
|
8240
|
-
signatures: [["input","
|
|
8246
|
+
signatures: [["input","axis","?options"]]
|
|
8241
8247
|
},
|
|
8242
8248
|
{
|
|
8243
8249
|
name: "softplus",
|
|
@@ -31,7 +31,7 @@ export const UIStrings = {
|
|
|
31
31
|
/**
|
|
32
32
|
* @description Title of a list to provide related stack trace data
|
|
33
33
|
*/
|
|
34
|
-
|
|
34
|
+
reflowCallFrames: 'Call frames that trigger reflow',
|
|
35
35
|
/**
|
|
36
36
|
* @description Text to describe the top time-consuming function call
|
|
37
37
|
*/
|
|
@@ -1091,7 +1091,16 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
1091
1091
|
// Node picker is using linkifier.
|
|
1092
1092
|
}
|
|
1093
1093
|
|
|
1094
|
-
|
|
1094
|
+
#canExecuteQuery(): boolean {
|
|
1095
|
+
const isBrandedBuild = Boolean(Root.Runtime.hostConfig.aidaAvailability?.enabled);
|
|
1096
|
+
const isBlockedByAge = Boolean(Root.Runtime.hostConfig.aidaAvailability?.blockedByAge);
|
|
1097
|
+
const isAidaAvailable = Boolean(this.#aidaAvailability === Host.AidaClient.AidaAccessPreconditions.AVAILABLE);
|
|
1098
|
+
const isUserOptedIn = Boolean(this.#aiAssistanceEnabledSetting?.getIfNotDisabled());
|
|
1099
|
+
|
|
1100
|
+
return isBrandedBuild && isAidaAvailable && isUserOptedIn && !isBlockedByAge;
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
async handleAction(actionId: string, opts?: Record<string, unknown>): Promise<void> {
|
|
1095
1104
|
if (this.#isLoading && !opts?.['prompt']) {
|
|
1096
1105
|
// If running some queries already, and this action doesn't contain a predefined prompt, focus the input with the abort
|
|
1097
1106
|
// button and do nothing.
|
|
@@ -1160,13 +1169,17 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
1160
1169
|
this.#updateConversationState({agent});
|
|
1161
1170
|
const predefinedPrompt = opts?.['prompt'];
|
|
1162
1171
|
if (predefinedPrompt && typeof predefinedPrompt === 'string') {
|
|
1172
|
+
if (!this.#canExecuteQuery()) {
|
|
1173
|
+
return;
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1163
1176
|
this.#imageInput = undefined;
|
|
1164
1177
|
this.#isTextInputEmpty = true;
|
|
1165
1178
|
Host.userMetrics.actionTaken(Host.UserMetrics.Action.AiAssistanceQuerySubmitted);
|
|
1166
1179
|
if (this.#blockedByCrossOrigin) {
|
|
1167
1180
|
this.#handleNewChatRequest();
|
|
1168
1181
|
}
|
|
1169
|
-
|
|
1182
|
+
await this.#startConversation(predefinedPrompt);
|
|
1170
1183
|
} else {
|
|
1171
1184
|
this.#viewOutput.chatView?.focusTextInput();
|
|
1172
1185
|
}
|
|
@@ -1187,7 +1200,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
1187
1200
|
|
|
1188
1201
|
contextMenu.defaultSection().appendCheckboxItem(title, () => {
|
|
1189
1202
|
void this.#openHistoricConversation(conversation);
|
|
1190
|
-
}, {checked: (this.#conversation === conversation)});
|
|
1203
|
+
}, {checked: (this.#conversation === conversation), jslogContext: 'freestyler.history-item'});
|
|
1191
1204
|
}
|
|
1192
1205
|
|
|
1193
1206
|
const historyEmpty = contextMenu.defaultSection().items.length === 0;
|
|
@@ -1671,7 +1684,7 @@ export class ActionDelegate implements UI.ActionRegistration.ActionDelegate {
|
|
|
1671
1684
|
}
|
|
1672
1685
|
|
|
1673
1686
|
const widget = (await view.widget()) as AiAssistancePanel;
|
|
1674
|
-
widget.handleAction(actionId, opts);
|
|
1687
|
+
void widget.handleAction(actionId, opts);
|
|
1675
1688
|
})();
|
|
1676
1689
|
return true;
|
|
1677
1690
|
}
|
|
@@ -61,6 +61,10 @@ const UIStringsNotTranslate = {
|
|
|
61
61
|
* @description Header text during loading state while an AI summary is being generated
|
|
62
62
|
*/
|
|
63
63
|
summarizing: 'Summarizing…',
|
|
64
|
+
/**
|
|
65
|
+
* @description Header text during longer lasting loading state while an AI summary is being generated
|
|
66
|
+
*/
|
|
67
|
+
summarizingTakesABitLonger: 'Summarizing takes a bit longer…',
|
|
64
68
|
/**
|
|
65
69
|
* @description Label for an animation shown while an AI response is being generated
|
|
66
70
|
*/
|
|
@@ -77,6 +81,10 @@ const UIStringsNotTranslate = {
|
|
|
77
81
|
* @description Aria-label for an infor-button triggering a tooltip with more info about data usage
|
|
78
82
|
*/
|
|
79
83
|
learnDataUsage: 'Learn more about how your data is used',
|
|
84
|
+
/**
|
|
85
|
+
* @description Header text if there was an error during AI summary generation
|
|
86
|
+
*/
|
|
87
|
+
summaryNotAvailable: 'Summary not available',
|
|
80
88
|
} as const;
|
|
81
89
|
|
|
82
90
|
const lockedString = i18n.i18n.lockedString;
|
|
@@ -84,6 +92,7 @@ const lockedString = i18n.i18n.lockedString;
|
|
|
84
92
|
const CODE_SNIPPET_WARNING_URL = 'https://support.google.com/legal/answer/13505487';
|
|
85
93
|
const DATA_USAGE_URL = 'https://developer.chrome.com/docs/devtools/ai-assistance/get-started#data-use';
|
|
86
94
|
const EXPLAIN_TEASER_ACTION_ID = 'explain.console-message.teaser';
|
|
95
|
+
const SLOW_GENERATION_CUTOFF_MILLISECONDS = 3500;
|
|
87
96
|
|
|
88
97
|
interface ViewInput {
|
|
89
98
|
onTellMeMoreClick: (event: Event) => void;
|
|
@@ -95,6 +104,8 @@ interface ViewInput {
|
|
|
95
104
|
isInactive: boolean;
|
|
96
105
|
dontShowChanged: (e: Event) => void;
|
|
97
106
|
hasTellMeMoreButton: boolean;
|
|
107
|
+
isSlowGeneration: boolean;
|
|
108
|
+
isError: boolean;
|
|
98
109
|
}
|
|
99
110
|
|
|
100
111
|
export const DEFAULT_VIEW = (input: ViewInput, _output: undefined, target: HTMLElement): void => {
|
|
@@ -104,6 +115,51 @@ export const DEFAULT_VIEW = (input: ViewInput, _output: undefined, target: HTMLE
|
|
|
104
115
|
}
|
|
105
116
|
|
|
106
117
|
const showPlaceholder = !Boolean(input.mainText);
|
|
118
|
+
const renderFooter = (): Lit.LitTemplate => {
|
|
119
|
+
// clang-format off
|
|
120
|
+
return html`
|
|
121
|
+
<div class="tooltip-footer">
|
|
122
|
+
${input.hasTellMeMoreButton ? html`
|
|
123
|
+
<devtools-button
|
|
124
|
+
title=${lockedString(UIStringsNotTranslate.tellMeMore)}
|
|
125
|
+
.jslogContext=${'insights-teaser-tell-me-more'},
|
|
126
|
+
.variant=${Buttons.Button.Variant.PRIMARY}
|
|
127
|
+
@click=${input.onTellMeMoreClick}
|
|
128
|
+
>
|
|
129
|
+
<devtools-icon class="lightbulb-icon" name="lightbulb-spark"></devtools-icon>
|
|
130
|
+
${lockedString(UIStringsNotTranslate.tellMeMore)}
|
|
131
|
+
</devtools-button>
|
|
132
|
+
` : Lit.nothing}
|
|
133
|
+
${showPlaceholder ? Lit.nothing : html`
|
|
134
|
+
<devtools-button
|
|
135
|
+
.iconName=${'info'}
|
|
136
|
+
.variant=${Buttons.Button.Variant.ICON}
|
|
137
|
+
aria-details=${'teaser-info-tooltip-' + input.uuid}
|
|
138
|
+
aria-label=${lockedString(UIStringsNotTranslate.learnDataUsage)}
|
|
139
|
+
></devtools-button>
|
|
140
|
+
<devtools-tooltip id=${'teaser-info-tooltip-' + input.uuid} variant="rich">
|
|
141
|
+
<div class="info-tooltip-text">${lockedString(UIStringsNotTranslate.infoTooltipText)}</div>
|
|
142
|
+
<div class="learn-more">
|
|
143
|
+
<x-link
|
|
144
|
+
class="devtools-link"
|
|
145
|
+
title=${lockedString(UIStringsNotTranslate.learnMoreAboutAiSummaries)}
|
|
146
|
+
href=${DATA_USAGE_URL}
|
|
147
|
+
jslog=${VisualLogging.link().track({click: true, keydown:'Enter|Space'}).context('explain.teaser.learn-more')}
|
|
148
|
+
>${lockedString(UIStringsNotTranslate.learnMoreAboutAiSummaries)}</x-link>
|
|
149
|
+
</div>
|
|
150
|
+
</devtools-tooltip>
|
|
151
|
+
`}
|
|
152
|
+
<devtools-checkbox
|
|
153
|
+
aria-label=${lockedString(UIStringsNotTranslate.dontShow)}
|
|
154
|
+
@change=${input.dontShowChanged}
|
|
155
|
+
jslog=${VisualLogging.toggle('explain.teaser.dont-show').track({ change: true })}>
|
|
156
|
+
${lockedString(UIStringsNotTranslate.dontShow)}
|
|
157
|
+
</devtools-checkbox>
|
|
158
|
+
</div>
|
|
159
|
+
`;
|
|
160
|
+
// clang-format on
|
|
161
|
+
};
|
|
162
|
+
|
|
107
163
|
// clang-format off
|
|
108
164
|
render(html`
|
|
109
165
|
<style>${consoleInsightTeaserStyles}</style>
|
|
@@ -115,64 +171,36 @@ export const DEFAULT_VIEW = (input: ViewInput, _output: undefined, target: HTMLE
|
|
|
115
171
|
prefer-span-left
|
|
116
172
|
>
|
|
117
173
|
<div class="teaser-tooltip-container">
|
|
118
|
-
${
|
|
119
|
-
<h2>${lockedString(UIStringsNotTranslate.
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
<
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
${lockedString(UIStringsNotTranslate.tellMeMore)}
|
|
149
|
-
</devtools-button>
|
|
150
|
-
` : Lit.nothing}
|
|
151
|
-
<devtools-button
|
|
152
|
-
.iconName=${'info'}
|
|
153
|
-
.variant=${Buttons.Button.Variant.ICON}
|
|
154
|
-
aria-details=${'teaser-info-tooltip-' + input.uuid}
|
|
155
|
-
aria-label=${lockedString(UIStringsNotTranslate.learnDataUsage)}
|
|
156
|
-
></devtools-button>
|
|
157
|
-
<devtools-tooltip id=${'teaser-info-tooltip-' + input.uuid} variant="rich">
|
|
158
|
-
<div class="info-tooltip-text">${lockedString(UIStringsNotTranslate.infoTooltipText)}</div>
|
|
159
|
-
<div class="learn-more">
|
|
160
|
-
<x-link
|
|
161
|
-
class="devtools-link"
|
|
162
|
-
title=${lockedString(UIStringsNotTranslate.learnMoreAboutAiSummaries)}
|
|
163
|
-
href=${DATA_USAGE_URL}
|
|
164
|
-
jslog=${VisualLogging.link().track({click: true, keydown:'Enter|Space'}).context('explain.teaser.learn-more')}
|
|
165
|
-
>${lockedString(UIStringsNotTranslate.learnMoreAboutAiSummaries)}</x-link>
|
|
166
|
-
</div>
|
|
167
|
-
</devtools-tooltip>
|
|
168
|
-
<devtools-checkbox
|
|
169
|
-
aria-label=${lockedString(UIStringsNotTranslate.dontShow)}
|
|
170
|
-
@change=${input.dontShowChanged}
|
|
171
|
-
jslog=${VisualLogging.toggle('explain.teaser.dont-show').track({ change: true })}>
|
|
172
|
-
${lockedString(UIStringsNotTranslate.dontShow)}
|
|
173
|
-
</devtools-checkbox>
|
|
174
|
-
</div>
|
|
175
|
-
`}
|
|
174
|
+
${input.isError ? html`
|
|
175
|
+
<h2>${lockedString(UIStringsNotTranslate.summaryNotAvailable)}</h2>
|
|
176
|
+
` :
|
|
177
|
+
showPlaceholder ? html`
|
|
178
|
+
<h2>${input.isSlowGeneration ?
|
|
179
|
+
lockedString(UIStringsNotTranslate.summarizingTakesABitLonger) :
|
|
180
|
+
lockedString(UIStringsNotTranslate.summarizing)
|
|
181
|
+
}</h2>
|
|
182
|
+
<div
|
|
183
|
+
role="presentation"
|
|
184
|
+
aria-label=${lockedString(UIStringsNotTranslate.loading)}
|
|
185
|
+
class="loader"
|
|
186
|
+
style="clip-path: url(${'#clipPath-' + input.uuid});"
|
|
187
|
+
>
|
|
188
|
+
<svg width="100%" height="52">
|
|
189
|
+
<defs>
|
|
190
|
+
<clipPath id=${'clipPath-' + input.uuid}>
|
|
191
|
+
<rect x="0" y="0" width="100%" height="12" rx="8"></rect>
|
|
192
|
+
<rect x="0" y="20" width="100%" height="12" rx="8"></rect>
|
|
193
|
+
<rect x="0" y="40" width="100%" height="12" rx="8"></rect>
|
|
194
|
+
</clipPath>
|
|
195
|
+
</defs>
|
|
196
|
+
</svg>
|
|
197
|
+
</div>
|
|
198
|
+
` : html`
|
|
199
|
+
<h2>${input.headerText}</h2>
|
|
200
|
+
<div>${input.mainText}</div>
|
|
201
|
+
`
|
|
202
|
+
}
|
|
203
|
+
${input.isError || input.isSlowGeneration || !showPlaceholder ? renderFooter() : Lit.nothing}
|
|
176
204
|
</div>
|
|
177
205
|
</devtools-tooltip>
|
|
178
206
|
`, target);
|
|
@@ -192,6 +220,9 @@ export class ConsoleInsightTeaser extends UI.Widget.Widget {
|
|
|
192
220
|
#consoleViewMessage: ConsoleViewMessage;
|
|
193
221
|
#isInactive = false;
|
|
194
222
|
#abortController: null|AbortController = null;
|
|
223
|
+
#isSlow = false;
|
|
224
|
+
#timeoutId: ReturnType<typeof setTimeout>|null = null;
|
|
225
|
+
#isError = false;
|
|
195
226
|
|
|
196
227
|
constructor(uuid: string, consoleViewMessage: ConsoleViewMessage, element?: HTMLElement, view?: View) {
|
|
197
228
|
super(element);
|
|
@@ -285,6 +316,9 @@ export class ConsoleInsightTeaser extends UI.Widget.Widget {
|
|
|
285
316
|
this.#abortController.abort();
|
|
286
317
|
}
|
|
287
318
|
this.#isGenerating = false;
|
|
319
|
+
if (this.#timeoutId) {
|
|
320
|
+
clearTimeout(this.#timeoutId);
|
|
321
|
+
}
|
|
288
322
|
}
|
|
289
323
|
|
|
290
324
|
setInactive(isInactive: boolean): void {
|
|
@@ -295,8 +329,14 @@ export class ConsoleInsightTeaser extends UI.Widget.Widget {
|
|
|
295
329
|
this.requestUpdate();
|
|
296
330
|
}
|
|
297
331
|
|
|
332
|
+
#setSlow(): void {
|
|
333
|
+
this.#isSlow = true;
|
|
334
|
+
this.requestUpdate();
|
|
335
|
+
}
|
|
336
|
+
|
|
298
337
|
async #generateTeaserText(): Promise<void> {
|
|
299
338
|
this.#isGenerating = true;
|
|
339
|
+
this.#timeoutId = setTimeout(this.#setSlow.bind(this), SLOW_GENERATION_CUTOFF_MILLISECONDS);
|
|
300
340
|
let teaserText = '';
|
|
301
341
|
try {
|
|
302
342
|
for await (const chunk of this.#getOnDeviceInsight()) {
|
|
@@ -306,12 +346,16 @@ export class ConsoleInsightTeaser extends UI.Widget.Widget {
|
|
|
306
346
|
// Ignore `AbortError` errors, which are thrown on mouse leave.
|
|
307
347
|
if (err.name !== 'AbortError') {
|
|
308
348
|
console.error(err.name, err.message);
|
|
349
|
+
this.#isError = true;
|
|
309
350
|
}
|
|
310
351
|
this.#isGenerating = false;
|
|
352
|
+
clearTimeout(this.#timeoutId);
|
|
353
|
+
this.requestUpdate();
|
|
311
354
|
return;
|
|
312
355
|
}
|
|
313
356
|
|
|
314
|
-
|
|
357
|
+
clearTimeout(this.#timeoutId);
|
|
358
|
+
this.#isGenerating = false;
|
|
315
359
|
let responseObject = {
|
|
316
360
|
header: null,
|
|
317
361
|
explanation: null,
|
|
@@ -320,10 +364,15 @@ export class ConsoleInsightTeaser extends UI.Widget.Widget {
|
|
|
320
364
|
responseObject = JSON.parse(teaserText);
|
|
321
365
|
} catch (err) {
|
|
322
366
|
console.error(err.name, err.message);
|
|
367
|
+
this.#isError = true;
|
|
368
|
+
this.requestUpdate();
|
|
369
|
+
return;
|
|
323
370
|
}
|
|
324
371
|
this.#headerText = responseObject.header || '';
|
|
325
372
|
this.#mainText = responseObject.explanation || '';
|
|
326
|
-
this.#
|
|
373
|
+
if (!this.#headerText || !this.#mainText) {
|
|
374
|
+
this.#isError = true;
|
|
375
|
+
}
|
|
327
376
|
this.requestUpdate();
|
|
328
377
|
}
|
|
329
378
|
|
|
@@ -373,6 +422,8 @@ export class ConsoleInsightTeaser extends UI.Widget.Widget {
|
|
|
373
422
|
!Common.Settings.Settings.instance().moduleSetting('console-insight-teasers-enabled').get(),
|
|
374
423
|
dontShowChanged: this.#dontShowChanged.bind(this),
|
|
375
424
|
hasTellMeMoreButton: this.#hasTellMeMoreButton(),
|
|
425
|
+
isSlowGeneration: this.#isSlow,
|
|
426
|
+
isError: this.#isError,
|
|
376
427
|
},
|
|
377
428
|
undefined, this.contentElement);
|
|
378
429
|
}
|
|
@@ -52,7 +52,7 @@ const str_ = i18n.i18n.registerUIStrings('panels/console/ConsoleSidebar.ts', UIS
|
|
|
52
52
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
53
53
|
const {render, html, nothing, Directives} = Lit;
|
|
54
54
|
|
|
55
|
-
const enum GroupName {
|
|
55
|
+
export const enum GroupName {
|
|
56
56
|
CONSOLE_API = 'user message',
|
|
57
57
|
ALL = 'message',
|
|
58
58
|
ERROR = 'error',
|
|
@@ -112,7 +112,7 @@ export const DEFAULT_VIEW: View = (input, output, target) => {
|
|
|
112
112
|
<ul role="group" hidden>
|
|
113
113
|
${group.urlGroups.values().map(urlGroup => html`
|
|
114
114
|
<li
|
|
115
|
-
${Directives.ref(element => element && nodeFilterMap.set(element,
|
|
115
|
+
${Directives.ref(element => element && nodeFilterMap.set(element, urlGroup.filter))}
|
|
116
116
|
role="treeitem"
|
|
117
117
|
?selected=${urlGroup.filter === input.selectedFilter}
|
|
118
118
|
title=${urlGroup.url ?? ''}>
|
|
@@ -126,7 +126,7 @@ export const DEFAULT_VIEW: View = (input, output, target) => {
|
|
|
126
126
|
target);
|
|
127
127
|
};
|
|
128
128
|
|
|
129
|
-
class ConsoleFilterGroup {
|
|
129
|
+
export class ConsoleFilterGroup {
|
|
130
130
|
readonly urlGroups = new Map<string|null, {filter: ConsoleFilter, url: string|null, count: number}>();
|
|
131
131
|
messageCount = 0;
|
|
132
132
|
readonly name: GroupName;
|
|
@@ -432,6 +432,27 @@ const UIStrings = {
|
|
|
432
432
|
* @description A context menu item in the Network Log View of the Network panel
|
|
433
433
|
*/
|
|
434
434
|
clearBrowserCookies: 'Clear browser cookies',
|
|
435
|
+
/**
|
|
436
|
+
* @description A context menu item in the Network Log View of the Network panel
|
|
437
|
+
*/
|
|
438
|
+
throttleRequests: 'Throttle requests',
|
|
439
|
+
/**
|
|
440
|
+
* @description A context menu item in the Network Log View of the Network panel
|
|
441
|
+
*/
|
|
442
|
+
throttleRequestUrl: 'Throttle request URL',
|
|
443
|
+
/**
|
|
444
|
+
* @description A context menu item in the Network Log View of the Network panel
|
|
445
|
+
* @example {example.com} PH1
|
|
446
|
+
*/
|
|
447
|
+
unthrottleS: 'Stop throttling {PH1}',
|
|
448
|
+
/**
|
|
449
|
+
* @description A context menu item in the Network Log View of the Network panel
|
|
450
|
+
*/
|
|
451
|
+
throttleRequestDomain: 'Throttle request domain',
|
|
452
|
+
/**
|
|
453
|
+
* @description A context menu item in the Network Log View of the Network panel
|
|
454
|
+
*/
|
|
455
|
+
blockRequests: 'Block requests',
|
|
435
456
|
/**
|
|
436
457
|
* @description A context menu item in the Network Log View of the Network panel
|
|
437
458
|
*/
|
|
@@ -1849,43 +1870,124 @@ export class NetworkLogView extends Common.ObjectWrapper.eventMixin<EventTypes,
|
|
|
1849
1870
|
const maxBlockedURLLength = 20;
|
|
1850
1871
|
const manager = SDK.NetworkManager.MultitargetNetworkManager.instance();
|
|
1851
1872
|
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1873
|
+
if (!Root.Runtime.hostConfig.devToolsIndividualRequestThrottling?.enabled) {
|
|
1874
|
+
function addBlockedURL(url: string): void {
|
|
1875
|
+
manager.requestConditions.add(SDK.NetworkManager.RequestCondition.createFromSetting(
|
|
1876
|
+
{enabled: true, url: url as Platform.DevToolsPath.UrlString}));
|
|
1877
|
+
manager.requestConditions.conditionsEnabled = true;
|
|
1878
|
+
void UI.ViewManager.ViewManager.instance().showView('network.blocked-urls');
|
|
1879
|
+
}
|
|
1858
1880
|
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1881
|
+
function removeBlockedURL(url: string): void {
|
|
1882
|
+
const entry = manager.requestConditions.findCondition(url);
|
|
1883
|
+
if (entry) {
|
|
1884
|
+
manager.requestConditions.delete(entry);
|
|
1885
|
+
}
|
|
1886
|
+
void UI.ViewManager.ViewManager.instance().showView('network.blocked-urls');
|
|
1863
1887
|
}
|
|
1864
|
-
void UI.ViewManager.ViewManager.instance().showView('network.blocked-urls');
|
|
1865
|
-
}
|
|
1866
1888
|
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1889
|
+
const urlWithoutScheme = request.parsedURL.urlWithoutScheme();
|
|
1890
|
+
if (urlWithoutScheme && !manager.requestConditions.has(urlWithoutScheme)) {
|
|
1891
|
+
contextMenu.debugSection().appendItem(
|
|
1892
|
+
i18nString(UIStrings.blockRequestUrl), addBlockedURL.bind(null, urlWithoutScheme),
|
|
1893
|
+
{jslogContext: 'block-request-url'});
|
|
1894
|
+
} else if (urlWithoutScheme) {
|
|
1895
|
+
const croppedURL = Platform.StringUtilities.trimMiddle(urlWithoutScheme, maxBlockedURLLength);
|
|
1896
|
+
contextMenu.debugSection().appendItem(
|
|
1897
|
+
i18nString(UIStrings.unblockS, {PH1: croppedURL}), removeBlockedURL.bind(null, urlWithoutScheme),
|
|
1898
|
+
{jslogContext: 'unblock'});
|
|
1899
|
+
}
|
|
1878
1900
|
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1901
|
+
const domain = request.parsedURL.domain();
|
|
1902
|
+
if (domain && !manager.requestConditions.has(domain)) {
|
|
1903
|
+
contextMenu.debugSection().appendItem(
|
|
1904
|
+
i18nString(UIStrings.blockRequestDomain), addBlockedURL.bind(null, domain),
|
|
1905
|
+
{jslogContext: 'block-request-domain'});
|
|
1906
|
+
} else if (domain) {
|
|
1907
|
+
const croppedDomain = Platform.StringUtilities.trimMiddle(domain, maxBlockedURLLength);
|
|
1908
|
+
contextMenu.debugSection().appendItem(
|
|
1909
|
+
i18nString(UIStrings.unblockS, {PH1: croppedDomain}), removeBlockedURL.bind(null, domain),
|
|
1910
|
+
{jslogContext: 'unblock'});
|
|
1911
|
+
}
|
|
1912
|
+
} else {
|
|
1913
|
+
function removeRequestCondition(pattern: SDK.NetworkManager.RequestURLPattern): void {
|
|
1914
|
+
const entry = manager.requestConditions.findCondition(pattern.constructorString);
|
|
1915
|
+
if (entry) {
|
|
1916
|
+
manager.requestConditions.delete(entry);
|
|
1917
|
+
void UI.ViewManager.ViewManager.instance().showView('network.blocked-urls');
|
|
1918
|
+
}
|
|
1919
|
+
}
|
|
1920
|
+
|
|
1921
|
+
function addRequestCondition(
|
|
1922
|
+
pattern: SDK.NetworkManager.RequestURLPattern,
|
|
1923
|
+
conditions: SDK.NetworkManager.ThrottlingConditions,
|
|
1924
|
+
): void {
|
|
1925
|
+
const entry = manager.requestConditions.findCondition(pattern.constructorString);
|
|
1926
|
+
if (entry) {
|
|
1927
|
+
entry.conditions = conditions;
|
|
1928
|
+
} else {
|
|
1929
|
+
manager.requestConditions.add(SDK.NetworkManager.RequestCondition.create(pattern, conditions));
|
|
1930
|
+
}
|
|
1931
|
+
manager.requestConditions.conditionsEnabled = true;
|
|
1932
|
+
void UI.ViewManager.ViewManager.instance().showView('network.blocked-urls');
|
|
1933
|
+
}
|
|
1934
|
+
|
|
1935
|
+
const blockingMenu =
|
|
1936
|
+
contextMenu.debugSection().appendSubMenuItem(i18nString(UIStrings.blockRequests), /* disabled=*/ true);
|
|
1937
|
+
const throttlingMenu =
|
|
1938
|
+
contextMenu.debugSection().appendSubMenuItem(i18nString(UIStrings.throttleRequests), /* disabled=*/ true);
|
|
1939
|
+
|
|
1940
|
+
const urlWithoutScheme = request.parsedURL.urlWithoutScheme();
|
|
1941
|
+
const urlPattern = urlWithoutScheme &&
|
|
1942
|
+
SDK.NetworkManager.RequestURLPattern.create(
|
|
1943
|
+
`*://${urlWithoutScheme}` as SDK.NetworkManager.URLPatternConstructorString);
|
|
1944
|
+
if (urlPattern) {
|
|
1945
|
+
throttlingMenu.setEnabled(true);
|
|
1946
|
+
blockingMenu.setEnabled(true);
|
|
1947
|
+
const existingConditions = manager.requestConditions.findCondition(urlPattern.constructorString);
|
|
1948
|
+
const isBlocking = existingConditions?.conditions === SDK.NetworkManager.BlockingConditions;
|
|
1949
|
+
const isThrottling = existingConditions &&
|
|
1950
|
+
existingConditions.conditions !== SDK.NetworkManager.BlockingConditions &&
|
|
1951
|
+
existingConditions.conditions !== SDK.NetworkManager.NoThrottlingConditions;
|
|
1952
|
+
blockingMenu.debugSection().appendItem(
|
|
1953
|
+
isBlocking ? i18nString(UIStrings.unblockS, {PH1: urlPattern.constructorString}) :
|
|
1954
|
+
i18nString(UIStrings.blockRequestUrl),
|
|
1955
|
+
() => isBlocking ? removeRequestCondition(urlPattern) :
|
|
1956
|
+
addRequestCondition(urlPattern, SDK.NetworkManager.BlockingConditions),
|
|
1957
|
+
{jslogContext: 'block-request-url'});
|
|
1958
|
+
throttlingMenu.debugSection().appendItem(
|
|
1959
|
+
isThrottling ? i18nString(UIStrings.unthrottleS, {PH1: urlPattern.constructorString}) :
|
|
1960
|
+
i18nString(UIStrings.throttleRequestUrl),
|
|
1961
|
+
() => isThrottling ? removeRequestCondition(urlPattern) :
|
|
1962
|
+
addRequestCondition(urlPattern, SDK.NetworkManager.Slow3GConditions),
|
|
1963
|
+
{jslogContext: 'throttle-request-url'});
|
|
1964
|
+
}
|
|
1965
|
+
|
|
1966
|
+
const domain = request.parsedURL.domain();
|
|
1967
|
+
const domainPattern = domain &&
|
|
1968
|
+
SDK.NetworkManager.RequestURLPattern.create(
|
|
1969
|
+
`*://${domain}` as SDK.NetworkManager.URLPatternConstructorString);
|
|
1970
|
+
if (domainPattern) {
|
|
1971
|
+
throttlingMenu.setEnabled(true);
|
|
1972
|
+
blockingMenu.setEnabled(true);
|
|
1973
|
+
const existingConditions = manager.requestConditions.findCondition(domainPattern.constructorString);
|
|
1974
|
+
const isBlocking = existingConditions?.conditions === SDK.NetworkManager.BlockingConditions;
|
|
1975
|
+
const isThrottling = existingConditions &&
|
|
1976
|
+
existingConditions.conditions !== SDK.NetworkManager.BlockingConditions &&
|
|
1977
|
+
existingConditions.conditions !== SDK.NetworkManager.NoThrottlingConditions;
|
|
1978
|
+
blockingMenu.debugSection().appendItem(
|
|
1979
|
+
isBlocking ? i18nString(UIStrings.unblockS, {PH1: domainPattern.constructorString}) :
|
|
1980
|
+
i18nString(UIStrings.blockRequestDomain),
|
|
1981
|
+
() => isBlocking ? removeRequestCondition(domainPattern) :
|
|
1982
|
+
addRequestCondition(domainPattern, SDK.NetworkManager.BlockingConditions),
|
|
1983
|
+
{jslogContext: 'block-request-domain'});
|
|
1984
|
+
throttlingMenu.debugSection().appendItem(
|
|
1985
|
+
isThrottling ? i18nString(UIStrings.unthrottleS, {PH1: domainPattern.constructorString}) :
|
|
1986
|
+
i18nString(UIStrings.throttleRequestDomain),
|
|
1987
|
+
() => isThrottling ? removeRequestCondition(domainPattern) :
|
|
1988
|
+
addRequestCondition(domainPattern, SDK.NetworkManager.Slow3GConditions),
|
|
1989
|
+
{jslogContext: 'throttle-request-domain'});
|
|
1990
|
+
}
|
|
1889
1991
|
}
|
|
1890
1992
|
|
|
1891
1993
|
if (SDK.NetworkManager.NetworkManager.canReplayRequest(request)) {
|