chrome-devtools-frontend 1.0.1581449 → 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.
Files changed (95) hide show
  1. package/agents/prompts/merging-devtools-module.md +144 -0
  2. package/agents/prompts/ui-widgets.md +351 -0
  3. package/agents/prompts/verification.md +2 -1
  4. package/docs/contributing/README.md +5 -6
  5. package/docs/contributing/changes.md +1 -2
  6. package/docs/styleguide/ux/README.md +1 -1
  7. package/front_end/core/sdk/OverlayModel.ts +4 -2
  8. package/front_end/core/sdk/RemoteObject.ts +7 -1
  9. package/front_end/core/sdk/StorageKeyManager.ts +6 -1
  10. package/front_end/core/sdk/Target.ts +4 -2
  11. package/front_end/entrypoint_template.html +5 -1
  12. package/front_end/entrypoints/greendev_floaty/FloatyEntrypoint.ts +31 -40
  13. package/front_end/entrypoints/greendev_floaty/floaty.css +41 -1
  14. package/front_end/entrypoints/greendev_floaty/floaty.html +8 -1
  15. package/front_end/entrypoints/greendev_floaty/greendev_floaty.ts +5 -5
  16. package/front_end/entrypoints/node_app/app/NodeMain.ts +19 -1
  17. package/front_end/entrypoints/node_app/node_app.ts +34 -0
  18. package/front_end/generated/InspectorBackendCommands.ts +1 -1
  19. package/front_end/generated/SupportedCSSProperties.js +2 -0
  20. package/front_end/generated/protocol.ts +0 -6
  21. package/front_end/models/ai_assistance/AiConversation.ts +10 -0
  22. package/front_end/models/ai_assistance/agents/AiAgent.ts +2 -0
  23. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.snapshot.txt +26 -4
  24. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +85 -7
  25. package/front_end/models/ai_assistance/agents/NetworkAgent.ts +2 -6
  26. package/front_end/models/ai_assistance/data_formatters/NetworkRequestFormatter.ts +66 -2
  27. package/front_end/models/computed_style/ComputedStyleModel.ts +26 -0
  28. package/front_end/models/greendev/Prototypes.ts +1 -10
  29. package/front_end/models/issues_manager/ConnectionAllowlistIssue.ts +75 -0
  30. package/front_end/models/issues_manager/CookieIssue.ts +0 -28
  31. package/front_end/models/issues_manager/FederatedAuthRequestIssue.ts +0 -30
  32. package/front_end/models/issues_manager/IssuesManager.ts +5 -0
  33. package/front_end/models/issues_manager/descriptions/connectionAllowlistInvalidAllowlistItemType.md +12 -0
  34. package/front_end/models/issues_manager/descriptions/connectionAllowlistInvalidHeader.md +12 -0
  35. package/front_end/models/issues_manager/descriptions/connectionAllowlistInvalidUrlPattern.md +8 -0
  36. package/front_end/models/issues_manager/descriptions/connectionAllowlistItemNotInnerList.md +12 -0
  37. package/front_end/models/issues_manager/descriptions/connectionAllowlistMoreThanOneList.md +7 -0
  38. package/front_end/models/issues_manager/descriptions/connectionAllowlistReportingEndpointNotToken.md +10 -0
  39. package/front_end/models/issues_manager/issues_manager.ts +2 -0
  40. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +93 -6
  41. package/front_end/panels/ai_assistance/components/ChatInput.ts +8 -4
  42. package/front_end/panels/application/ApplicationPanelSidebar.ts +13 -11
  43. package/front_end/panels/application/DOMStorageModel.ts +1 -1
  44. package/front_end/panels/application/ResourcesPanel.ts +10 -5
  45. package/front_end/panels/application/preloading/PreloadingView.ts +8 -1
  46. package/front_end/panels/application/preloading/components/PreloadingDetailsReportView.ts +4 -1
  47. package/front_end/panels/application/preloading/components/PreloadingGrid.ts +2 -1
  48. package/front_end/panels/application/preloading/components/PreloadingString.ts +12 -3
  49. package/front_end/panels/application/preloading/helper/PreloadingForward.ts +14 -0
  50. package/front_end/panels/browser_debugger/CategorizedBreakpointsSidebarPane.ts +37 -3
  51. package/front_end/panels/changes/ChangesSidebar.ts +2 -6
  52. package/front_end/panels/common/AiCodeCompletionTeaser.ts +13 -3
  53. package/front_end/panels/common/aiCodeCompletionTeaser.css +6 -0
  54. package/front_end/panels/console/ConsoleSidebar.ts +3 -11
  55. package/front_end/panels/console_counters/WarningErrorCounter.ts +16 -10
  56. package/front_end/panels/elements/ComputedStyleWidget.ts +55 -37
  57. package/front_end/panels/elements/PlatformFontsWidget.ts +23 -10
  58. package/front_end/panels/greendev/GreenDevPanel.css +42 -1
  59. package/front_end/panels/greendev/GreenDevPanel.ts +30 -1
  60. package/front_end/panels/lighthouse/LighthouseStartView.ts +3 -5
  61. package/front_end/panels/lighthouse/lighthouseStartView.css +6 -0
  62. package/front_end/panels/network/NetworkLogView.ts +6 -6
  63. package/front_end/panels/network/RequestInitiatorView.ts +27 -19
  64. package/front_end/panels/network/RequestTimingView.ts +1 -1
  65. package/front_end/panels/settings/AISettingsTab.ts +1 -5
  66. package/front_end/panels/settings/KeybindsSettingsTab.ts +4 -3
  67. package/front_end/panels/settings/SettingsScreen.ts +0 -51
  68. package/front_end/panels/sources/OutlineQuickOpen.ts +19 -0
  69. package/front_end/panels/timeline/AnimationsTrackAppender.ts +4 -1
  70. package/front_end/panels/timeline/InteractionsTrackAppender.ts +1 -1
  71. package/front_end/panels/timeline/TimelinePanel.ts +25 -0
  72. package/front_end/panels/timeline/TimelineUIUtils.ts +13 -16
  73. package/front_end/third_party/chromium/README.chromium +1 -1
  74. package/front_end/third_party/lighthouse/README.chromium +2 -2
  75. package/front_end/third_party/lighthouse/lighthouse-dt-bundle.js +145 -144
  76. package/front_end/third_party/lighthouse/report/bundle.js +12 -5
  77. package/front_end/third_party/lighthouse/report-assets/report-generator.mjs +2 -2
  78. package/front_end/ui/components/markdown_view/MarkdownLinksMap.ts +5 -1
  79. package/front_end/ui/legacy/ListControl.ts +28 -1
  80. package/front_end/ui/legacy/Toolbar.ts +4 -4
  81. package/front_end/ui/legacy/Treeoutline.ts +5 -5
  82. package/front_end/ui/legacy/UIUtils.ts +26 -10
  83. package/front_end/ui/legacy/components/utils/JSPresentationUtils.ts +10 -13
  84. package/front_end/ui/legacy/components/utils/Linkifier.ts +4 -7
  85. package/front_end/ui/visual_logging/KnownContextValues.ts +2 -0
  86. package/inspector_overlay/main.ts +18 -3
  87. package/inspector_overlay/tool_green_dev_anchors.css +54 -0
  88. package/inspector_overlay/tool_green_dev_anchors.ts +164 -0
  89. package/inspector_overlay/tool_persistent.ts +14 -0
  90. package/package.json +1 -1
  91. package/docs/contributing/design.md +0 -166
  92. package/docs/design_guidelines.md +0 -1
  93. package/front_end/models/issues_manager/descriptions/federatedAuthRequestClientMetadataHttpNotFound.md +0 -1
  94. package/front_end/models/issues_manager/descriptions/federatedAuthRequestClientMetadataInvalidResponse.md +0 -1
  95. package/front_end/models/issues_manager/descriptions/federatedAuthRequestClientMetadataNoResponse.md +0 -1
@@ -9,7 +9,9 @@ import * as Platform from '../../../core/platform/platform.js';
9
9
  import * as Root from '../../../core/root/root.js';
10
10
  import * as SDK from '../../../core/sdk/sdk.js';
11
11
  import * as Logs from '../../logs/logs.js';
12
+ import type * as Trace from '../../trace/trace.js';
12
13
  import * as Workspace from '../../workspace/workspace.js';
14
+ import {AgentFocus} from '../performance/AIContext.js';
13
15
 
14
16
  import {
15
17
  type AgentOptions,
@@ -30,7 +32,7 @@ You aim to help developers of all levels, prioritizing teaching web concepts as
30
32
 
31
33
  # Considerations
32
34
  * Determine what the question the domain of the question is - styling, network, sources, performance or other part of DevTools.
33
- * When possible proactively try to gather additional data and select context that they user may find relevant to the question they are asking utilizing the function calls available to you.
35
+ * Proactively try to gather additional data. If a select specific data can be selected, select one.
34
36
  * Avoid making assumptions without sufficient evidence, and always seek further clarification if needed.
35
37
  * Always explore multiple possible explanations for the observed behavior before settling on a conclusion.
36
38
  * When presenting solutions, clearly distinguish between the primary cause and contributing factors.
@@ -71,11 +73,19 @@ export class ContextSelectionAgent extends AiAgent<never> {
71
73
  };
72
74
  }
73
75
 
74
- constructor(opts: AgentOptions) {
76
+ readonly #performanceRecordAndReload?: () => Promise<Trace.TraceModel.ParsedTrace>;
77
+ readonly #onInspectElement?: () => Promise<SDK.DOMModel.DOMNode|null>;
78
+
79
+ constructor(opts: AgentOptions&{
80
+ performanceRecordAndReload?: () => Promise<Trace.TraceModel.ParsedTrace>,
81
+ onInspectElement?: () => Promise<SDK.DOMModel.DOMNode|null>,
82
+ }) {
75
83
  super(opts);
84
+ this.#performanceRecordAndReload = opts.performanceRecordAndReload;
85
+ this.#onInspectElement = opts.onInspectElement;
76
86
 
77
87
  this.declareFunction<Record<string, never>>('listNetworkRequests', {
78
- description: `Gives a list of network requests including URL, status code, and duration in ms`,
88
+ description: `Gives a list of network requests including URL, status code, and duration in ms.`,
79
89
  parameters: {
80
90
  type: Host.AidaClient.ParametersTypes.OBJECT,
81
91
  description: '',
@@ -106,6 +116,12 @@ export class ContextSelectionAgent extends AiAgent<never> {
106
116
  });
107
117
  }
108
118
 
119
+ if (requests.length === 0) {
120
+ return {
121
+ error: 'No requests recorded by DevTools',
122
+ };
123
+ }
124
+
109
125
  return {
110
126
  result: requests,
111
127
  };
@@ -113,7 +129,8 @@ export class ContextSelectionAgent extends AiAgent<never> {
113
129
  });
114
130
 
115
131
  this.declareFunction<{url: string}>('selectNetworkRequest', {
116
- description: `From the list of selected request select one to debug`,
132
+ description:
133
+ `Selects a specific network request to further provide information about. Use this when asked about network requests issues.`,
117
134
  parameters: {
118
135
  type: Host.AidaClient.ParametersTypes.OBJECT,
119
136
  description: '',
@@ -181,7 +198,7 @@ export class ContextSelectionAgent extends AiAgent<never> {
181
198
  });
182
199
 
183
200
  this.declareFunction<{name: string}>('selectSourceFile', {
184
- description: `Returns a list of all files in the project.`,
201
+ description: `Selects a source file. Use this when asked about files on the page.`,
185
202
  parameters: {
186
203
  type: Host.AidaClient.ParametersTypes.OBJECT,
187
204
  description: '',
@@ -190,14 +207,14 @@ export class ContextSelectionAgent extends AiAgent<never> {
190
207
  properties: {
191
208
  name: {
192
209
  type: Host.AidaClient.ParametersTypes.STRING,
193
- description: 'The name of the file',
210
+ description: 'The name of the file you want to select.',
194
211
  nullable: false,
195
212
  },
196
213
  },
197
214
  },
198
215
  displayInfoFromArgs: args => {
199
216
  return {
200
- title: lockedString('Getting source file'),
217
+ title: lockedString('Getting source file'),
201
218
  action: `selectSourceFile(${args.name})`,
202
219
  };
203
220
  },
@@ -213,6 +230,67 @@ export class ContextSelectionAgent extends AiAgent<never> {
213
230
  return {error: 'Unable to find file.'};
214
231
  },
215
232
  });
233
+
234
+ this.declareFunction('performanceRecordAndReload', {
235
+ description: 'Records a new performance trace, to help debug performance issue.',
236
+ parameters: {
237
+ type: Host.AidaClient.ParametersTypes.OBJECT,
238
+ description: '',
239
+ nullable: true,
240
+ required: [],
241
+ properties: {},
242
+ },
243
+ displayInfoFromArgs: () => {
244
+ return {
245
+ title: 'Recording a performance trace…',
246
+ action: 'performanceRecordAndReload()',
247
+ };
248
+ },
249
+ handler: async () => {
250
+ if (!this.#performanceRecordAndReload) {
251
+ return {
252
+ error: 'Performance recording is not available.',
253
+ };
254
+ }
255
+ const result = await this.#performanceRecordAndReload();
256
+
257
+ return {
258
+ context: AgentFocus.fromParsedTrace(result),
259
+ };
260
+ }
261
+ });
262
+
263
+ this.declareFunction<Record<string, never>>('inspectDom', {
264
+ description:
265
+ `Prompts user to select a DOM element from the page. Use this when you don't know which element is selected.`,
266
+ parameters: {
267
+ type: Host.AidaClient.ParametersTypes.OBJECT,
268
+ description: '',
269
+ nullable: true,
270
+ required: [],
271
+ properties: {},
272
+ },
273
+ displayInfoFromArgs: () => {
274
+ return {
275
+ title: lockedString('Please select an element on the page…'),
276
+ action: 'selectElement()',
277
+ };
278
+ },
279
+ handler: async () => {
280
+ if (!this.#onInspectElement) {
281
+ return {error: 'The inspect element action is not available.'};
282
+ }
283
+ const node = await this.#onInspectElement();
284
+ if (node) {
285
+ return {
286
+ context: node,
287
+ };
288
+ }
289
+ return {
290
+ error: 'Unable to select element.',
291
+ };
292
+ },
293
+ });
216
294
  }
217
295
 
218
296
  #getUISourceCodes = (): Iterable<Workspace.UISourceCode.UISourceCode> => {
@@ -80,10 +80,6 @@ const UIStringsNotTranslate = {
80
80
  * @description Title text for request timing details.
81
81
  */
82
82
  timing: 'Timing',
83
- /**
84
- * @description Prefix text for response status.
85
- */
86
- responseStatus: 'Response Status',
87
83
  /**
88
84
  * @description Title text for request initiator chain.
89
85
  */
@@ -178,8 +174,8 @@ async function createContextDetailsForNetworkAgent(
178
174
 
179
175
  const responseContextDetail: ContextDetail = {
180
176
  title: lockedString(UIStringsNotTranslate.response),
181
- text: lockedString(UIStringsNotTranslate.responseStatus) + ': ' + request.statusCode + ' ' + request.statusText +
182
- `\n\n${formatter.formatResponseHeaders()}` + responseBodyString,
177
+ text: formatter.formatResponseHeaders() + responseBodyString +
178
+ `\n\n${formatter.formatStatus()}${formatter.formatFailureReasons()}`,
183
179
  };
184
180
  const timingContextDetail: ContextDetail = {
185
181
  title: lockedString(UIStringsNotTranslate.timing),
@@ -3,6 +3,7 @@
3
3
  // found in the LICENSE file.
4
4
 
5
5
  import type * as SDK from '../../../core/sdk/sdk.js';
6
+ import type * as Protocol from '../../../generated/protocol.js';
6
7
  import * as Annotations from '../../annotations/annotations.js';
7
8
  import * as Logs from '../../logs/logs.js';
8
9
  import * as NetworkTimeCalculator from '../../network_time_calculator/network_time_calculator.js';
@@ -75,6 +76,51 @@ export class NetworkRequestFormatter {
75
76
  return '<redacted cross-origin initiator URL>';
76
77
  }
77
78
 
79
+ static formatStatus(status: {
80
+ statusCode: number,
81
+ statusText: string,
82
+ failed: boolean,
83
+ canceled: boolean,
84
+ preserved: boolean,
85
+ finished: boolean,
86
+ }): string {
87
+ let responseStatus = '';
88
+ if (status.statusCode) {
89
+ responseStatus = `Response status: ${status.statusCode} ${status.statusText}\n`;
90
+ }
91
+ const flags = [];
92
+ flags.push(status.finished ? 'finished' : 'pending');
93
+ if (status.failed) {
94
+ flags.push('failed');
95
+ }
96
+ if (status.canceled) {
97
+ flags.push('canceled');
98
+ }
99
+ if (status.preserved) {
100
+ flags.push('preserved');
101
+ }
102
+ const requestStatus = flags.length > 0 ? `Network request status: ${flags.join(', ')}\n` : '';
103
+ return `${responseStatus}${requestStatus}`;
104
+ }
105
+
106
+ static formatFailureReasons(reasons: {
107
+ blockedReason?: Protocol.Network.BlockedReason,
108
+ corsErrorStatus?: Protocol.Network.CorsErrorStatus,
109
+ localizedFailDescription?: string|null,
110
+ }): string {
111
+ const lines = [];
112
+ if (reasons.blockedReason) {
113
+ lines.push(`Blocked reason: ${reasons.blockedReason}`);
114
+ }
115
+ if (reasons.corsErrorStatus) {
116
+ lines.push(`CORS error: ${reasons.corsErrorStatus.corsError} ${reasons.corsErrorStatus.failedParameter}`);
117
+ }
118
+ if (reasons.localizedFailDescription) {
119
+ lines.push(`Fail description: ${reasons.localizedFailDescription}`);
120
+ }
121
+ return lines.length > 0 ? `${lines.join('\n')}\n` : '';
122
+ }
123
+
78
124
  constructor(
79
125
  request: SDK.NetworkRequest.NetworkRequest, calculator: NetworkTimeCalculator.NetworkTransferTimeCalculator) {
80
126
  this.#request = request;
@@ -111,13 +157,31 @@ ${this.formatRequestHeaders()}
111
157
 
112
158
  ${this.formatResponseHeaders()}${responseBody}
113
159
 
114
- Response status: ${this.#request.statusCode} ${this.#request.statusText}
115
-
160
+ ${this.formatStatus()}${this.formatFailureReasons()}
116
161
  Request timing:\n${this.formatNetworkRequestTiming()}
117
162
 
118
163
  Request initiator chain:\n${this.formatRequestInitiatorChain()}`;
119
164
  }
120
165
 
166
+ formatStatus(): string {
167
+ return NetworkRequestFormatter.formatStatus({
168
+ statusCode: this.#request.statusCode,
169
+ statusText: this.#request.statusText,
170
+ failed: this.#request.failed,
171
+ canceled: this.#request.canceled,
172
+ preserved: this.#request.preserved,
173
+ finished: this.#request.finished,
174
+ });
175
+ }
176
+
177
+ formatFailureReasons(): string {
178
+ return NetworkRequestFormatter.formatFailureReasons({
179
+ blockedReason: this.#request.blockedReason(),
180
+ corsErrorStatus: this.#request.corsErrorStatus(),
181
+ localizedFailDescription: this.#request.localizedFailDescription,
182
+ });
183
+ }
184
+
121
185
  /**
122
186
  * Note: nothing here should include information from origins other than
123
187
  * the request's origin.
@@ -137,6 +137,32 @@ export class ComputedStyleModel extends Common.ObjectWrapper.ObjectWrapper<Event
137
137
  null as ComputedStyle | null;
138
138
  }
139
139
  }
140
+
141
+ private async fetchMatchedCascade(): Promise<SDK.CSSMatchedStyles.CSSMatchedStyles|null> {
142
+ const node = this.node;
143
+ if (!node || !this.cssModel()) {
144
+ return null;
145
+ }
146
+
147
+ const cssModel = this.cssModel();
148
+ if (!cssModel) {
149
+ return null;
150
+ }
151
+
152
+ const matchedStyles = await cssModel.cachedMatchedCascadeForNode(node);
153
+ if (!matchedStyles) {
154
+ return null;
155
+ }
156
+ return matchedStyles.node() === this.node ? matchedStyles : null;
157
+ }
158
+
159
+ async fetchAllComputedStyleInfo(): Promise<{
160
+ computedStyle: ComputedStyle | null,
161
+ matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles|null,
162
+ }> {
163
+ const [computedStyle, matchedStyles] = await Promise.all([this.fetchComputedStyle(), this.fetchMatchedCascade()]);
164
+ return {computedStyle, matchedStyles};
165
+ }
140
166
  }
141
167
 
142
168
  export const enum Events {
@@ -9,8 +9,6 @@ let instance: Prototypes|null = null;
9
9
 
10
10
  export interface GreenDevSettings {
11
11
  inDevToolsFloaty: Common.Settings.Setting<boolean>;
12
- inlineWidgets: Common.Settings.Setting<boolean>;
13
- artifactViewer: Common.Settings.Setting<boolean>;
14
12
  aiAnnotations: Common.Settings.Setting<boolean>;
15
13
  copyToGemini: Common.Settings.Setting<boolean>;
16
14
  }
@@ -41,21 +39,14 @@ export class Prototypes {
41
39
  const inDevToolsFloaty =
42
40
  settings.createSetting('greendev-in-devtools-floaty-enabled', false, Common.Settings.SettingStorageType.LOCAL);
43
41
 
44
- const inlineWidgets =
45
- settings.createSetting('greendev-inline-widgets-enabled', false, Common.Settings.SettingStorageType.LOCAL);
46
-
47
42
  const aiAnnotations = settings.createSetting(
48
43
  'greendev-ai-annotations-enabled',
49
44
  false,
50
45
  Common.Settings.SettingStorageType.LOCAL,
51
46
  );
52
-
53
- const artifactViewer =
54
- settings.createSetting('greendev-artifact-viewer-enabled', false, Common.Settings.SettingStorageType.LOCAL);
55
-
56
47
  const copyToGemini =
57
48
  settings.createSetting('greendev-copy-to-gemini-enabled', false, Common.Settings.SettingStorageType.LOCAL);
58
49
 
59
- return {inDevToolsFloaty, inlineWidgets, aiAnnotations, artifactViewer, copyToGemini};
50
+ return {inDevToolsFloaty, aiAnnotations, copyToGemini};
60
51
  }
61
52
  }
@@ -0,0 +1,75 @@
1
+ // Copyright 2026 The Chromium Authors
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ import * as i18n from '../../core/i18n/i18n.js';
6
+ import type * as SDK from '../../core/sdk/sdk.js';
7
+ import * as Protocol from '../../generated/protocol.js';
8
+
9
+ import {Issue, IssueCategory, IssueKind} from './Issue.js';
10
+ import {
11
+ type LazyMarkdownIssueDescription,
12
+ type MarkdownIssueDescription,
13
+ resolveLazyDescription,
14
+ } from './MarkdownIssueDescription.js';
15
+
16
+ const UIStrings = {
17
+ /**
18
+ *@description Title for Connection-Allowlist specification url
19
+ */
20
+ connectionAllowlistHeader: 'Connection-Allowlist specification',
21
+ } as const;
22
+ const str_ = i18n.i18n.registerUIStrings('models/issues_manager/ConnectionAllowlistIssue.ts', UIStrings);
23
+ const i18nLazyString = i18n.i18n.getLazilyComputedLocalizedString.bind(undefined, str_);
24
+
25
+ export class ConnectionAllowlistIssue extends Issue<Protocol.Audits.ConnectionAllowlistIssueDetails> {
26
+ constructor(
27
+ issueDetails: Protocol.Audits.ConnectionAllowlistIssueDetails, issuesModel: SDK.IssuesModel.IssuesModel|null) {
28
+ super(
29
+ {
30
+ code: `${Protocol.Audits.InspectorIssueCode.ConnectionAllowlistIssue}::${issueDetails.error}`,
31
+ umaCode: `${Protocol.Audits.InspectorIssueCode.ConnectionAllowlistIssue}::${issueDetails.error}`,
32
+ },
33
+ issueDetails, issuesModel);
34
+ }
35
+
36
+ override primaryKey(): string {
37
+ return JSON.stringify(this.details());
38
+ }
39
+
40
+ override getDescription(): MarkdownIssueDescription|null {
41
+ const description: LazyMarkdownIssueDescription = {
42
+ file: `connectionAllowlist${this.details().error}.md`,
43
+ links: [
44
+ {
45
+ link: 'https://wicg.github.io/private-network-access/#connection-allowlist',
46
+ linkTitle: i18nLazyString(UIStrings.connectionAllowlistHeader),
47
+ },
48
+ ],
49
+ };
50
+ return resolveLazyDescription(description);
51
+ }
52
+
53
+ override getCategory(): IssueCategory {
54
+ return IssueCategory.OTHER;
55
+ }
56
+
57
+ override getKind(): IssueKind {
58
+ return IssueKind.PAGE_ERROR;
59
+ }
60
+
61
+ override requests(): Iterable<Protocol.Audits.AffectedRequest> {
62
+ return this.details().request ? [this.details().request] : [];
63
+ }
64
+
65
+ static fromInspectorIssue(
66
+ issuesModel: SDK.IssuesModel.IssuesModel|null,
67
+ inspectorIssue: Protocol.Audits.InspectorIssue): ConnectionAllowlistIssue[] {
68
+ const details = inspectorIssue.details.connectionAllowlistIssueDetails;
69
+ if (!details) {
70
+ console.warn('Connection-Allowlist issue without details received.');
71
+ return [];
72
+ }
73
+ return [new ConnectionAllowlistIssue(details, issuesModel)];
74
+ }
75
+ }
@@ -8,7 +8,6 @@ import * as i18n from '../../core/i18n/i18n.js';
8
8
  import type * as Platform from '../../core/platform/platform.js';
9
9
  import * as SDK from '../../core/sdk/sdk.js';
10
10
  import * as Protocol from '../../generated/protocol.js';
11
- import * as ThirdPartyWeb from '../../third_party/third-party-web/third-party-web.js';
12
11
 
13
12
  import {Issue, IssueCategory, IssueKind} from './Issue.js';
14
13
  import {
@@ -55,15 +54,6 @@ export const enum CookieStatus {
55
54
  ALLOWED_BY_HEURISTICS = 3,
56
55
  }
57
56
 
58
- export interface CookieReportInfo {
59
- name: string;
60
- domain: string;
61
- type?: string;
62
- platform?: string;
63
- status: CookieStatus;
64
- insight?: Protocol.Audits.CookieIssueInsight;
65
- }
66
-
67
57
  export class CookieIssue extends Issue<Protocol.Audits.CookieIssueDetails> {
68
58
  cookieId(): string {
69
59
  const details = this.details();
@@ -246,24 +236,6 @@ export class CookieIssue extends Issue<Protocol.Audits.CookieIssueDetails> {
246
236
  return IssueKind.BREAKING_CHANGE;
247
237
  }
248
238
 
249
- makeCookieReportEntry(): CookieReportInfo|undefined {
250
- const status = CookieIssue.getCookieStatus(this.details());
251
- const details = this.details();
252
- if (details.cookie && details.cookieUrl && status !== undefined) {
253
- const entity = ThirdPartyWeb.ThirdPartyWeb.getEntity(details.cookieUrl);
254
- return {
255
- name: details.cookie.name,
256
- domain: details.cookie.domain,
257
- type: entity?.category,
258
- platform: entity?.name,
259
- status,
260
- insight: this.details().insight,
261
- };
262
- }
263
-
264
- return;
265
- }
266
-
267
239
  static getCookieStatus(cookieIssueDetails: Protocol.Audits.CookieIssueDetails): CookieStatus|undefined {
268
240
  if (cookieIssueDetails.cookieExclusionReasons.includes(
269
241
  Protocol.Audits.CookieExclusionReason.ExcludeThirdPartyPhaseout)) {
@@ -109,36 +109,6 @@ const issueDescriptions = new Map<Protocol.Audits.FederatedAuthRequestIssueReaso
109
109
  }],
110
110
  },
111
111
  ],
112
- [
113
- Protocol.Audits.FederatedAuthRequestIssueReason.ClientMetadataHttpNotFound,
114
- {
115
- file: 'federatedAuthRequestClientMetadataHttpNotFound.md',
116
- links: [{
117
- link: 'https://fedidcg.github.io/FedCM/',
118
- linkTitle: i18nLazyString(UIStrings.fedCm),
119
- }],
120
- },
121
- ],
122
- [
123
- Protocol.Audits.FederatedAuthRequestIssueReason.ClientMetadataNoResponse,
124
- {
125
- file: 'federatedAuthRequestClientMetadataNoResponse.md',
126
- links: [{
127
- link: 'https://fedidcg.github.io/FedCM/',
128
- linkTitle: i18nLazyString(UIStrings.fedCm),
129
- }],
130
- },
131
- ],
132
- [
133
- Protocol.Audits.FederatedAuthRequestIssueReason.ClientMetadataInvalidResponse,
134
- {
135
- file: 'federatedAuthRequestClientMetadataInvalidResponse.md',
136
- links: [{
137
- link: 'https://fedidcg.github.io/FedCM/',
138
- linkTitle: i18nLazyString(UIStrings.fedCm),
139
- }],
140
- },
141
- ],
142
112
  [
143
113
  Protocol.Audits.FederatedAuthRequestIssueReason.ErrorFetchingSignin,
144
114
  {
@@ -9,6 +9,7 @@ import * as Protocol from '../../generated/protocol.js';
9
9
  import {AttributionReportingIssue} from './AttributionReportingIssue.js';
10
10
  import {BounceTrackingIssue} from './BounceTrackingIssue.js';
11
11
  import {ClientHintIssue} from './ClientHintIssue.js';
12
+ import {ConnectionAllowlistIssue} from './ConnectionAllowlistIssue.js';
12
13
  import {ContentSecurityPolicyIssue} from './ContentSecurityPolicyIssue.js';
13
14
  import {CookieDeprecationMetadataIssue} from './CookieDeprecationMetadataIssue.js';
14
15
  import {CookieIssue} from './CookieIssue.js';
@@ -144,6 +145,10 @@ const issueCodeHandlers = new Map<
144
145
  Protocol.Audits.InspectorIssueCode.UnencodedDigestIssue,
145
146
  UnencodedDigestIssue.fromInspectorIssue,
146
147
  ],
148
+ [
149
+ Protocol.Audits.InspectorIssueCode.ConnectionAllowlistIssue,
150
+ ConnectionAllowlistIssue.fromInspectorIssue,
151
+ ],
147
152
  [
148
153
  Protocol.Audits.InspectorIssueCode.PermissionElementIssue,
149
154
  PermissionElementIssue.fromInspectorIssue,
@@ -0,0 +1,12 @@
1
+ # An item in the `Connection-Allowlist` header is invalid.
2
+
3
+ Each item in the `Connection-Allowlist`'s header's [Inner List](sfInnerList)
4
+ must be a [String](sfString) representing a [URL Pattern](urlPatternSpec), or
5
+ the [Token](sfToken) `response-origin`.
6
+
7
+ For example, the following header allows connections to (only)
8
+ `https://example.com/` and the origin from which the response was delivered:
9
+
10
+ ```
11
+ Connection-Allowlist: ("https://example.com" response-origin)
12
+ ```
@@ -0,0 +1,12 @@
1
+ # The `Connection-Allowlist` header is not formatted as a Structured Field 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,8 @@
1
+ # An item in the `Connection-Allowlist` header is not a valid URL pattern.
2
+
3
+ Each item in the `Connection-Allowlist` header must be a valid
4
+ [URL Pattern](urlPatternSpec) that can be used to match against the request's
5
+ origin.
6
+
7
+ Note that our current implementation does not allow regular expressions to be
8
+ used as part of the pattern.
@@ -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.
@@ -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,