chrome-devtools-frontend 1.0.1534717 → 1.0.1535712

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 (26) hide show
  1. package/docs/contributing/issues.md +15 -37
  2. package/eslint.config.mjs +1 -0
  3. package/front_end/core/host/InspectorFrontendHost.ts +6 -0
  4. package/front_end/core/host/UserMetrics.ts +5 -1
  5. package/front_end/core/protocol_client/CDPConnection.ts +53 -5
  6. package/front_end/core/protocol_client/protocol_client.ts +2 -0
  7. package/front_end/devtools_compatibility.js +32 -24
  8. package/front_end/generated/SupportedCSSProperties.js +38 -0
  9. package/front_end/panels/ai_assistance/PatchWidget.ts +39 -40
  10. package/front_end/panels/ai_assistance/components/ExploreWidget.ts +0 -2
  11. package/front_end/panels/autofill/AutofillView.ts +2 -3
  12. package/front_end/panels/changes/CombinedDiffView.ts +13 -14
  13. package/front_end/panels/console/ConsoleInsightTeaser.ts +6 -1
  14. package/front_end/panels/console/ConsoleView.ts +1 -0
  15. package/front_end/panels/console/consoleView.css +0 -1
  16. package/front_end/panels/elements/ElementsTreeOutline.ts +1 -1
  17. package/front_end/panels/network/components/DirectSocketConnectionView.ts +4 -6
  18. package/front_end/panels/security/CookieControlsView.ts +72 -66
  19. package/front_end/panels/security/CookieReportView.ts +15 -14
  20. package/front_end/panels/security/IPProtectionView.ts +1 -2
  21. package/front_end/panels/security/SecurityPanel.ts +19 -19
  22. package/front_end/panels/timeline/TimelineSelectorStatsView.ts +36 -36
  23. package/front_end/panels/timeline/components/SidebarAnnotationsTab.ts +1 -2
  24. package/front_end/third_party/chromium/README.chromium +1 -1
  25. package/front_end/ui/visual_logging/KnownContextValues.ts +2 -0
  26. package/package.json +1 -1
@@ -61,53 +61,29 @@ Tracker]. This section provides an overview of the Chromium DevTools specifics.
61
61
  ### Issue types
62
62
 
63
63
  [crbug] supports a wide range of different issue types, with ambiguous semantics.
64
- For Chromium DevTools we explicitly limit the set of types we use and give them
65
- well-defined semantics:
64
+ For the Chromium DevTools component tree ([Chromium>Platform>DevTools]) we
65
+ explicitly limit the set of types we use and give them well-defined semantics:
66
66
 
67
67
  | Issue Type | Meaning |
68
68
  | -------------------- | ------------------------------------------ |
69
69
  | **Bug** | The behavior does not match what is supposed to occur or what is documented. The product does not work as expected. |
70
70
  | **Feature Request** | The product works as intended but could be improved. |
71
71
  | **Internal Cleanup** | This is typically a maintenance issue. The issue has no effect on the behavior of a product, but addressing it may allow more intuitive interaction. |
72
- | **Vulnerability** | Security vulnerabilities subject to the handling outlined in Google's [Vulnerability Priority Guidelines](http://go/vulnerability-slo). |
73
72
  | **Privacy Issue** | Privacy issues subject to the handling outlined in Google's [Privacy Issue Bugs](http://go/pib-slo). |
74
73
  | **Task** | A small unit of work. |
75
- | **Project** | A goal-driven effort with a finite start and end, focused on creating a unique product, service, or result. |
76
- | **Feature** | A collection of work that provides a specific value to the user. |
77
-
78
- The first 6 (**Bug** to **Task**) are used for day-to-day work and for issues
79
- reported by users. The last 2 (**Project** and **Feature**) are used to organize
80
- the other types of issues for the purpose of planning (ahead). We explicitly
81
- don't use Customer Issue, Process, Milestone, Epic, and Story within Chrome DevTools.
82
-
83
- *** promo
84
- **BEST PRACTICE:** Limit the nesting of **Project** and **Feature** to the bare
85
- minimum needed, and use **Task** for small chunks of work.
86
- ***
87
-
88
- ### Parent-Child Relationships and Blocking
89
-
90
- *** note
91
- **TL;DR:**
92
-
93
- - Prefer parent-child relationships to split work into smaller chunks.
94
- - Prefer blocking to express dependencies between independent / adjacent
95
- issues.
96
- ***
74
+ | **Vulnerability** | Security vulnerabilities subject to the handling outlined in Google's [Vulnerability Priority Guidelines](http://go/vulnerability-slo). |
97
75
 
98
- When splitting up work into smaller chunks or when scoping a project that
99
- encompasses multiple bugs or feature requests, favor to express this via a
100
- parent-child relationship. Consider the example of a CSS Nesting:
76
+ These are used to track day-to-day work, primarily issues reported by users. We
77
+ explicitly don't use the Customer Issue, Process, and Story types, because the
78
+ former is already sufficiently covered with **Bug**, **Privacy Issue** and
79
+ **Vulnerability**, while the latter two are basically just special sub types of
80
+ **Task** and this fine-grained distinction would add more confusion than good.
81
+ Any use of the disallowed issue types will be corrected automatically by the
82
+ [Blunderbuss](http://go/blunderbuss) bot.
101
83
 
102
- 1. This should start with an issue of type Feature which is about adding CSS
103
- Nesting support to Chromium DevTools.
104
- 1. This Feature has child issues of type Task, which are concerned with adding
105
- CSS Nesting support to the various parts of DevTools involved, for example
106
- the CDP (Chrome DevTools Protocol), the Elements panel, the Sources panel,
107
- and so forth.
108
- 1. Over the course of the project there'll likely also be Feature Requests and
109
- Bugs from internal and external developers, which should also be parented
110
- under the CSS Nesting Feature issue.
84
+ We also explicitly disallow goal-type issues in the [Chromium>Platform>DevTools]
85
+ component tree. Check out [go/chrome-tooling/project-management] for guidance
86
+ how to manage goals using **Feature** and **Project** (_Googlers-only_).
111
87
 
112
88
  ### Priorities
113
89
 
@@ -265,6 +241,8 @@ refreshed every 2-4 hours, to see SLO compliance for a given lead.
265
241
  [Chrome SLO Policy]: https://b.corp.google.com/slos/1834
266
242
  [go/chrome-slo]: http://go/chrome-slo
267
243
  [go/chrome-release-slos]: http://go/chrome-release-slos
244
+ [go/chrome-tooling/project-management]: http://go/chrome-tooling/project-management
268
245
  [Buganizer SLO Compliance]: go/b-slo-compliance
269
246
  [TaskFlow]: http://go/chrome-devtools:taskflow
270
247
  [TaskFlow Inbox]: http://go/chrome-devtools:taskflow/inbox
248
+ [Chromium>Platform>DevTools]: https://issues.chromium.org/components/1457055
package/eslint.config.mjs CHANGED
@@ -84,6 +84,7 @@ export default defineConfig([
84
84
 
85
85
  linterOptions: {
86
86
  reportUnusedDisableDirectives: 'error',
87
+ reportUnusedInlineConfigs: 'error',
87
88
  },
88
89
 
89
90
  rules: {
@@ -601,6 +601,12 @@ class InspectorFrontendAPIImpl {
601
601
  }
602
602
  }
603
603
 
604
+ /**
605
+ * Used in `front_end/devtools_compatibility.js` to verify that calls from there
606
+ * are valid.
607
+ */
608
+ export type InspectorFrontendAPIImplMethods = keyof InspectorFrontendAPIImpl;
609
+
604
610
  (function(): void {
605
611
 
606
612
  function initializeInspectorFrontendHost(): void {
@@ -523,7 +523,11 @@ export enum Action {
523
523
  AiCodeCompletionError = 188,
524
524
  AttributeLinkClicked = 189,
525
525
  InsightRequestedViaTeaser = 190,
526
- MAX_VALUE = 191,
526
+ InsightTeaserGenerationStarted = 191,
527
+ InsightTeaserGenerationCompleted = 192,
528
+ InsightTeaserGenerationAborted = 193,
529
+ InsightTeaserGenerationErrored = 194,
530
+ MAX_VALUE = 195,
527
531
  /* eslint-enable @typescript-eslint/naming-convention */
528
532
  }
529
533
 
@@ -4,6 +4,55 @@
4
4
 
5
5
  import type {ProtocolMapping} from '../../generated/protocol-mapping.js';
6
6
 
7
+ export type CommandParams<T extends keyof ProtocolMapping.Commands> = ProtocolMapping.Commands[T]['paramsType'][0];
8
+ export type CommandResult<T extends keyof ProtocolMapping.Commands> = ProtocolMapping.Commands[T]['returnType'];
9
+ export type EventParams<T extends keyof ProtocolMapping.Events> = ProtocolMapping.Events[T];
10
+
11
+ export interface CDPBaseMessage {
12
+ sessionId?: string;
13
+ }
14
+
15
+ export interface CDPCommandRequest<T extends keyof ProtocolMapping.Commands> extends CDPBaseMessage {
16
+ id: number;
17
+ method: T;
18
+ params: CommandParams<T>;
19
+ }
20
+
21
+ export interface CDPCommandResponse<T extends keyof ProtocolMapping.Commands> extends CDPBaseMessage {
22
+ id: number;
23
+ result: CommandResult<T>;
24
+ }
25
+
26
+ export interface CDPEvent<T extends keyof ProtocolMapping.Events> extends CDPBaseMessage {
27
+ method: T;
28
+ params: EventParams<T>;
29
+ }
30
+
31
+ /**
32
+ * Keep this in sync with https://source.chromium.org/chromium/chromium/src/+/main:third_party/inspector_protocol/crdtp/dispatch.h.
33
+ */
34
+ export const enum CDPErrorStatus {
35
+ PARSE_ERROR = -32700,
36
+ INVALID_REQUEST = -32600,
37
+ METHOD_NOT_FOUND = -32601,
38
+ INVALID_PARAMS = -32602,
39
+ INTERNAL_ERROR = -32603,
40
+ SERVER_ERROR = -32000,
41
+ SESSION_NOT_FOUND = SERVER_ERROR - 1,
42
+ }
43
+
44
+ export interface CDPError extends CDPBaseMessage {
45
+ id?: number;
46
+ error: {
47
+ code: CDPErrorStatus,
48
+ message: string,
49
+ data?: string,
50
+ };
51
+ }
52
+
53
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
54
+ export type CDPMessage = CDPCommandRequest<any>|CDPCommandResponse<any>|CDPEvent<any>|CDPError;
55
+
7
56
  /**
8
57
  * Allows the sending and receiving of CDP commands and the notification of CDP events to observers.
9
58
  *
@@ -12,9 +61,8 @@ import type {ProtocolMapping} from '../../generated/protocol-mapping.js';
12
61
  * would conflict with any other shared traffic.
13
62
  */
14
63
  export interface CDPConnection {
15
- send<T extends keyof ProtocolMapping.Commands>(
16
- method: T, params: ProtocolMapping.Commands[T]['paramsType'][0],
17
- sessionId: string|undefined): Promise<ProtocolMapping.Commands[T]['returnType']|{getError(): string}>;
64
+ send<T extends keyof ProtocolMapping.Commands>(method: T, params: CommandParams<T>, sessionId: string|undefined):
65
+ Promise<CommandResult<T>|{getError(): string}>;
18
66
 
19
67
  observe(observer: CDPConnectionObserver): void;
20
68
  unobserve(observer: CDPConnectionObserver): void;
@@ -34,6 +82,6 @@ export interface DebuggableCDPConnection extends CDPConnection {
34
82
  }
35
83
 
36
84
  export interface RawMessageObserver {
37
- onMessageReceived(message: unknown): void;
38
- onMessageSent(message: unknown): void;
85
+ onMessageReceived(message: CDPMessage): void;
86
+ onMessageSent(message: CDPMessage): void;
39
87
  }
@@ -2,11 +2,13 @@
2
2
  // Use of this source code is governed by a BSD-style license that can be
3
3
  // found in the LICENSE file.
4
4
 
5
+ import * as CDPConnection from './CDPConnection.js';
5
6
  import * as ConnectionTransport from './ConnectionTransport.js';
6
7
  import * as InspectorBackend from './InspectorBackend.js';
7
8
  import * as NodeURL from './NodeURL.js';
8
9
 
9
10
  export {
11
+ CDPConnection,
10
12
  ConnectionTransport,
11
13
  InspectorBackend,
12
14
  NodeURL,
@@ -7,8 +7,13 @@
7
7
  // https://crsrc.org/c/third_party/blink/renderer/controller/dev_tools_frontend_impl.cc;l=107
8
8
  (window => {
9
9
  /**
10
+ * A function that tries to check the remotely connected instance
11
+ * major version. You should check against this to provide
12
+ * forward and backwards compatibility.
13
+ *
10
14
  * @returns {number|null}
11
15
  */
16
+
12
17
  function getRemoteMajorVersion() {
13
18
  try {
14
19
  const remoteVersion = new URLSearchParams(window.location.search).get('remoteVersion');
@@ -97,7 +102,9 @@
97
102
  }
98
103
 
99
104
  /**
100
- * @param method
105
+ * @typedef {import('./core/host/InspectorFrontendHostAPI.js').Events} Events
106
+ * @typedef {import('./core/host/InspectorFrontendHost.js').InspectorFrontendAPIImplMethods} Methods
107
+ * @param {`${Events|Methods}`} method
101
108
  * @param args
102
109
  */
103
110
  _dispatchOnInspectorFrontendAPI(method, args) {
@@ -114,7 +121,7 @@
114
121
  // API methods below this line --------------------------------------------
115
122
 
116
123
  /**
117
- * @param extensions {ExtensionDescriptor[]}
124
+ * @param {ExtensionDescriptor[]} extensions
118
125
  */
119
126
  addExtensions(extensions) {
120
127
  // The addExtensions command is sent as the onload event happens for
@@ -128,7 +135,7 @@
128
135
  }
129
136
 
130
137
  /**
131
- * @param forbiddenOrigins {string[]}
138
+ * @param {string[]} forbiddenOrigins
132
139
  */
133
140
  setOriginsForbiddenForExtensions(forbiddenOrigins) {
134
141
  this._originsForbiddenForExtensions = forbiddenOrigins;
@@ -142,14 +149,14 @@
142
149
  }
143
150
 
144
151
  /**
145
- * @param url {string}
152
+ * @param {string} url
146
153
  */
147
154
  appendedToURL(url) {
148
155
  this._dispatchOnInspectorFrontendAPI('appendedToURL', [url]);
149
156
  }
150
157
 
151
158
  /**
152
- * @param url {string}
159
+ * @param {string} url
153
160
  */
154
161
  canceledSaveURL(url) {
155
162
  this._dispatchOnInspectorFrontendAPI('canceledSaveURL', [url]);
@@ -167,7 +174,7 @@
167
174
  }
168
175
 
169
176
  /**
170
- * @param count
177
+ * @param {number} count
171
178
  */
172
179
  deviceCountUpdated(count) {
173
180
  this._dispatchOnInspectorFrontendAPI('deviceCountUpdated', [count]);
@@ -287,7 +294,7 @@
287
294
  }
288
295
 
289
296
  /**
290
- * @param callback {(param: object) => unknown}
297
+ * @param {(param: object) => unknown} callback
291
298
  */
292
299
  setAddExtensionCallback(callback) {
293
300
  this._addExtensionCallback = callback;
@@ -298,7 +305,7 @@
298
305
  }
299
306
 
300
307
  /**
301
- * @param hard {boolean}
308
+ * @param {boolean} hard
302
309
  */
303
310
  reloadInspectedPage(hard) {
304
311
  this._dispatchOnInspectorFrontendAPI('reloadInspectedPage', [hard]);
@@ -335,7 +342,7 @@
335
342
  }
336
343
 
337
344
  /**
338
- * @param tabId {string}
345
+ * @param {string} tabId
339
346
  */
340
347
  setInspectedTabId(tabId) {
341
348
  this._inspectedTabIdValue = tabId;
@@ -344,7 +351,7 @@
344
351
  }
345
352
 
346
353
  /**
347
- * @param targetId {string}
354
+ * @param {string} targetId
348
355
  */
349
356
  setInitialTargetId(targetId) {
350
357
  this._setInitialTargetId(targetId);
@@ -358,30 +365,30 @@
358
365
  }
359
366
 
360
367
  /**
361
- * @param useSoftMenu {boolean}
368
+ * @param {boolean} useSoftMenu
362
369
  */
363
370
  setUseSoftMenu(useSoftMenu) {
364
371
  this._dispatchOnInspectorFrontendAPI('setUseSoftMenu', [useSoftMenu]);
365
372
  }
366
373
 
367
374
  /**
368
- * @param panelName {string}
375
+ * @param {string} panelName
369
376
  */
370
377
  showPanel(panelName) {
371
378
  this._dispatchOnInspectorFrontendAPI('showPanel', [panelName]);
372
379
  }
373
380
 
374
381
  /**
375
- * @param id {number}
376
- * @param chunk {string}
377
- * @param encoded {boolean}
382
+ * @param {number} id
383
+ * @param {string} chunk
384
+ * @param {boolean} encoded
378
385
  */
379
386
  streamWrite(id, chunk, encoded) {
380
387
  this._dispatchOnInspectorFrontendAPI('streamWrite', [id, encoded ? this._decodeBase64(chunk) : chunk]);
381
388
  }
382
389
 
383
390
  /**
384
- * @param chunk {string}
391
+ * @param {string} chunk
385
392
  * @returns {string}
386
393
  */
387
394
  _decodeBase64(chunk) {
@@ -516,7 +523,7 @@
516
523
 
517
524
  /**
518
525
  * @param trigger
519
- * @param callback {(param: object) => unknown}
526
+ * @param {(param: object) => unknown} callback
520
527
  */
521
528
  showSurvey(trigger, callback) {
522
529
  DevToolsAPI.sendMessageToEmbedder('showSurvey', [trigger], callback);
@@ -524,7 +531,7 @@
524
531
 
525
532
  /**
526
533
  * @param trigger
527
- * @param callback {(param: object) => unknown}
534
+ * @param {(param: object) => unknown} callback
528
535
  */
529
536
  canShowSurvey(trigger, callback) {
530
537
  DevToolsAPI.sendMessageToEmbedder('canShowSurvey', [trigger], callback);
@@ -546,7 +553,7 @@
546
553
  * @param url
547
554
  * @param headers
548
555
  * @param streamId
549
- * @param callback {(param: object) => unknown}
556
+ * @param {(param: object) => unknown} callback
550
557
  */
551
558
  loadNetworkResource(url, headers, streamId, callback) {
552
559
  DevToolsAPI.sendMessageToEmbedder('loadNetworkResource', [url, headers, streamId], callback);
@@ -561,7 +568,7 @@
561
568
  }
562
569
 
563
570
  /**
564
- * @param callback {(param: object) => unknown}
571
+ * @param {(param: object) => unknown} callback
565
572
  */
566
573
  getPreferences(callback) {
567
574
  DevToolsAPI.sendMessageToEmbedder('getPreferences', [], callback);
@@ -569,7 +576,7 @@
569
576
 
570
577
  /**
571
578
  * @param name
572
- * @param callback {(param: object) => unknown}
579
+ * @param {(param: object) => unknown} callback
573
580
  */
574
581
  getPreference(name, callback) {
575
582
  DevToolsAPI.sendMessageToEmbedder('getPreference', [name], callback);
@@ -709,9 +716,10 @@
709
716
  }
710
717
 
711
718
  /**
712
- * @param url
719
+ * @param {string} _url
713
720
  */
714
- close(url) {
721
+ close(_url) {
722
+ // This is required when InspectorFrontendHostStub is used
715
723
  }
716
724
 
717
725
  /**
@@ -1136,7 +1144,7 @@
1136
1144
  ]);
1137
1145
 
1138
1146
  /**
1139
- * @param keyCode {number}
1147
+ * @param {number} keyCode
1140
1148
  * @returns
1141
1149
  */
1142
1150
  function keyCodeToKeyIdentifier(keyCode) {
@@ -421,6 +421,7 @@ export const generatedProperties = [
421
421
  "column-rule-color",
422
422
  "column-rule-outset",
423
423
  "column-rule-style",
424
+ "column-rule-visibility-items",
424
425
  "column-rule-width",
425
426
  "column-span",
426
427
  "column-width",
@@ -720,6 +721,7 @@ export const generatedProperties = [
720
721
  "text-emphasis-style",
721
722
  "text-grow",
722
723
  "text-indent",
724
+ "text-justify",
723
725
  "text-orientation",
724
726
  "text-overflow",
725
727
  "text-rendering",
@@ -1736,6 +1738,16 @@ export const generatedProperties = [
1736
1738
  ],
1737
1739
  "name": "column-rule-style"
1738
1740
  },
1741
+ {
1742
+ "inherited": false,
1743
+ "keywords": [
1744
+ "all",
1745
+ "around",
1746
+ "between",
1747
+ "none"
1748
+ ],
1749
+ "name": "column-rule-visibility-items"
1750
+ },
1739
1751
  {
1740
1752
  "keywords": [
1741
1753
  "thin",
@@ -4321,6 +4333,16 @@ export const generatedProperties = [
4321
4333
  "inherited": true,
4322
4334
  "name": "text-indent"
4323
4335
  },
4336
+ {
4337
+ "inherited": true,
4338
+ "keywords": [
4339
+ "auto",
4340
+ "none",
4341
+ "inter-word",
4342
+ "inter-character"
4343
+ ],
4344
+ "name": "text-justify"
4345
+ },
4324
4346
  {
4325
4347
  "inherited": true,
4326
4348
  "keywords": [
@@ -5364,6 +5386,14 @@ export const generatedPropertyValues = {
5364
5386
  "double"
5365
5387
  ]
5366
5388
  },
5389
+ "column-rule-visibility-items": {
5390
+ "values": [
5391
+ "all",
5392
+ "around",
5393
+ "between",
5394
+ "none"
5395
+ ]
5396
+ },
5367
5397
  "column-rule-width": {
5368
5398
  "values": [
5369
5399
  "thin",
@@ -6773,6 +6803,14 @@ export const generatedPropertyValues = {
6773
6803
  "currentcolor"
6774
6804
  ]
6775
6805
  },
6806
+ "text-justify": {
6807
+ "values": [
6808
+ "auto",
6809
+ "none",
6810
+ "inter-word",
6811
+ "inter-character"
6812
+ ]
6813
+ },
6776
6814
  "text-orientation": {
6777
6815
  "values": [
6778
6816
  "sideways",
@@ -1,7 +1,6 @@
1
1
  // Copyright 2025 The Chromium Authors
2
2
  // Use of this source code is governed by a BSD-style license that can be
3
3
  // found in the LICENSE file.
4
- /* eslint-disable @devtools/no-lit-render-outside-of-view */
5
4
 
6
5
  import '../../ui/legacy/legacy.js';
7
6
  import '../../ui/components/markdown_view/markdown_view.js';
@@ -187,42 +186,8 @@ export interface ViewOutput {
187
186
  }
188
187
 
189
188
  type View = (input: ViewInput, output: ViewOutput, target: HTMLElement) => void;
190
-
191
- export class PatchWidget extends UI.Widget.Widget {
192
- changeSummary = '';
193
- changeManager: AiAssistanceModel.ChangeManager.ChangeManager|undefined;
194
- // Whether the user completed first run experience dialog or not.
195
- #aiPatchingFreCompletedSetting =
196
- Common.Settings.Settings.instance().createSetting('ai-assistance-patching-fre-completed', false);
197
- #projectIdSetting =
198
- Common.Settings.Settings.instance().createSetting('ai-assistance-patching-selected-project-id', '');
199
- #view: View;
200
- #viewOutput: ViewOutput = {};
201
- #aidaClient: Host.AidaClient.AidaClient;
202
- #applyPatchAbortController?: AbortController;
203
- #project?: Workspace.Workspace.Project;
204
- #patchSources?: string;
205
- #savedToDisk?: boolean;
206
- #noLogging: boolean; // Whether the enterprise setting is `ALLOW_WITHOUT_LOGGING` or not.
207
- #patchSuggestionState = PatchSuggestionState.INITIAL;
208
- #workspaceDiff = WorkspaceDiff.WorkspaceDiff.workspaceDiff();
209
- #workspace = Workspace.Workspace.WorkspaceImpl.instance();
210
- #automaticFileSystem =
211
- Persistence.AutomaticFileSystemManager.AutomaticFileSystemManager.instance().automaticFileSystem;
212
- #applyToDisconnectedAutomaticWorkspace = false;
213
- // `rpcId` from the `applyPatch` request
214
- #rpcId: Host.AidaClient.RpcGlobalId|null = null;
215
-
216
- constructor(element?: HTMLElement, view?: View, opts?: {
217
- aidaClient: Host.AidaClient.AidaClient,
218
- }) {
219
- super(element);
220
- this.#aidaClient = opts?.aidaClient ?? new Host.AidaClient.AidaClient();
221
- this.#noLogging = Root.Runtime.hostConfig.aidaAvailability?.enterprisePolicyValue ===
222
- Root.Runtime.GenAiEnterprisePolicyValue.ALLOW_WITHOUT_LOGGING;
223
-
224
- // clang-format off
225
- this.#view = view ?? ((input, output, target) => {
189
+ const DEFAULT_VIEW: View =
190
+ (input, output, target) => {
226
191
  if (!input.changeSummary && input.patchSuggestionState === PatchSuggestionState.INITIAL) {
227
192
  return;
228
193
  }
@@ -428,9 +393,43 @@ export class PatchWidget extends UI.Widget.Widget {
428
393
  </details>
429
394
  `;
430
395
 
431
- render(template, target, {host: target});
432
- });
433
- // clang-format on
396
+ render(template, target);
397
+ };
398
+
399
+ export class PatchWidget extends UI.Widget.Widget {
400
+ changeSummary = '';
401
+ changeManager: AiAssistanceModel.ChangeManager.ChangeManager|undefined;
402
+ // Whether the user completed first run experience dialog or not.
403
+ #aiPatchingFreCompletedSetting =
404
+ Common.Settings.Settings.instance().createSetting('ai-assistance-patching-fre-completed', false);
405
+ #projectIdSetting =
406
+ Common.Settings.Settings.instance().createSetting('ai-assistance-patching-selected-project-id', '');
407
+ #view: View;
408
+ #viewOutput: ViewOutput = {};
409
+ #aidaClient: Host.AidaClient.AidaClient;
410
+ #applyPatchAbortController?: AbortController;
411
+ #project?: Workspace.Workspace.Project;
412
+ #patchSources?: string;
413
+ #savedToDisk?: boolean;
414
+ #noLogging: boolean; // Whether the enterprise setting is `ALLOW_WITHOUT_LOGGING` or not.
415
+ #patchSuggestionState = PatchSuggestionState.INITIAL;
416
+ #workspaceDiff = WorkspaceDiff.WorkspaceDiff.workspaceDiff();
417
+ #workspace = Workspace.Workspace.WorkspaceImpl.instance();
418
+ #automaticFileSystem =
419
+ Persistence.AutomaticFileSystemManager.AutomaticFileSystemManager.instance().automaticFileSystem;
420
+ #applyToDisconnectedAutomaticWorkspace = false;
421
+ // `rpcId` from the `applyPatch` request
422
+ #rpcId: Host.AidaClient.RpcGlobalId|null = null;
423
+
424
+ constructor(element?: HTMLElement, view = DEFAULT_VIEW, opts?: {
425
+ aidaClient: Host.AidaClient.AidaClient,
426
+ }) {
427
+ super(element);
428
+ this.#aidaClient = opts?.aidaClient ?? new Host.AidaClient.AidaClient();
429
+ this.#noLogging = Root.Runtime.hostConfig.aidaAvailability?.enterprisePolicyValue ===
430
+ Root.Runtime.GenAiEnterprisePolicyValue.ALLOW_WITHOUT_LOGGING;
431
+ this.#view = view;
432
+
434
433
  this.requestUpdate();
435
434
  }
436
435
 
@@ -2,7 +2,6 @@
2
2
  // Copyright 2025 The Chromium Authors
3
3
  // Use of this source code is governed by a BSD-style license that can be
4
4
  // found in the LICENSE file.
5
- /* eslint-disable @devtools/no-lit-render-outside-of-view */
6
5
 
7
6
  import * as i18n from '../../../core/i18n/i18n.js';
8
7
  import * as Root from '../../../core/root/root.js';
@@ -105,7 +104,6 @@ export const DEFAULT_VIEW = (
105
104
  </div>
106
105
  `,
107
106
  target,
108
- { host: target },
109
107
  );
110
108
  // clang-format on
111
109
  };
@@ -1,7 +1,6 @@
1
1
  // Copyright 2023 The Chromium Authors
2
2
  // Use of this source code is governed by a BSD-style license that can be
3
3
  // found in the LICENSE file.
4
- /* eslint-disable @devtools/no-lit-render-outside-of-view */
5
4
 
6
5
  import '../../ui/components/adorners/adorners.js';
7
6
  import '../../ui/legacy/components/data_grid/data_grid.js';
@@ -250,7 +249,7 @@ const DEFAULT_VIEW: View = (input: ViewInput, _output: ViewOutput, target: HTMLE
250
249
  </div>
251
250
  </div>
252
251
  </main>
253
- `, target, {host: this});
252
+ `, target);
254
253
  // clang-format on
255
254
  return;
256
255
  }
@@ -287,7 +286,7 @@ const DEFAULT_VIEW: View = (input: ViewInput, _output: ViewOutput, target: HTMLE
287
286
  ${renderFilledFields()}
288
287
  </div>
289
288
  </main>
290
- `, target, {host: this});
289
+ `, target);
291
290
  // clang-format on
292
291
  };
293
292
 
@@ -1,7 +1,6 @@
1
1
  // Copyright 2025 The Chromium Authors
2
2
  // Use of this source code is governed by a BSD-style license that can be
3
3
  // found in the LICENSE file.
4
- /* eslint-disable @devtools/no-lit-render-outside-of-view */
5
4
 
6
5
  import * as Common from '../../core/common/common.js';
7
6
  import * as i18n from '../../core/i18n/i18n.js';
@@ -101,6 +100,18 @@ function renderSingleDiffView(singleDiffViewInput: SingleDiffViewInput): Lit.Tem
101
100
  // clang-format on
102
101
  }
103
102
 
103
+ const DEFAULT_VIEW: View = (input, output, target) => {
104
+ // clang-format off
105
+ Lit.render(
106
+ html`
107
+ <div class="combined-diff-view">
108
+ ${input.singleDiffViewInputs.map(singleDiffViewInput => renderSingleDiffView(singleDiffViewInput))}
109
+ </div>
110
+ `,
111
+ target);
112
+ // clang-format on
113
+ };
114
+
104
115
  export class CombinedDiffView extends UI.Widget.Widget {
105
116
  /**
106
117
  * Ignores urls that start with any in the list
@@ -113,19 +124,7 @@ export class CombinedDiffView extends UI.Widget.Widget {
113
124
  #copiedFiles: Record<string, boolean> = {};
114
125
  #view: View;
115
126
  #viewOutput: ViewOutput = {};
116
- constructor(element?: HTMLElement, view: View = (input, output, target) => {
117
- output.scrollToSelectedDiff = () => {
118
- target.querySelector('details.selected')?.scrollIntoView();
119
- };
120
-
121
- Lit.render(
122
- html`
123
- <div class="combined-diff-view">
124
- ${input.singleDiffViewInputs.map(singleDiffViewInput => renderSingleDiffView(singleDiffViewInput))}
125
- </div>
126
- `,
127
- target, {host: target});
128
- }) {
127
+ constructor(element?: HTMLElement, view: View = DEFAULT_VIEW) {
129
128
  super(element);
130
129
  this.registerRequiredCSS(combinedDiffViewStyles);
131
130
  this.#view = view;