chrome-devtools-frontend 1.0.1556696 → 1.0.1558690

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 (157) hide show
  1. package/front_end/core/common/Object.ts +5 -1
  2. package/front_end/core/host/ResourceLoader.ts +1 -1
  3. package/front_end/core/host/UserMetrics.ts +3 -1
  4. package/front_end/core/sdk/DOMModel.ts +7 -0
  5. package/front_end/core/sdk/NetworkManager.ts +0 -7
  6. package/front_end/core/sdk/SourceMap.ts +16 -2
  7. package/front_end/core/sdk/SourceMapManager.ts +1 -1
  8. package/front_end/core/sdk/SourceMapScopesInfo.ts +11 -4
  9. package/front_end/entrypoints/formatter_worker/FormatterActions.ts +1 -0
  10. package/front_end/entrypoints/formatter_worker/ScopeParser.ts +51 -8
  11. package/front_end/entrypoints/main/GlobalAiButton.ts +5 -1
  12. package/front_end/generated/Deprecation.ts +0 -7
  13. package/front_end/generated/InspectorBackendCommands.ts +3 -3
  14. package/front_end/generated/protocol.ts +9 -0
  15. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt +3 -3
  16. package/front_end/models/bindings/CompilerScriptMapping.ts +7 -6
  17. package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +4 -4
  18. package/front_end/models/javascript_metadata/NativeFunctions.js +2 -2
  19. package/front_end/models/stack_trace/StackTraceImpl.ts +5 -3
  20. package/front_end/models/stack_trace/StackTraceModel.ts +53 -40
  21. package/front_end/models/trace/EventsSerializer.ts +8 -2
  22. package/front_end/models/trace/handlers/LayoutShiftsHandler.ts +2 -2
  23. package/front_end/panels/application/AppManifestView.ts +134 -223
  24. package/front_end/panels/application/CookieItemsView.ts +1 -0
  25. package/front_end/panels/application/SharedStorageTreeElement.ts +3 -0
  26. package/front_end/panels/application/appManifestView.css +1 -1
  27. package/front_end/panels/console/ConsoleViewMessage.ts +4 -3
  28. package/front_end/panels/elements/ElementsTreeElement.ts +30 -1
  29. package/front_end/panels/elements/ElementsTreeOutlineRenderer.ts +7 -1
  30. package/front_end/panels/elements/components/AdornerManager.ts +8 -0
  31. package/front_end/panels/emulation/DeviceModeToolbar.ts +3 -1
  32. package/front_end/panels/issues/AffectedResourcesView.ts +0 -1
  33. package/front_end/panels/lighthouse/LighthousePanel.ts +10 -0
  34. package/front_end/panels/lighthouse/lighthousePanel.css +46 -3
  35. package/front_end/panels/network/NetworkLogViewColumns.ts +9 -9
  36. package/front_end/panels/network/RequestCookiesView.ts +125 -141
  37. package/front_end/panels/network/components/RequestHeadersView.ts +2 -2
  38. package/front_end/panels/network/requestCookiesView.css +22 -20
  39. package/front_end/panels/recorder/components/RecordingView.ts +3 -3
  40. package/front_end/panels/recorder/components/StepView.ts +2 -1
  41. package/front_end/panels/settings/keybindsSettingsTab.css +4 -0
  42. package/front_end/panels/sources/CallStackSidebarPane.ts +7 -3
  43. package/front_end/panels/sources/DebuggerPausedMessage.ts +125 -90
  44. package/front_end/panels/sources/SourcesPanel.ts +10 -7
  45. package/front_end/panels/sources/debuggerPausedMessage.css +8 -0
  46. package/front_end/panels/timeline/components/sidebarInsightsTab.css +2 -0
  47. package/front_end/third_party/acorn/estree-legacy.d.ts +2 -0
  48. package/front_end/third_party/chromium/README.chromium +1 -1
  49. package/front_end/third_party/puppeteer/README.chromium +2 -2
  50. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Browser.d.ts +12 -0
  51. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Browser.d.ts.map +1 -1
  52. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Browser.js.map +1 -1
  53. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts +14 -2
  54. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts.map +1 -1
  55. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.js.map +1 -1
  56. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Browser.d.ts +3 -1
  57. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Browser.d.ts.map +1 -1
  58. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Browser.js +6 -0
  59. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Browser.js.map +1 -1
  60. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/HTTPRequest.d.ts +0 -1
  61. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/HTTPRequest.d.ts.map +1 -1
  62. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/HTTPRequest.js +0 -20
  63. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/HTTPRequest.js.map +1 -1
  64. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.d.ts +3 -1
  65. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.d.ts.map +1 -1
  66. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.js +10 -14
  67. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.js.map +1 -1
  68. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.d.ts +1 -0
  69. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.d.ts.map +1 -1
  70. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.js +14 -0
  71. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.js.map +1 -1
  72. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.d.ts +3 -1
  73. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.d.ts.map +1 -1
  74. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.js +12 -0
  75. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.js.map +1 -1
  76. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/EmulationManager.d.ts +1 -0
  77. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/EmulationManager.d.ts.map +1 -1
  78. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/EmulationManager.js +22 -0
  79. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/EmulationManager.js.map +1 -1
  80. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.d.ts +3 -1
  81. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.d.ts.map +1 -1
  82. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js +9 -2
  83. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js.map +1 -1
  84. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/injected/injected.d.ts +1 -1
  85. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.d.ts +3 -3
  86. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js +3 -3
  87. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js.map +1 -1
  88. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/Mutex.d.ts +2 -2
  89. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.d.ts +1 -1
  90. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.js +1 -1
  91. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.d.ts +26 -0
  92. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +72 -15
  93. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Browser.d.ts +12 -0
  94. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Browser.d.ts.map +1 -1
  95. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Browser.js.map +1 -1
  96. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts +14 -2
  97. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts.map +1 -1
  98. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.js.map +1 -1
  99. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Browser.d.ts +3 -1
  100. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Browser.d.ts.map +1 -1
  101. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Browser.js +6 -0
  102. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Browser.js.map +1 -1
  103. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/HTTPRequest.d.ts +0 -1
  104. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/HTTPRequest.d.ts.map +1 -1
  105. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/HTTPRequest.js +0 -20
  106. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/HTTPRequest.js.map +1 -1
  107. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.d.ts +3 -1
  108. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.d.ts.map +1 -1
  109. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.js +11 -15
  110. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.js.map +1 -1
  111. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.d.ts +1 -0
  112. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.d.ts.map +1 -1
  113. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.js +14 -0
  114. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.js.map +1 -1
  115. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.d.ts +3 -1
  116. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.d.ts.map +1 -1
  117. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.js +12 -0
  118. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.js.map +1 -1
  119. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/EmulationManager.d.ts +1 -0
  120. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/EmulationManager.d.ts.map +1 -1
  121. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/EmulationManager.js +22 -0
  122. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/EmulationManager.js.map +1 -1
  123. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.d.ts +3 -1
  124. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.d.ts.map +1 -1
  125. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js +9 -2
  126. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js.map +1 -1
  127. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.d.ts +3 -3
  128. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js +3 -3
  129. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js.map +1 -1
  130. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.d.ts +1 -1
  131. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.js +1 -1
  132. package/front_end/third_party/puppeteer/package/lib/types.d.ts +26 -0
  133. package/front_end/third_party/puppeteer/package/package.json +1 -1
  134. package/front_end/third_party/puppeteer/package/src/api/Browser.ts +18 -0
  135. package/front_end/third_party/puppeteer/package/src/api/Page.ts +16 -2
  136. package/front_end/third_party/puppeteer/package/src/bidi/Browser.ts +13 -0
  137. package/front_end/third_party/puppeteer/package/src/bidi/HTTPRequest.ts +0 -33
  138. package/front_end/third_party/puppeteer/package/src/bidi/Page.ts +14 -28
  139. package/front_end/third_party/puppeteer/package/src/bidi/core/BrowsingContext.ts +19 -0
  140. package/front_end/third_party/puppeteer/package/src/cdp/Browser.ts +19 -0
  141. package/front_end/third_party/puppeteer/package/src/cdp/EmulationManager.ts +30 -0
  142. package/front_end/third_party/puppeteer/package/src/cdp/Page.ts +15 -6
  143. package/front_end/third_party/puppeteer/package/src/revisions.ts +3 -3
  144. package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
  145. package/front_end/ui/components/icon_button/iconButton.css +3 -1
  146. package/front_end/ui/components/report_view/ReportView.ts +11 -2
  147. package/front_end/ui/components/report_view/report.css +16 -0
  148. package/front_end/ui/components/text_editor/AiCodeGenerationProvider.ts +135 -7
  149. package/front_end/ui/components/text_editor/config.ts +6 -6
  150. package/front_end/ui/legacy/ContextMenu.ts +11 -2
  151. package/front_end/ui/legacy/TextPrompt.ts +1 -1
  152. package/front_end/ui/legacy/Toolbar.ts +4 -0
  153. package/front_end/ui/legacy/UIUtils.ts +0 -2
  154. package/front_end/ui/legacy/components/cookie_table/CookiesTable.ts +18 -3
  155. package/front_end/ui/legacy/components/data_grid/DataGrid.ts +3 -3
  156. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +6 -0
  157. package/package.json +1 -1
@@ -8,7 +8,7 @@ import type {Protocol} from 'devtools-protocol';
8
8
 
9
9
  import {firstValueFrom, from, raceWith} from '../../third_party/rxjs/rxjs.js';
10
10
  import type {BluetoothEmulation} from '../api/BluetoothEmulation.js';
11
- import type {Browser} from '../api/Browser.js';
11
+ import type {Browser, WindowId} from '../api/Browser.js';
12
12
  import type {BrowserContext} from '../api/BrowserContext.js';
13
13
  import {CDPSessionEvent, type CDPSession} from '../api/CDPSession.js';
14
14
  import type {DeviceRequestPrompt} from '../api/DeviceRequestPrompt.js';
@@ -375,17 +375,22 @@ export class CdpPage extends Page {
375
375
  contentWidth: number;
376
376
  contentHeight: number;
377
377
  }): Promise<void> {
378
- const {windowId} = await this.#primaryTargetClient.send(
379
- 'Browser.getWindowForTarget',
380
- );
381
-
378
+ const windowId = await this.windowId();
382
379
  await this.#primaryTargetClient.send('Browser.setContentsSize', {
383
- windowId,
380
+ windowId: Number(windowId),
384
381
  width: params.contentWidth,
385
382
  height: params.contentHeight,
386
383
  });
387
384
  }
388
385
 
386
+ override async windowId(): Promise<WindowId> {
387
+ const {windowId} = await this.#primaryTargetClient.send(
388
+ 'Browser.getWindowForTarget',
389
+ );
390
+
391
+ return windowId.toString();
392
+ }
393
+
389
394
  async #onFileChooser(
390
395
  event: Protocol.Page.FileChooserOpenedEvent,
391
396
  ): Promise<void> {
@@ -580,6 +585,10 @@ export class CdpPage extends Page {
580
585
  );
581
586
  }
582
587
 
588
+ override async emulateFocusedPage(enabled: boolean): Promise<void> {
589
+ return await this.#emulationManager.emulateFocus(enabled);
590
+ }
591
+
583
592
  override setDefaultNavigationTimeout(timeout: number): void {
584
593
  this._timeoutSettings.setDefaultNavigationTimeout(timeout);
585
594
  }
@@ -8,7 +8,7 @@
8
8
  * @internal
9
9
  */
10
10
  export const PUPPETEER_REVISIONS = Object.freeze({
11
- chrome: '143.0.7499.40',
12
- 'chrome-headless-shell': '143.0.7499.40',
13
- firefox: 'stable_145.0.2',
11
+ chrome: '143.0.7499.42',
12
+ 'chrome-headless-shell': '143.0.7499.42',
13
+ firefox: 'stable_146.0',
14
14
  });
@@ -6,5 +6,5 @@
6
6
 
7
7
  // If moved update release-please config
8
8
  // x-release-please-start-version
9
- export const packageVersion = '24.32.1';
9
+ export const packageVersion = '24.33.0';
10
10
  // x-release-please-end
@@ -7,6 +7,8 @@
7
7
  :host {
8
8
  white-space: normal;
9
9
  display: inline-block;
10
+ margin-right: var(--sys-size-1);
11
+ margin-left: var(--sys-size-1);
10
12
  }
11
13
 
12
14
  .icon-button {
@@ -33,7 +35,7 @@
33
35
  }
34
36
 
35
37
  .icon-button:focus-visible {
36
- background-color: var(--sys-color-state-hover-on-subtle);
38
+ outline: var(--sys-size-2) solid var(--sys-color-state-focus-ring);
37
39
  }
38
40
 
39
41
  .compact .icon-button-title {
@@ -3,6 +3,8 @@
3
3
  // found in the LICENSE file.
4
4
  /* eslint-disable @devtools/no-lit-render-outside-of-view, @devtools/enforce-custom-element-definitions-location */
5
5
 
6
+ import * as Platform from '../../../core/platform/platform.js';
7
+ import * as Components from '../../legacy/components/utils/utils.js';
6
8
  import {html, nothing, render} from '../../lit/lit.js';
7
9
 
8
10
  import reportStyles from './report.css.js';
@@ -33,13 +35,16 @@ import reportValueStyles from './reportValue.css.js';
33
35
  */
34
36
  export interface ReportData {
35
37
  reportTitle: string;
38
+ reportUrl?: Platform.DevToolsPath.UrlString;
36
39
  }
37
40
  export class Report extends HTMLElement {
38
41
  readonly #shadow = this.attachShadow({mode: 'open'});
39
42
  #reportTitle = '';
43
+ #reportUrl = Platform.DevToolsPath.EmptyUrlString;
40
44
 
41
- set data({reportTitle}: ReportData) {
45
+ set data({reportTitle, reportUrl}: ReportData) {
42
46
  this.#reportTitle = reportTitle;
47
+ this.#reportUrl = reportUrl ?? Platform.DevToolsPath.EmptyUrlString;
43
48
  this.#render();
44
49
  }
45
50
 
@@ -52,7 +57,11 @@ export class Report extends HTMLElement {
52
57
  // clang-format off
53
58
  render(html`
54
59
  <style>${reportStyles}</style>
55
- ${this.#reportTitle ? html`<div class="report-title">${this.#reportTitle}</div>` : nothing}
60
+ ${this.#reportTitle ? html`<div class="report-title">
61
+ ${this.#reportTitle}
62
+ ${this.#reportUrl ? Components.Linkifier.Linkifier.linkifyURL(this.#reportUrl, {
63
+ tabStop: true, jslogContext: 'source-location', className: 'report-url'}) : nothing}
64
+ </div>` : nothing}
56
65
  <div class="content">
57
66
  <slot></slot>
58
67
  </div>
@@ -26,3 +26,19 @@
26
26
  color: var(--sys-color-on-surface);
27
27
  background-color: var(--sys-color-cdt-base-container);
28
28
  }
29
+
30
+ .report-url {
31
+ background: none;
32
+ border-radius: 2px;
33
+ border: none;
34
+ color: var(--text-link);
35
+ cursor: pointer;
36
+ display: block;
37
+ font: var(--sys-typescale-body4-regular);
38
+ height: unset;
39
+ margin: 0;
40
+ outline-offset: 2px;
41
+ outline: none;
42
+ padding: 0 !important; /* stylelint-disable-line declaration-no-important */
43
+ text-decoration: underline;
44
+ }
@@ -12,6 +12,13 @@ import * as UI from '../../../ui/legacy/legacy.js';
12
12
  import * as VisualLogging from '../../visual_logging/visual_logging.js';
13
13
 
14
14
  import {AiCodeCompletionTeaserPlaceholder} from './AiCodeCompletionTeaserPlaceholder.js';
15
+ import {
16
+ acceptAiAutoCompleteSuggestion,
17
+ aiAutoCompleteSuggestion,
18
+ aiAutoCompleteSuggestionState,
19
+ hasActiveAiSuggestion,
20
+ setAiAutoCompleteSuggestion,
21
+ } from './config.js';
15
22
  import type {TextEditor} from './TextEditor.js';
16
23
 
17
24
  export enum AiCodeGenerationTeaserMode {
@@ -28,30 +35,47 @@ const aiCodeGenerationTeaserModeState = CodeMirror.StateField.define<AiCodeGener
28
35
  },
29
36
  });
30
37
 
38
+ export interface AiCodeGenerationConfig {
39
+ generationContext: {
40
+ inferenceLanguage?: Host.AidaClient.AidaInferenceLanguage,
41
+ };
42
+ onSuggestionAccepted: () => void;
43
+ onRequestTriggered: () => void;
44
+ // TODO(b/445394511): Move exposing citations to onSuggestionAccepted
45
+ onResponseReceived: (citations: Host.AidaClient.Citation[]) => void;
46
+ }
47
+
31
48
  export class AiCodeGenerationProvider {
32
49
  #devtoolsLocale: string;
33
50
  #aiCodeCompletionSetting = Common.Settings.Settings.instance().createSetting('ai-code-completion-enabled', false);
34
51
  #generationTeaserCompartment = new CodeMirror.Compartment();
35
52
  #generationTeaser: PanelCommon.AiCodeGenerationTeaser;
36
53
  #editor?: TextEditor;
54
+ #aiCodeGenerationConfig: AiCodeGenerationConfig;
55
+ #aiCodeGeneration?: AiCodeGeneration.AiCodeGeneration.AiCodeGeneration;
37
56
 
57
+ #aidaClient: Host.AidaClient.AidaClient = new Host.AidaClient.AidaClient();
38
58
  #boundOnUpdateAiCodeGenerationState = this.#updateAiCodeGenerationState.bind(this);
59
+ #controller = new AbortController();
39
60
 
40
- private constructor() {
61
+ private constructor(aiCodeGenerationConfig: AiCodeGenerationConfig) {
41
62
  this.#devtoolsLocale = i18n.DevToolsLocale.DevToolsLocale.instance().locale;
42
63
  if (!AiCodeGeneration.AiCodeGeneration.AiCodeGeneration.isAiCodeGenerationEnabled(this.#devtoolsLocale)) {
43
64
  throw new Error('AI code generation feature is not enabled.');
44
65
  }
45
66
  this.#generationTeaser = new PanelCommon.AiCodeGenerationTeaser();
67
+ this.#aiCodeGenerationConfig = aiCodeGenerationConfig;
46
68
  }
47
69
 
48
- static createInstance(): AiCodeGenerationProvider {
49
- return new AiCodeGenerationProvider();
70
+ static createInstance(aiCodeGenerationConfig: AiCodeGenerationConfig): AiCodeGenerationProvider {
71
+ return new AiCodeGenerationProvider(aiCodeGenerationConfig);
50
72
  }
51
73
 
52
74
  extension(): CodeMirror.Extension[] {
53
75
  return [
54
76
  CodeMirror.EditorView.updateListener.of(update => this.activateTeaser(update)),
77
+ aiAutoCompleteSuggestion,
78
+ aiAutoCompleteSuggestionState,
55
79
  aiCodeGenerationTeaserModeState,
56
80
  this.#generationTeaserCompartment.of([]),
57
81
  CodeMirror.Prec.highest(CodeMirror.keymap.of(this.#editorKeymap())),
@@ -59,6 +83,7 @@ export class AiCodeGenerationProvider {
59
83
  }
60
84
 
61
85
  dispose(): void {
86
+ this.#controller.abort();
62
87
  this.#cleanupAiCodeGeneration();
63
88
  }
64
89
 
@@ -71,6 +96,10 @@ export class AiCodeGenerationProvider {
71
96
  }
72
97
 
73
98
  #setupAiCodeGeneration(): void {
99
+ if (this.#aiCodeGeneration) {
100
+ return;
101
+ }
102
+ this.#aiCodeGeneration = new AiCodeGeneration.AiCodeGeneration.AiCodeGeneration({aidaClient: this.#aidaClient});
74
103
  this.#editor?.dispatch({
75
104
  effects:
76
105
  [this.#generationTeaserCompartment.reconfigure([aiCodeGenerationTeaserExtension(this.#generationTeaser)])],
@@ -78,6 +107,10 @@ export class AiCodeGenerationProvider {
78
107
  }
79
108
 
80
109
  #cleanupAiCodeGeneration(): void {
110
+ if (!this.#aiCodeGeneration) {
111
+ return;
112
+ }
113
+ this.#aiCodeGeneration = undefined;
81
114
  this.#editor?.dispatch({
82
115
  effects: [this.#generationTeaserCompartment.reconfigure([])],
83
116
  });
@@ -99,23 +132,51 @@ export class AiCodeGenerationProvider {
99
132
  {
100
133
  key: 'Escape',
101
134
  run: (): boolean => {
102
- if (!this.#editor || !this.#generationTeaser.isShowing() || !this.#generationTeaser.loading) {
135
+ if (!this.#editor || !this.#aiCodeGeneration) {
103
136
  return false;
104
137
  }
105
- this.#editor.dispatch({effects: setAiCodeGenerationTeaserMode.of(AiCodeGenerationTeaserMode.DISMISSED)});
138
+ if (hasActiveAiSuggestion(this.#editor.state)) {
139
+ this.#editor.dispatch({
140
+ effects: setAiAutoCompleteSuggestion.of(null),
141
+ });
142
+ return true;
143
+ }
144
+ if (this.#generationTeaser.isShowing() && this.#generationTeaser.loading) {
145
+ this.#controller.abort();
146
+ this.#controller = new AbortController();
147
+ this.#dismissTeaser();
148
+ return true;
149
+ }
150
+ return false;
151
+ },
152
+ },
153
+ {
154
+ key: 'Tab',
155
+ run: (): boolean => {
156
+ if (!this.#aiCodeGeneration || !this.#editor || !hasActiveAiSuggestion(this.#editor.state)) {
157
+ return false;
158
+ }
159
+ const {accepted, suggestion} = acceptAiAutoCompleteSuggestion(this.#editor.editor);
160
+ if (!accepted) {
161
+ return false;
162
+ }
163
+ if (suggestion?.rpcGlobalId) {
164
+ this.#aiCodeGeneration.registerUserAcceptance(suggestion.rpcGlobalId, suggestion.sampleId);
165
+ }
166
+ this.#aiCodeGenerationConfig?.onSuggestionAccepted();
106
167
  return true;
107
168
  },
108
169
  },
109
170
  {
110
171
  any: (_view: unknown, event: KeyboardEvent) => {
111
- if (!this.#editor || !this.#generationTeaser.isShowing()) {
172
+ if (!this.#editor || !this.#aiCodeGeneration || !this.#generationTeaser.isShowing()) {
112
173
  return false;
113
174
  }
114
175
  if (UI.KeyboardShortcut.KeyboardShortcut.eventHasCtrlEquivalentKey(event)) {
115
176
  if (event.key === 'i') {
116
177
  event.consume(true);
117
178
  void VisualLogging.logKeyDown(event.currentTarget, event, 'ai-code-generation.triggered');
118
- this.#generationTeaser.loading = true;
179
+ void this.#triggerAiCodeGeneration({signal: this.#controller.signal});
119
180
  return true;
120
181
  }
121
182
  }
@@ -125,6 +186,11 @@ export class AiCodeGenerationProvider {
125
186
  ];
126
187
  }
127
188
 
189
+ #dismissTeaser(): void {
190
+ this.#generationTeaser.loading = false;
191
+ this.#editor?.dispatch({effects: setAiCodeGenerationTeaserMode.of(AiCodeGenerationTeaserMode.DISMISSED)});
192
+ }
193
+
128
194
  async activateTeaser(update: CodeMirror.ViewUpdate): Promise<void> {
129
195
  const currentTeaserMode = update.state.field(aiCodeGenerationTeaserModeState);
130
196
  if (currentTeaserMode === AiCodeGenerationTeaserMode.ACTIVE) {
@@ -135,6 +201,68 @@ export class AiCodeGenerationProvider {
135
201
  }
136
202
  update.view.dispatch({effects: setAiCodeGenerationTeaserMode.of(AiCodeGenerationTeaserMode.ACTIVE)});
137
203
  }
204
+
205
+ async #triggerAiCodeGeneration(options?: {signal?: AbortSignal}): Promise<void> {
206
+ if (!this.#editor || !this.#aiCodeGeneration) {
207
+ return;
208
+ }
209
+
210
+ this.#generationTeaser.loading = true;
211
+ const cursor = this.#editor.state.selection.main.head;
212
+ // TODO(b/445899453): Detect all types of comments
213
+ const query = this.#editor.state.doc.lineAt(cursor).text;
214
+ if (query.trim().length === 0) {
215
+ return;
216
+ }
217
+
218
+ try {
219
+ const startTime = performance.now();
220
+ this.#aiCodeGenerationConfig?.onRequestTriggered();
221
+ Host.userMetrics.actionTaken(Host.UserMetrics.Action.AiCodeGenerationRequestTriggered);
222
+
223
+ const generationResponse = await this.#aiCodeGeneration.generateCode(
224
+ query, AiCodeGeneration.AiCodeGeneration.basePreamble,
225
+ this.#aiCodeGenerationConfig?.generationContext.inferenceLanguage, options);
226
+
227
+ if (this.#generationTeaser) {
228
+ this.#dismissTeaser();
229
+ }
230
+
231
+ if (!generationResponse || generationResponse.samples.length === 0) {
232
+ this.#aiCodeGenerationConfig?.onResponseReceived([]);
233
+ return;
234
+ }
235
+ const topSample = generationResponse.samples[0];
236
+
237
+ const shouldBlock = topSample.attributionMetadata?.attributionAction === Host.AidaClient.RecitationAction.BLOCK;
238
+ if (shouldBlock) {
239
+ return;
240
+ }
241
+
242
+ this.#editor.dispatch({
243
+ effects: setAiAutoCompleteSuggestion.of({
244
+ text: '\n' + topSample.generationString,
245
+ from: cursor,
246
+ rpcGlobalId: generationResponse.metadata.rpcGlobalId,
247
+ sampleId: topSample.sampleId,
248
+ startTime,
249
+ onImpression: this.#aiCodeGeneration?.registerUserImpression.bind(this.#aiCodeGeneration),
250
+ })
251
+ });
252
+
253
+ AiCodeGeneration.debugLog('Suggestion dispatched to the editor', topSample.generationString);
254
+ const citations = topSample.attributionMetadata?.citations ?? [];
255
+ this.#aiCodeGenerationConfig?.onResponseReceived(citations);
256
+ } catch (e) {
257
+ AiCodeGeneration.debugLog('Error while fetching code generation suggestions from AIDA', e);
258
+ this.#aiCodeGenerationConfig?.onResponseReceived([]);
259
+ Host.userMetrics.actionTaken(Host.UserMetrics.Action.AiCodeGenerationError);
260
+ }
261
+
262
+ if (this.#generationTeaser) {
263
+ this.#dismissTeaser();
264
+ }
265
+ }
138
266
  }
139
267
 
140
268
  // TODO(b/445899453): Handle teaser's discovery mode
@@ -490,7 +490,7 @@ export interface ActiveSuggestion {
490
490
  rpcGlobalId?: Host.AidaClient.RpcGlobalId;
491
491
  startTime: number;
492
492
  onImpression: (rpcGlobalId: Host.AidaClient.RpcGlobalId, latency: number, sampleId?: number) => void;
493
- clearCachedRequest: () => void;
493
+ clearCachedRequest?: () => void;
494
494
  }
495
495
 
496
496
  export const aiAutoCompleteSuggestionState = CM.StateField.define<ActiveSuggestion|null>({
@@ -501,7 +501,7 @@ export const aiAutoCompleteSuggestionState = CM.StateField.define<ActiveSuggesti
501
501
  if (effect.value) {
502
502
  return effect.value;
503
503
  }
504
- value?.clearCachedRequest();
504
+ value?.clearCachedRequest?.();
505
505
  return null;
506
506
  }
507
507
  }
@@ -514,14 +514,14 @@ export const aiAutoCompleteSuggestionState = CM.StateField.define<ActiveSuggesti
514
514
  // between when the request was sent and the response was received.
515
515
  // We check if the position is still valid before trying to map it.
516
516
  if (value.from > tr.state.doc.length) {
517
- value.clearCachedRequest();
517
+ value.clearCachedRequest?.();
518
518
  return null;
519
519
  }
520
520
 
521
521
  // If deletion occurs, set to null. Otherwise, the mapping might fail if
522
522
  // the position is inside the deleted range.
523
523
  if (tr.docChanged && tr.state.doc.length < tr.startState.doc.length) {
524
- value.clearCachedRequest();
524
+ value.clearCachedRequest?.();
525
525
  return null;
526
526
  }
527
527
 
@@ -530,7 +530,7 @@ export const aiAutoCompleteSuggestionState = CM.StateField.define<ActiveSuggesti
530
530
 
531
531
  // If a change happened before the position from which suggestion was generated, set to null.
532
532
  if (tr.docChanged && head < from) {
533
- value.clearCachedRequest();
533
+ value.clearCachedRequest?.();
534
534
  return null;
535
535
  }
536
536
 
@@ -571,7 +571,7 @@ export function acceptAiAutoCompleteSuggestion(view: CM.EditorView):
571
571
  userEvent: 'input.complete',
572
572
  });
573
573
 
574
- suggestion.clearCachedRequest();
574
+ suggestion.clearCachedRequest?.();
575
575
  return {accepted: true, suggestion};
576
576
  }
577
577
 
@@ -787,8 +787,17 @@ export class ContextMenu extends SubMenu {
787
787
 
788
788
  const menuObject = this.buildMenuDescriptors();
789
789
  const ownerDocument = (this.eventTarget as HTMLElement).ownerDocument;
790
- if (this.useSoftMenu || ContextMenu.useSoftMenu ||
791
- Host.InspectorFrontendHost.InspectorFrontendHostInstance.isHostedMode()) {
790
+
791
+ let useSoftMenu = this.useSoftMenu || ContextMenu.useSoftMenu ||
792
+ Host.InspectorFrontendHost.InspectorFrontendHostInstance.isHostedMode();
793
+
794
+ // Allow force opening a Native menu when DevTools is under test.
795
+ // This allows opening DevTools on DevTools
796
+ if (!this.useSoftMenu && ContextMenu.useSoftMenu && this.event.altKey) {
797
+ useSoftMenu = false;
798
+ }
799
+
800
+ if (useSoftMenu) {
792
801
  this.softMenu = new SoftContextMenu(
793
802
  (menuObject as SoftContextMenuDescriptor[]), this.itemSelected.bind(this), this.keepOpen, undefined,
794
803
  this.onSoftMenuClosed, this.loggableParent);
@@ -327,7 +327,7 @@ export class TextPrompt extends Common.ObjectWrapper.ObjectWrapper<EventTypes> i
327
327
  * or the |blurListener| parameter to register a "blur" event listener on the |element|
328
328
  * (since the "blur" event does not bubble.)
329
329
  */
330
- attachAndStartEditing(element: Element, blurListener: (arg0: Event) => void): Element {
330
+ attachAndStartEditing(element: Element, blurListener?: (arg0: Event) => void): Element {
331
331
  const proxyElement = this.#attach(element);
332
332
  this.startEditing(blurListener);
333
333
  return proxyElement;
@@ -1166,6 +1166,10 @@ export class ToolbarComboBox extends ToolbarItem<void, HTMLSelectElement> {
1166
1166
  }
1167
1167
  }
1168
1168
 
1169
+ turnShrinkable(): void {
1170
+ this.element.classList.add('toolbar-has-dropdown-shrinkable');
1171
+ }
1172
+
1169
1173
  size(): number {
1170
1174
  return this.element.childElementCount;
1171
1175
  }
@@ -1295,8 +1295,6 @@ export class DevToolsIconLabel extends HTMLElement {
1295
1295
 
1296
1296
  set data(data: IconData) {
1297
1297
  this.#icon.data = data;
1298
- // TODO(crbug.com/1427397): Clean this up. This was necessary so `DevToolsIconLabel` can use Lit icon
1299
- // while being backwards-compatible with the legacy Icon while working for both small and large icons.
1300
1298
  if (data.height === '14px') {
1301
1299
  this.#icon.style.setProperty('margin-bottom', '-2px');
1302
1300
  } else if (data.height === '20px') {
@@ -176,6 +176,12 @@ const i18nLazyString = i18n.i18n.getLazilyComputedLocalizedString.bind(undefined
176
176
 
177
177
  const expiresSessionValue = i18nLazyString(UIStrings.session);
178
178
 
179
+ export interface CookiesTableData {
180
+ cookies: SDK.Cookie.Cookie[];
181
+ cookieToBlockedReasons?: ReadonlyMap<SDK.Cookie.Cookie, SDK.CookieModel.BlockedReason[]>;
182
+ cookieToExemptionReason?: ReadonlyMap<SDK.Cookie.Cookie, SDK.CookieModel.ExemptionReason>;
183
+ }
184
+
179
185
  export class CookiesTable extends UI.Widget.VBox {
180
186
  private saveCallback?: ((arg0: SDK.Cookie.Cookie, arg1: SDK.Cookie.Cookie|null) => Promise<boolean>);
181
187
  private readonly refreshCallback?: (() => void);
@@ -190,15 +196,15 @@ export class CookiesTable extends UI.Widget.VBox {
190
196
  private readonly view: ViewFunction;
191
197
  private selectedKey?: string;
192
198
  private readonly editable: boolean;
193
- private readonly renderInline: boolean;
199
+ private renderInline: boolean;
194
200
  private readonly schemeBindingEnabled: boolean;
195
201
  private readonly portBindingEnabled: boolean;
196
202
  constructor(
197
- renderInline?: boolean,
203
+ element?: HTMLElement, renderInline?: boolean,
198
204
  saveCallback?: ((arg0: SDK.Cookie.Cookie, arg1: SDK.Cookie.Cookie|null) => Promise<boolean>),
199
205
  refreshCallback?: (() => void), selectedCallback?: (() => void),
200
206
  deleteCallback?: ((arg0: SDK.Cookie.Cookie, arg1: () => void) => void), view?: ViewFunction) {
201
- super();
207
+ super(element);
202
208
  if (!view) {
203
209
  view = (input, _, target) => {
204
210
  // clang-format off
@@ -325,6 +331,15 @@ export class CookiesTable extends UI.Widget.VBox {
325
331
  this.requestUpdate();
326
332
  }
327
333
 
334
+ set cookiesData(data: CookiesTableData) {
335
+ this.setCookies(data.cookies, data.cookieToBlockedReasons, data.cookieToExemptionReason);
336
+ }
337
+
338
+ set inline(value: boolean) {
339
+ this.renderInline = value;
340
+ this.requestUpdate();
341
+ }
342
+
328
343
  setCookies(
329
344
  cookies: SDK.Cookie.Cookie[],
330
345
  cookieToBlockedReasons?: ReadonlyMap<SDK.Cookie.Cookie, SDK.CookieModel.BlockedReason[]>,
@@ -68,15 +68,15 @@ const UIStrings = {
68
68
  /**
69
69
  * @description A context menu item in the Data Grid of a data grid
70
70
  */
71
- sortByString: 'Sort By',
71
+ sortByString: 'Sort by',
72
72
  /**
73
73
  * @description A context menu item in data grids to reset the columns to their default weight
74
74
  */
75
- resetColumns: 'Reset Columns',
75
+ resetColumns: 'Reset columns',
76
76
  /**
77
77
  * @description A context menu item in data grids to list header options.
78
78
  */
79
- headerOptions: 'Header Options',
79
+ headerOptions: 'Header options',
80
80
  /**
81
81
  * @description Text to refresh the page
82
82
  */
@@ -1697,6 +1697,12 @@ export class Renderer implements UI.UIUtils.Renderer {
1697
1697
  if (options?.expand) {
1698
1698
  section.firstChild()?.expand();
1699
1699
  }
1700
+ const dispatchDimensionChange = (): void => {
1701
+ section.element.dispatchEvent(new CustomEvent('dimensionschanged'));
1702
+ };
1703
+ section.addEventListener(UI.TreeOutline.Events.ElementAttached, dispatchDimensionChange);
1704
+ section.addEventListener(UI.TreeOutline.Events.ElementExpanded, dispatchDimensionChange);
1705
+ section.addEventListener(UI.TreeOutline.Events.ElementCollapsed, dispatchDimensionChange);
1700
1706
  return {
1701
1707
  element: section.element,
1702
1708
  forceSelect: section.forceSelect.bind(section),
package/package.json CHANGED
@@ -104,5 +104,5 @@
104
104
  "flat-cache": "6.1.12"
105
105
  }
106
106
  },
107
- "version": "1.0.1556696"
107
+ "version": "1.0.1558690"
108
108
  }