chrome-devtools-frontend 1.0.1543082 → 1.0.1544076

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 (149) hide show
  1. package/AUTHORS +2 -0
  2. package/front_end/core/common/Gzip.ts +4 -4
  3. package/front_end/core/common/common.ts +0 -2
  4. package/front_end/core/host/AidaClient.ts +10 -7
  5. package/front_end/core/host/DispatchHttpRequestClient.ts +18 -3
  6. package/front_end/core/root/DevToolsContext.ts +60 -0
  7. package/front_end/core/root/Runtime.ts +8 -7
  8. package/front_end/core/root/root.ts +6 -1
  9. package/front_end/core/sdk/CPUThrottlingManager.ts +0 -4
  10. package/front_end/core/sdk/CSSMatchedStyles.ts +7 -9
  11. package/front_end/core/sdk/CSSModel.ts +1 -1
  12. package/front_end/core/sdk/CSSRule.ts +18 -6
  13. package/front_end/core/sdk/ChildTargetManager.ts +2 -2
  14. package/front_end/core/sdk/TargetManager.ts +5 -6
  15. package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshotLoader.ts +2 -0
  16. package/front_end/entrypoints/inspector_main/InspectorMain.ts +1 -13
  17. package/front_end/entrypoints/main/MainImpl.ts +2 -20
  18. package/front_end/foundation/Universe.ts +24 -1
  19. package/front_end/models/ai_assistance/agents/AiAgent.ts +10 -8
  20. package/front_end/models/ai_assistance/agents/PatchAgent.ts +7 -1
  21. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +0 -5
  22. package/front_end/models/ai_assistance/agents/StylingAgent.ts +4 -8
  23. package/front_end/models/ai_code_completion/AiCodeCompletion.ts +1 -1
  24. package/front_end/models/ai_code_generation/AiCodeGeneration.ts +5 -3
  25. package/front_end/models/bindings/CSSWorkspaceBinding.ts +8 -7
  26. package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +19 -15
  27. package/front_end/models/bindings/ResourceMapping.ts +57 -15
  28. package/front_end/models/live-metrics/LiveMetrics.ts +12 -20
  29. package/front_end/models/trace/handlers/SamplesHandler.ts +64 -6
  30. package/front_end/models/trace/types/TraceEvents.ts +16 -0
  31. package/front_end/models/workspace/IgnoreListManager.ts +10 -9
  32. package/front_end/models/workspace/WorkspaceImpl.ts +5 -10
  33. package/front_end/panels/accessibility/AccessibilityNodeView.ts +6 -2
  34. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +1 -1
  35. package/front_end/panels/ai_assistance/components/ChatView.ts +2 -4
  36. package/front_end/panels/ai_assistance/components/PerformanceAgentMarkdownRenderer.ts +2 -1
  37. package/front_end/panels/animation/AnimationTimeline.ts +6 -6
  38. package/front_end/panels/application/ApplicationPanelSidebar.ts +0 -1
  39. package/front_end/panels/application/OpenedWindowDetailsView.ts +0 -2
  40. package/front_end/panels/application/ServiceWorkersView.ts +0 -2
  41. package/front_end/panels/application/StorageView.ts +0 -1
  42. package/front_end/panels/application/components/FrameDetailsView.ts +468 -447
  43. package/front_end/panels/application/components/ReportsGrid.ts +7 -2
  44. package/front_end/panels/application/components/SharedStorageAccessGrid.ts +5 -3
  45. package/front_end/panels/application/components/TrustTokensView.ts +7 -1
  46. package/front_end/panels/application/preloading/PreloadingView.ts +10 -4
  47. package/front_end/panels/application/preloading/components/PreloadingDisabledInfobar.ts +7 -11
  48. package/front_end/panels/application/preloading/components/UsedPreloadingView.ts +15 -3
  49. package/front_end/panels/browser_debugger/DOMBreakpointsSidebarPane.ts +12 -13
  50. package/front_end/panels/{elements → common}/DOMLinkifier.ts +6 -6
  51. package/front_end/panels/common/common.ts +1 -0
  52. package/front_end/panels/console/ConsoleView.ts +9 -7
  53. package/front_end/panels/console/ConsoleViewMessage.ts +23 -13
  54. package/front_end/panels/css_overview/CSSOverviewCompletedView.ts +2 -1
  55. package/front_end/panels/elements/ElementsTreeElement.ts +3 -1
  56. package/front_end/panels/elements/StylePropertiesSection.ts +52 -15
  57. package/front_end/panels/elements/StylePropertyTreeElement.ts +8 -3
  58. package/front_end/panels/elements/StylesSidebarPane.ts +24 -14
  59. package/front_end/panels/elements/elements-meta.ts +11 -2
  60. package/front_end/panels/elements/elements.ts +0 -3
  61. package/front_end/panels/explain/components/ConsoleInsight.ts +333 -318
  62. package/front_end/panels/issues/AffectedResourcesView.ts +2 -1
  63. package/front_end/panels/lighthouse/LighthouseReportRenderer.ts +2 -1
  64. package/front_end/panels/network/NetworkLogView.ts +1 -1
  65. package/front_end/panels/recorder/RecorderController.ts +7 -1
  66. package/front_end/panels/settings/SettingsScreen.ts +3 -6
  67. package/front_end/panels/settings/components/SyncSection.ts +218 -226
  68. package/front_end/panels/settings/components/syncSection.css +81 -80
  69. package/front_end/panels/sources/AiCodeCompletionPlugin.ts +42 -294
  70. package/front_end/panels/sources/DebuggerPausedMessage.ts +3 -3
  71. package/front_end/panels/sources/DebuggerPlugin.ts +3 -1
  72. package/front_end/panels/sources/ResourceOriginPlugin.ts +7 -3
  73. package/front_end/panels/sources/SourcesPanel.ts +5 -1
  74. package/front_end/panels/timeline/TimelinePanel.ts +0 -21
  75. package/front_end/panels/timeline/TimelineUIUtils.ts +3 -2
  76. package/front_end/panels/timeline/components/LiveMetricsView.ts +7 -4
  77. package/front_end/panels/timeline/components/insights/NodeLink.ts +3 -2
  78. package/front_end/third_party/puppeteer/README.chromium +2 -2
  79. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/HTTPRequest.d.ts +1 -0
  80. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/HTTPRequest.d.ts.map +1 -1
  81. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/HTTPRequest.js +4 -1
  82. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/HTTPRequest.js.map +1 -1
  83. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/NetworkEventManager.d.ts +1 -0
  84. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/NetworkEventManager.d.ts.map +1 -1
  85. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/NetworkEventManager.js +8 -0
  86. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/NetworkEventManager.js.map +1 -1
  87. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/NetworkManager.d.ts.map +1 -1
  88. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/NetworkManager.js +22 -0
  89. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/NetworkManager.js.map +1 -1
  90. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/injected/injected.d.ts +1 -1
  91. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.d.ts +3 -3
  92. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js +3 -3
  93. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js.map +1 -1
  94. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/Mutex.d.ts +2 -2
  95. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.d.ts +1 -1
  96. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.js +1 -1
  97. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +34 -6
  98. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/HTTPRequest.d.ts +1 -0
  99. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/HTTPRequest.d.ts.map +1 -1
  100. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/HTTPRequest.js +4 -1
  101. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/HTTPRequest.js.map +1 -1
  102. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/NetworkEventManager.d.ts +1 -0
  103. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/NetworkEventManager.d.ts.map +1 -1
  104. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/NetworkEventManager.js +8 -0
  105. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/NetworkEventManager.js.map +1 -1
  106. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/NetworkManager.d.ts.map +1 -1
  107. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/NetworkManager.js +22 -0
  108. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/NetworkManager.js.map +1 -1
  109. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.d.ts +3 -3
  110. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js +3 -3
  111. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js.map +1 -1
  112. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.d.ts +1 -1
  113. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.js +1 -1
  114. package/front_end/third_party/puppeteer/package/package.json +2 -2
  115. package/front_end/third_party/puppeteer/package/src/cdp/HTTPRequest.ts +5 -1
  116. package/front_end/third_party/puppeteer/package/src/cdp/NetworkEventManager.ts +16 -1
  117. package/front_end/third_party/puppeteer/package/src/cdp/NetworkManager.ts +28 -0
  118. package/front_end/third_party/puppeteer/package/src/revisions.ts +3 -3
  119. package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
  120. package/front_end/ui/components/docs/component_docs.ts +0 -4
  121. package/front_end/ui/components/report_view/ReportView.ts +4 -1
  122. package/front_end/ui/components/text_editor/AiCodeCompletionProvider.ts +8 -5
  123. package/front_end/ui/i18n/i18n.ts +16 -0
  124. package/front_end/ui/legacy/ReportView.ts +0 -5
  125. package/front_end/ui/legacy/TextPrompt.ts +65 -19
  126. package/front_end/ui/legacy/UIUtils.ts +1 -1
  127. package/front_end/ui/legacy/Widget.ts +56 -25
  128. package/front_end/ui/legacy/XLink.ts +0 -2
  129. package/front_end/ui/legacy/components/object_ui/JavaScriptREPL.ts +8 -4
  130. package/front_end/ui/legacy/components/object_ui/ObjectPopoverHelper.ts +3 -1
  131. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +239 -284
  132. package/front_end/ui/legacy/components/object_ui/RemoteObjectPreviewFormatter.ts +114 -184
  133. package/front_end/ui/legacy/components/utils/Linkifier.ts +1 -1
  134. package/front_end/ui/legacy/inspectorCommon.css +0 -4
  135. package/front_end/ui/{components/docs/theme_colors/basic.ts → legacy/theme_support/ThemeColors.docs.ts} +33 -23
  136. package/mcp/mcp.ts +1 -0
  137. package/package.json +1 -1
  138. package/front_end/core/common/QueryParamHandler.ts +0 -7
  139. package/front_end/ui/components/docs/input/basic.html +0 -31
  140. package/front_end/ui/components/docs/input/basic.ts +0 -12
  141. package/front_end/ui/components/docs/report/basic.html +0 -27
  142. package/front_end/ui/components/docs/report/basic.ts +0 -48
  143. package/front_end/ui/components/docs/theme_colors/basic.html +0 -56
  144. package/front_end/ui/components/docs/toggle_dark_mode.ts +0 -36
  145. package/front_end/ui/components/docs/toggle_fonts.ts +0 -74
  146. package/front_end/ui/components/docs/user_agent_client_hints/basic.html +0 -25
  147. package/front_end/ui/components/docs/user_agent_client_hints/basic.ts +0 -26
  148. package/front_end/ui/components/expandable_list/ExpandableList.docs.ts +0 -30
  149. /package/front_end/panels/{elements → common}/domLinkifier.css +0 -0
@@ -4,63 +4,65 @@
4
4
  * found in the LICENSE file.
5
5
  */
6
6
 
7
- :host {
8
- break-inside: avoid;
9
- display: block;
10
- width: 100%;
11
- position: relative;
12
- }
7
+ @scope to (devtools-widget > *) {
8
+ :scope {
9
+ break-inside: avoid;
10
+ display: block;
11
+ width: 100%;
12
+ position: relative;
13
+ }
13
14
 
14
- fieldset {
15
- border: 0;
16
- padding: 0;
17
- padding: 4px 0 0;
18
- }
15
+ fieldset {
16
+ border: 0;
17
+ padding: 0;
18
+ padding: 4px 0 0;
19
+ }
19
20
 
20
- .link {
21
- color: var(--sys-color-primary);
22
- text-decoration: underline;
23
- cursor: pointer;
24
- outline-offset: 2px;
25
- }
21
+ .link {
22
+ color: var(--sys-color-primary);
23
+ text-decoration: underline;
24
+ cursor: pointer;
25
+ outline-offset: 2px;
26
+ }
26
27
 
27
- .account-avatar {
28
- border: 0;
29
- border-radius: var(--sys-shape-corner-full);
30
- display: block;
31
- height: var(--sys-size-9);
32
- width: var(--sys-size-9);
33
- }
28
+ .account-avatar {
29
+ border: 0;
30
+ border-radius: var(--sys-shape-corner-full);
31
+ display: block;
32
+ height: var(--sys-size-9);
33
+ width: var(--sys-size-9);
34
+ }
34
35
 
35
- .account-info {
36
- display: flex;
37
- align-items: center;
38
- }
36
+ .account-info {
37
+ display: flex;
38
+ align-items: center;
39
+ }
39
40
 
40
- .account-email {
41
- display: flex;
42
- flex-direction: column;
43
- margin-left: 8px;
44
- }
41
+ .account-email {
42
+ display: flex;
43
+ flex-direction: column;
44
+ margin-left: 8px;
45
+ }
45
46
 
46
- .not-signed-in {
47
- padding-bottom: 4px;
48
- }
47
+ .not-signed-in {
48
+ padding-bottom: 4px;
49
+ }
49
50
 
50
- .setting-checkbox-container {
51
- display: flex;
52
- align-items: center;
53
- gap: var(--sys-size-2);
54
- }
51
+ .setting-checkbox-container {
52
+ display: flex;
53
+ align-items: center;
54
+ gap: var(--sys-size-2);
55
+ }
55
56
 
56
- .setting-checkbox {
57
- display: inline-block;
58
- }
57
+ .setting-checkbox {
58
+ display: inline-block;
59
+ }
59
60
 
60
- .gdp-profile-container {
61
- padding-bottom: var(--sys-size-4);
61
+ .gdp-profile-container {
62
+ padding-bottom: var(--sys-size-4);
63
+ }
62
64
 
63
- & .divider {
65
+ .gdp-profile-container .divider {
64
66
  left: 0;
65
67
  position: absolute;
66
68
  width: 100%;
@@ -68,57 +70,56 @@ fieldset {
68
70
  background: var(--sys-color-divider);
69
71
  }
70
72
 
71
- & .gdp-profile-header {
73
+ .gdp-profile-container .gdp-profile-header {
72
74
  display: flex;
73
75
  align-items: center;
74
76
  gap: var(--sys-size-5);
75
77
  font-family: "Google Sans", system-ui;
76
78
  font-size: var(--sys-typescale-body3-size);
77
79
  height: var(--sys-size-11);
80
+ }
78
81
 
79
- & .gdp-logo {
80
- background-image: var(--image-file-gdp-logo-light);
81
- background-size: contain;
82
- width: 203px;
83
- height: 18px;
84
- background-repeat: no-repeat;
85
- }
82
+ .gdp-profile-container .gdp-profile-header .gdp-logo {
83
+ background-image: var(--image-file-gdp-logo-light);
84
+ background-size: contain;
85
+ width: 203px;
86
+ height: 18px;
87
+ background-repeat: no-repeat;
88
+ }
86
89
 
87
- :host-context(.theme-with-dark-background) & .gdp-logo {
88
- background-image: var(--image-file-gdp-logo-dark);
89
- }
90
+ :host-context(.theme-with-dark-background) & .gdp-profile-container .gdp-profile-header .gdp-logo {
91
+ background-image: var(--image-file-gdp-logo-dark);
90
92
  }
91
93
 
92
- & .gdp-profile-sign-up-content {
94
+ .gdp-profile-container .gdp-profile-sign-up-content {
93
95
  padding-top: var(--sys-size-7);
94
96
  display: flex;
95
97
  justify-content: space-between;
96
98
  align-items: center;
97
99
  }
98
100
 
99
- & .gdp-profile-details-content {
101
+ .gdp-profile-container .gdp-profile-details-content {
100
102
  padding-top: var(--sys-size-7);
101
103
  font: var(--sys-typescale-body4-regular);
104
+ }
105
+
106
+ .gdp-profile-container .gdp-profile-details-content .plan-details {
107
+ margin-top: var(--sys-size-3);
108
+ height: 18px;
109
+ display: flex;
110
+ align-items: center;
111
+ }
112
+
113
+ .gdp-profile-container .gdp-profile-details-content .setting-container {
114
+ margin: calc(var(--sys-size-3) - 6px) 0 -6px;
115
+ display: flex;
116
+ align-items: center;
117
+ gap: var(--sys-size-2);
118
+ }
102
119
 
103
- & .plan-details {
104
- margin-top: var(--sys-size-3);
105
- height: 18px;
106
- display: flex;
107
- align-items: center;
108
- }
109
-
110
- & .setting-container {
111
- /* `<settigns-checkbox>` already provides 6px margin and we want to get rid of it here */
112
- margin: calc(var(--sys-size-3) - 6px) -6px -6px;
113
- display: flex;
114
- align-items: center;
115
- gap: var(--sys-size-2);
116
- }
117
-
118
- & .tooltip-content {
119
- max-width: 278px;
120
- padding: var(--sys-size-2) var(--sys-size-3);
121
- font: var(--sys-typescale-body5-regular);
122
- }
120
+ .gdp-profile-container .gdp-profile-details-content .tooltip-content {
121
+ max-width: 278px;
122
+ padding: var(--sys-size-2) var(--sys-size-3);
123
+ font: var(--sys-typescale-body5-regular);
123
124
  }
124
125
  }
@@ -2,53 +2,23 @@
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 Common from '../../core/common/common.js';
6
5
  import * as Host from '../../core/host/host.js';
7
6
  import * as i18n from '../../core/i18n/i18n.js';
8
- import * as Root from '../../core/root/root.js';
9
7
  import * as AiCodeCompletion from '../../models/ai_code_completion/ai_code_completion.js';
10
8
  import type * as Workspace from '../../models/workspace/workspace.js';
11
- import * as CodeMirror from '../../third_party/codemirror.next/codemirror.next.js';
9
+ import type * as CodeMirror from '../../third_party/codemirror.next/codemirror.next.js';
12
10
  import * as TextEditor from '../../ui/components/text_editor/text_editor.js';
13
11
  import * as SourceFrame from '../../ui/legacy/components/source_frame/source_frame.js';
14
12
  import * as UI from '../../ui/legacy/legacy.js';
15
- import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
16
13
  import * as PanelCommon from '../common/common.js';
17
14
 
18
15
  import {Plugin} from './Plugin.js';
19
16
 
20
- const AI_CODE_COMPLETION_CHARACTER_LIMIT = 20_000;
21
17
  const DISCLAIMER_TOOLTIP_ID = 'sources-ai-code-completion-disclaimer-tooltip';
22
18
  const SPINNER_TOOLTIP_ID = 'sources-ai-code-completion-spinner-tooltip';
23
19
  const CITATIONS_TOOLTIP_ID = 'sources-ai-code-completion-citations-tooltip';
24
20
 
25
- function createCallbacks(editor: TextEditor.TextEditor.TextEditor): AiCodeCompletion.AiCodeCompletion.Callbacks {
26
- return {
27
- getSelectionHead: () => editor.editor.state.selection.main.head,
28
- getCompletionHint: () => editor.editor.plugin(TextEditor.Config.showCompletionHint)?.currentHint,
29
- setAiAutoCompletion: (args: {
30
- text: string,
31
- from: number,
32
- startTime: number,
33
- onImpression: (rpcGlobalId: Host.AidaClient.RpcGlobalId, latency: number, sampleId?: number) => void,
34
- clearCachedRequest: () => void,
35
- rpcGlobalId?: Host.AidaClient.RpcGlobalId,
36
- sampleId?: number,
37
- }|null) => editor.editor.dispatch({effects: TextEditor.Config.setAiAutoCompleteSuggestion.of(args)}),
38
- };
39
- }
40
-
41
21
  export class AiCodeCompletionPlugin extends Plugin {
42
- #aidaClient?: Host.AidaClient.AidaClient;
43
- #aidaAvailability?: Host.AidaClient.AidaAccessPreconditions;
44
- #boundOnAidaAvailabilityChange: () => Promise<void>;
45
- #aiCodeCompletion?: AiCodeCompletion.AiCodeCompletion.AiCodeCompletion;
46
- #aiCodeCompletionSetting = Common.Settings.Settings.instance().createSetting('ai-code-completion-enabled', false);
47
- #aiCodeCompletionTeaserDismissedSetting =
48
- Common.Settings.Settings.instance().createSetting('ai-code-completion-teaser-dismissed', false);
49
- #teaserCompartment = new CodeMirror.Compartment();
50
- #teaser?: PanelCommon.AiCodeCompletionTeaser;
51
- #teaserDisplayTimeout?: number;
52
22
  #editor?: TextEditor.TextEditor.TextEditor;
53
23
  #aiCodeCompletionDisclaimer?: PanelCommon.AiCodeCompletionDisclaimer;
54
24
  #aiCodeCompletionDisclaimerContainer = document.createElement('div');
@@ -57,25 +27,39 @@ export class AiCodeCompletionPlugin extends Plugin {
57
27
  #aiCodeCompletionCitationsToolbar?: PanelCommon.AiCodeCompletionSummaryToolbar;
58
28
  #aiCodeCompletionCitationsToolbarContainer = document.createElement('div');
59
29
  #aiCodeCompletionCitationsToolbarAttached = false;
60
-
61
- #boundEditorKeyDown: (event: KeyboardEvent) => Promise<void>;
62
- #boundOnAiCodeCompletionSettingChanged: () => void;
30
+ aiCodeCompletionConfig: TextEditor.AiCodeCompletionProvider.AiCodeCompletionConfig;
31
+ #aiCodeCompletionProvider: TextEditor.AiCodeCompletionProvider.AiCodeCompletionProvider;
63
32
 
64
33
  constructor(uiSourceCode: Workspace.UISourceCode.UISourceCode) {
65
34
  super(uiSourceCode);
66
- if (!this.#isAiCodeCompletionEnabled()) {
35
+ const devtoolsLocale = i18n.DevToolsLocale.DevToolsLocale.instance();
36
+ if (!AiCodeCompletion.AiCodeCompletion.AiCodeCompletion.isAiCodeCompletionEnabled(devtoolsLocale.locale)) {
67
37
  throw new Error('AI code completion feature is not enabled.');
68
38
  }
69
- this.#boundEditorKeyDown = this.#editorKeyDown.bind(this);
70
- this.#boundOnAiCodeCompletionSettingChanged = this.#onAiCodeCompletionSettingChanged.bind(this);
71
- this.#boundOnAidaAvailabilityChange = this.#onAidaAvailabilityChange.bind(this);
72
- Host.AidaClient.HostConfigTracker.instance().addEventListener(
73
- Host.AidaClient.Events.AIDA_AVAILABILITY_CHANGED, this.#boundOnAidaAvailabilityChange);
74
- const showTeaser = !this.#aiCodeCompletionSetting.get() && !this.#aiCodeCompletionTeaserDismissedSetting.get();
75
- if (showTeaser) {
76
- this.#teaser = new PanelCommon.AiCodeCompletionTeaser({onDetach: this.#detachAiCodeCompletionTeaser.bind(this)});
77
- }
78
39
 
40
+ this.aiCodeCompletionConfig = {
41
+ completionContext: {
42
+ additionalFiles: this.uiSourceCode.url().startsWith('snippet://') ? [{
43
+ path: 'devtools-console-context.js',
44
+ content: AiCodeCompletion.AiCodeCompletion.consoleAdditionalContextFileContent,
45
+ included_reason: Host.AidaClient.Reason.RELATED_FILE,
46
+ }] :
47
+ undefined,
48
+ inferenceLanguage: this.#getInferenceLanguage()
49
+ },
50
+ onFeatureEnabled: () => {
51
+ this.#setupAiCodeCompletion();
52
+ },
53
+ onFeatureDisabled: () => {
54
+ this.#cleanupAiCodeCompletion();
55
+ },
56
+ onSuggestionAccepted: this.#onAiCodeCompletionSuggestionAccepted.bind(this),
57
+ onRequestTriggered: this.#onAiRequestTriggered.bind(this),
58
+ onResponseReceived: this.#onAiResponseReceived.bind(this),
59
+ panel: AiCodeCompletion.AiCodeCompletion.ContextFlavor.SOURCES,
60
+ };
61
+ this.#aiCodeCompletionProvider =
62
+ TextEditor.AiCodeCompletionProvider.AiCodeCompletionProvider.createInstance(this.aiCodeCompletionConfig);
79
63
  this.#aiCodeCompletionDisclaimerContainer.classList.add('ai-code-completion-disclaimer-container');
80
64
  this.#aiCodeCompletionDisclaimerContainer.style.paddingInline = 'var(--sys-size-3)';
81
65
  }
@@ -85,158 +69,28 @@ export class AiCodeCompletionPlugin extends Plugin {
85
69
  }
86
70
 
87
71
  override dispose(): void {
88
- this.#teaser = undefined;
89
- this.#aiCodeCompletionSetting.removeChangeListener(this.#boundOnAiCodeCompletionSettingChanged);
90
- Host.AidaClient.HostConfigTracker.instance().removeEventListener(
91
- Host.AidaClient.Events.AIDA_AVAILABILITY_CHANGED, this.#boundOnAidaAvailabilityChange);
92
- this.#editor?.removeEventListener('keydown', this.#boundEditorKeyDown);
93
- this.#cleanupAiCodeCompletion();
72
+ this.#aiCodeCompletionProvider.dispose();
94
73
  super.dispose();
95
74
  }
96
75
 
97
76
  override editorInitialized(editor: TextEditor.TextEditor.TextEditor): void {
98
77
  this.#editor = editor;
99
- this.#editor.addEventListener('keydown', this.#boundEditorKeyDown);
100
- this.#aiCodeCompletionSetting.addChangeListener(this.#boundOnAiCodeCompletionSettingChanged);
101
- this.#onAiCodeCompletionSettingChanged();
102
- void this.#onAidaAvailabilityChange();
78
+ this.#aiCodeCompletionProvider.editorInitialized(editor);
79
+ this.#editor.editor.dispatch({
80
+ effects: TextEditor.AiCodeCompletionProvider.setAiCodeCompletionTeaserMode.of(
81
+ TextEditor.AiCodeCompletionProvider.AiCodeCompletionTeaserMode.ON)
82
+ });
103
83
  }
104
84
 
105
85
  override editorExtension(): CodeMirror.Extension {
106
- return [
107
- CodeMirror.EditorView.updateListener.of(update => this.#editorUpdate(update)), this.#teaserCompartment.of([]),
108
- TextEditor.Config.aiAutoCompleteSuggestion, CodeMirror.Prec.highest(CodeMirror.keymap.of(this.#editorKeymap()))
109
- ];
86
+ return this.#aiCodeCompletionProvider.extension();
110
87
  }
111
88
 
112
89
  override rightToolbarItems(): UI.Toolbar.ToolbarItem[] {
113
90
  return [this.#aiCodeCompletionDisclaimerToolbarItem];
114
91
  }
115
92
 
116
- #editorUpdate(update: CodeMirror.ViewUpdate): void {
117
- if (this.#teaser) {
118
- if (update.docChanged) {
119
- update.view.dispatch({effects: this.#teaserCompartment.reconfigure([])});
120
- window.clearTimeout(this.#teaserDisplayTimeout);
121
- this.#addTeaserPluginToCompartment(update.view);
122
- } else if (update.selectionSet && update.state.doc.length > 0) {
123
- update.view.dispatch({effects: this.#teaserCompartment.reconfigure([])});
124
- }
125
- } else if (this.#aiCodeCompletion) {
126
- if (update.docChanged && update.state.doc !== update.startState.doc) {
127
- this.#triggerAiCodeCompletion();
128
- }
129
- }
130
- }
131
-
132
- #triggerAiCodeCompletion(): void {
133
- if (!this.#editor || !this.#aiCodeCompletion) {
134
- return;
135
- }
136
- const {doc, selection} = this.#editor.state;
137
- const query = doc.toString();
138
- const cursor = selection.main.head;
139
- let prefix = query.substring(0, cursor);
140
- if (prefix.trim().length === 0) {
141
- return;
142
- }
143
- let suffix = query.substring(cursor);
144
- if (prefix.length > AI_CODE_COMPLETION_CHARACTER_LIMIT) {
145
- prefix = prefix.substring(prefix.length - AI_CODE_COMPLETION_CHARACTER_LIMIT);
146
- }
147
- if (suffix.length > AI_CODE_COMPLETION_CHARACTER_LIMIT) {
148
- suffix = suffix.substring(0, AI_CODE_COMPLETION_CHARACTER_LIMIT);
149
- }
150
- this.#aiCodeCompletion.onTextChanged(prefix, suffix, cursor, this.#getInferenceLanguage());
151
- }
152
-
153
- #editorKeymap(): readonly CodeMirror.KeyBinding[] {
154
- return [
155
- {
156
- key: 'Escape',
157
- run: (): boolean => {
158
- if (this.#aiCodeCompletion && this.#editor && TextEditor.Config.hasActiveAiSuggestion(this.#editor.state)) {
159
- this.#editor.dispatch({
160
- effects: TextEditor.Config.setAiAutoCompleteSuggestion.of(null),
161
- });
162
- return true;
163
- }
164
- return false;
165
- },
166
- },
167
- {
168
- key: 'Tab',
169
- run: (): boolean => {
170
- if (this.#aiCodeCompletion && this.#editor && TextEditor.Config.hasActiveAiSuggestion(this.#editor.state)) {
171
- const {accepted, suggestion} = TextEditor.Config.acceptAiAutoCompleteSuggestion(this.#editor.editor);
172
- if (accepted) {
173
- if (suggestion?.rpcGlobalId) {
174
- this.#aiCodeCompletion?.registerUserAcceptance(suggestion.rpcGlobalId, suggestion.sampleId);
175
- }
176
- this.#onAiCodeCompletionSuggestionAccepted();
177
- }
178
- return accepted;
179
- }
180
- return false;
181
- },
182
- }
183
- ];
184
- }
185
-
186
- async #editorKeyDown(event: KeyboardEvent): Promise<void> {
187
- if (!this.#teaser?.isShowing()) {
188
- return;
189
- }
190
- const keyboardEvent = event;
191
- if (UI.KeyboardShortcut.KeyboardShortcut.eventHasCtrlEquivalentKey(keyboardEvent)) {
192
- if (keyboardEvent.key === 'i') {
193
- keyboardEvent.consume(true);
194
- void VisualLogging.logKeyDown(event.currentTarget, event, 'ai-code-completion-teaser.fre');
195
- await this.#teaser?.onAction(event);
196
- } else if (keyboardEvent.key === 'x') {
197
- keyboardEvent.consume(true);
198
- void VisualLogging.logKeyDown(event.currentTarget, event, 'ai-code-completion-teaser.dismiss');
199
- this.#teaser?.onDismiss(event);
200
- }
201
- }
202
- }
203
-
204
- #addTeaserPluginToCompartment = Common.Debouncer.debounce((view: CodeMirror.EditorView) => {
205
- this.#teaserDisplayTimeout = window.setTimeout(() => {
206
- this.#addTeaserPluginToCompartmentImmediate(view);
207
- }, AiCodeCompletion.AiCodeCompletion.DELAY_BEFORE_SHOWING_RESPONSE_MS);
208
- }, AiCodeCompletion.AiCodeCompletion.AIDA_REQUEST_DEBOUNCE_TIMEOUT_MS);
209
-
210
- #addTeaserPluginToCompartmentImmediate = (view: CodeMirror.EditorView): void => {
211
- if (!this.#teaser) {
212
- return;
213
- }
214
-
215
- view.dispatch({effects: this.#teaserCompartment.reconfigure([aiCodeCompletionTeaserExtension(this.#teaser)])});
216
- };
217
-
218
93
  #setupAiCodeCompletion(): void {
219
- if (!this.#editor) {
220
- return;
221
- }
222
- if (!this.#aidaClient) {
223
- this.#aidaClient = new Host.AidaClient.AidaClient();
224
- }
225
- if (this.#teaser) {
226
- this.#detachAiCodeCompletionTeaser();
227
- this.#teaser = undefined;
228
- }
229
- if (!this.#aiCodeCompletion) {
230
- const contextFlavor = this.uiSourceCode.url().startsWith('snippet://') ?
231
- AiCodeCompletion.AiCodeCompletion.ContextFlavor.CONSOLE :
232
- AiCodeCompletion.AiCodeCompletion.ContextFlavor.SOURCES;
233
- this.#aiCodeCompletion = new AiCodeCompletion.AiCodeCompletion.AiCodeCompletion(
234
- {aidaClient: this.#aidaClient}, contextFlavor, createCallbacks(this.#editor));
235
- this.#aiCodeCompletion.addEventListener(
236
- AiCodeCompletion.AiCodeCompletion.Events.REQUEST_TRIGGERED, this.#onAiRequestTriggered, this);
237
- this.#aiCodeCompletion.addEventListener(
238
- AiCodeCompletion.AiCodeCompletion.Events.RESPONSE_RECEIVED, this.#onAiResponseReceived, this);
239
- }
240
94
  this.#createAiCodeCompletionDisclaimer();
241
95
  this.#createAiCodeCompletionCitationsToolbar();
242
96
  }
@@ -281,46 +135,10 @@ export class AiCodeCompletionPlugin extends Plugin {
281
135
  }
282
136
  }
283
137
 
284
- #onAiCodeCompletionSettingChanged(): void {
285
- if (this.#aiCodeCompletionSetting.get()) {
286
- this.#setupAiCodeCompletion();
287
- } else if (this.#aiCodeCompletion) {
288
- this.#cleanupAiCodeCompletion();
289
- }
290
- }
291
-
292
- async #onAidaAvailabilityChange(): Promise<void> {
293
- const currentAidaAvailability = await Host.AidaClient.AidaClient.checkAccessPreconditions();
294
- if (currentAidaAvailability !== this.#aidaAvailability) {
295
- this.#aidaAvailability = currentAidaAvailability;
296
- if (this.#aidaAvailability === Host.AidaClient.AidaAccessPreconditions.AVAILABLE) {
297
- this.#onAiCodeCompletionSettingChanged();
298
- if (this.#editor?.state.doc.length === 0) {
299
- this.#addTeaserPluginToCompartmentImmediate(this.#editor?.editor);
300
- }
301
- } else if (this.#aiCodeCompletion) {
302
- this.#cleanupAiCodeCompletion();
303
- if (this.#teaser) {
304
- this.#editor?.dispatch({
305
- effects: this.#teaserCompartment.reconfigure([]),
306
- });
307
- }
308
- }
309
- }
310
- }
311
-
312
138
  #cleanupAiCodeCompletion(): void {
313
- this.#aiCodeCompletion?.removeEventListener(
314
- AiCodeCompletion.AiCodeCompletion.Events.REQUEST_TRIGGERED, this.#onAiRequestTriggered, this);
315
- this.#aiCodeCompletion?.removeEventListener(
316
- AiCodeCompletion.AiCodeCompletion.Events.RESPONSE_RECEIVED, this.#onAiResponseReceived, this);
317
- this.#aiCodeCompletion?.remove();
318
- this.#aiCodeCompletion = undefined;
319
- this.#aiCodeCompletionCitations = [];
320
- this.#aiCodeCompletionDisclaimer?.detach();
139
+ this.#aiCodeCompletionDisclaimerContainer.removeChildren();
321
140
  this.#aiCodeCompletionDisclaimer = undefined;
322
141
  this.#removeAiCodeCompletionCitationsToolbar();
323
- this.#aiCodeCompletionCitationsToolbar = undefined;
324
142
  }
325
143
 
326
144
  #onAiRequestTriggered = (): void => {
@@ -329,13 +147,12 @@ export class AiCodeCompletionPlugin extends Plugin {
329
147
  }
330
148
  };
331
149
 
332
- #onAiResponseReceived =
333
- (event: Common.EventTarget.EventTargetEvent<AiCodeCompletion.AiCodeCompletion.ResponseReceivedEvent>): void => {
334
- this.#aiCodeCompletionCitations = event.data.citations ?? [];
335
- if (this.#aiCodeCompletionDisclaimer) {
336
- this.#aiCodeCompletionDisclaimer.loading = false;
337
- }
338
- };
150
+ #onAiResponseReceived = (citations: Host.AidaClient.Citation[]): void => {
151
+ this.#aiCodeCompletionCitations = citations;
152
+ if (this.#aiCodeCompletionDisclaimer) {
153
+ this.#aiCodeCompletionDisclaimer.loading = false;
154
+ }
155
+ };
339
156
 
340
157
  #onAiCodeCompletionSuggestionAccepted(): void {
341
158
  if (!this.#aiCodeCompletionCitationsToolbar || this.#aiCodeCompletionCitations.length === 0) {
@@ -349,28 +166,6 @@ export class AiCodeCompletionPlugin extends Plugin {
349
166
  }
350
167
  }
351
168
 
352
- #detachAiCodeCompletionTeaser(): void {
353
- this.#editor?.dispatch({
354
- effects: this.#teaserCompartment.reconfigure([]),
355
- });
356
- this.#teaser = undefined;
357
- }
358
-
359
- #isAiCodeCompletionEnabled(): boolean {
360
- const devtoolsLocale = i18n.DevToolsLocale.DevToolsLocale.instance();
361
- const aidaAvailability = Root.Runtime.hostConfig.aidaAvailability;
362
- if (!devtoolsLocale.locale.startsWith('en-')) {
363
- return false;
364
- }
365
- if (aidaAvailability?.blockedByGeo) {
366
- return false;
367
- }
368
- if (aidaAvailability?.blockedByAge) {
369
- return false;
370
- }
371
- return Boolean(Root.Runtime.hostConfig.devToolsAiCodeCompletion?.enabled);
372
- }
373
-
374
169
  #getInferenceLanguage(): Host.AidaClient.AidaInferenceLanguage|undefined {
375
170
  const mimeType = this.uiSourceCode.mimeType();
376
171
  switch (mimeType) {
@@ -435,51 +230,4 @@ export class AiCodeCompletionPlugin extends Plugin {
435
230
  return undefined;
436
231
  }
437
232
  }
438
-
439
- setAidaClientForTest(aidaClient: Host.AidaClient.AidaClient): void {
440
- this.#aidaClient = aidaClient;
441
- }
442
- }
443
-
444
- export function aiCodeCompletionTeaserExtension(teaser: PanelCommon.AiCodeCompletionTeaser): CodeMirror.Extension {
445
- const teaserPlugin = CodeMirror.ViewPlugin.fromClass(class {
446
- #teaserDecoration: CodeMirror.DecorationSet;
447
-
448
- constructor(readonly view: CodeMirror.EditorView) {
449
- const cursorPosition = this.view.state.selection.main.head;
450
- const line = this.view.state.doc.lineAt(cursorPosition);
451
- const column = cursorPosition - line.from;
452
- const isCursorAtEndOfLine = column >= line.length;
453
- if (isCursorAtEndOfLine) {
454
- this.#teaserDecoration = CodeMirror.Decoration.set([
455
- CodeMirror.Decoration
456
- .widget({
457
- widget: new TextEditor.AiCodeCompletionTeaserPlaceholder.AiCodeCompletionTeaserPlaceholder(teaser),
458
- side: 1
459
- })
460
- .range(cursorPosition),
461
- ]);
462
- } else {
463
- this.#teaserDecoration = CodeMirror.Decoration.none;
464
- }
465
- }
466
-
467
- declare update: () => void;
468
-
469
- get decorations(): CodeMirror.DecorationSet {
470
- return this.#teaserDecoration;
471
- }
472
- }, {
473
- decorations: v => v.decorations,
474
- eventHandlers: {
475
- mousedown(event: MouseEvent): boolean {
476
- // Required for mouse click to propagate to the "Don't show again" span in teaser.
477
- if (event.target instanceof Node && teaser.contentElement.contains(event.target)) {
478
- return true;
479
- }
480
- return false;
481
- },
482
- },
483
- });
484
- return teaserPlugin;
485
233
  }
@@ -3,7 +3,6 @@
3
3
  // found in the LICENSE file.
4
4
  /* eslint-disable @devtools/no-imperative-dom-api */
5
5
 
6
- import * as Common from '../../core/common/common.js';
7
6
  import * as i18n from '../../core/i18n/i18n.js';
8
7
  import type * as Platform from '../../core/platform/platform.js';
9
8
  import * as SDK from '../../core/sdk/sdk.js';
@@ -14,6 +13,7 @@ import * as IconButton from '../../ui/components/icon_button/icon_button.js';
14
13
  import * as uiI18n from '../../ui/i18n/i18n.js';
15
14
  import * as UI from '../../ui/legacy/legacy.js';
16
15
  import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
16
+ import * as PanelsCommon from '../common/common.js';
17
17
 
18
18
  import {getLocalizedBreakpointName} from './CategorizedBreakpointL10n.js';
19
19
  import debuggerPausedMessageStyles from './debuggerPausedMessage.css.js';
@@ -168,11 +168,11 @@ export class DebuggerPausedMessage {
168
168
  i18nString(UIStrings.pausedOnS, {PH1: breakpointType ? breakpointType() : String(null)})));
169
169
 
170
170
  const subElement = messageWrapper.createChild('div', 'status-sub monospace');
171
- const linkifiedNode = await Common.Linkifier.Linkifier.linkify(data.node);
171
+ const linkifiedNode = PanelsCommon.DOMLinkifier.Linkifier.instance().linkify(data.node);
172
172
  subElement.appendChild(linkifiedNode);
173
173
 
174
174
  if (data.targetNode) {
175
- const targetNodeLink = await Common.Linkifier.Linkifier.linkify(data.targetNode);
175
+ const targetNodeLink = PanelsCommon.DOMLinkifier.Linkifier.instance().linkify(data.targetNode);
176
176
  let messageElement;
177
177
  if (data.insertion) {
178
178
  if (data.targetNode === data.node) {
@@ -24,6 +24,7 @@ import * as Tooltips from '../../ui/components/tooltips/tooltips.js';
24
24
  import * as ObjectUI from '../../ui/legacy/components/object_ui/object_ui.js';
25
25
  import * as SourceFrame from '../../ui/legacy/components/source_frame/source_frame.js';
26
26
  import * as UI from '../../ui/legacy/legacy.js';
27
+ import {render} from '../../ui/lit/lit.js';
27
28
  import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
28
29
 
29
30
  import {AddDebugInfoURLDialog} from './AddSourceMapURLDialog.js';
@@ -2004,7 +2005,8 @@ class ValueDecoration extends CodeMirror.WidgetType {
2004
2005
  const propertyCount = value.preview ? value.preview.properties.length : 0;
2005
2006
  const entryCount = value.preview?.entries ? value.preview.entries.length : 0;
2006
2007
  if (value.preview && propertyCount + entryCount < 10) {
2007
- formatter.appendObjectPreview(nameValuePair, value.preview, false /* isEntry */);
2008
+ /* eslint-disable-next-line @devtools/no-lit-render-outside-of-view */
2009
+ render(formatter.renderObjectPreview(value.preview), nameValuePair.createChild('span'));
2008
2010
  } else {
2009
2011
  const propertyValue = ObjectUI.ObjectPropertiesSection.ObjectPropertiesSection.createPropertyValue(
2010
2012
  value, /* wasThrown */ false, /* showPreview */ false);