chrome-devtools-frontend 1.0.1697595 → 1.0.1698733

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 (124) hide show
  1. package/.agents/skills/version-control/SKILL.md +21 -9
  2. package/.stylelintignore +2 -0
  3. package/front_end/core/common/VersionController.ts +5 -1
  4. package/front_end/core/platform/HostRuntime.ts +12 -0
  5. package/front_end/core/platform/api/HostRuntime.ts +13 -0
  6. package/front_end/core/platform/browser/HostRuntime.ts +34 -0
  7. package/front_end/core/platform/node/HostRuntime.ts +40 -0
  8. package/front_end/core/sdk/AnimationModel.ts +21 -99
  9. package/front_end/core/sdk/CSSModel.ts +4 -2
  10. package/front_end/core/sdk/CSSPropertyParser.ts +4 -4
  11. package/front_end/core/sdk/CSSPropertyParserMatchers.ts +4 -44
  12. package/front_end/core/sdk/Connections.ts +6 -1
  13. package/front_end/core/sdk/ConsoleModel.ts +1 -12
  14. package/front_end/core/sdk/DOMModel.ts +3 -51
  15. package/front_end/core/sdk/DebuggerModel.ts +9 -8
  16. package/front_end/core/sdk/NetworkRequest.ts +1 -1
  17. package/front_end/core/sdk/PageFunctions.ts +187 -0
  18. package/front_end/core/sdk/Resource.ts +1 -1
  19. package/front_end/core/sdk/RuntimeModel.ts +1 -20
  20. package/front_end/core/sdk/Script.ts +21 -0
  21. package/front_end/core/sdk/SourceMap.ts +15 -2
  22. package/front_end/core/sdk/SourceMapCache.ts +13 -10
  23. package/front_end/core/sdk/SourceMapManager.ts +11 -9
  24. package/front_end/core/sdk/SourceMapScopeChainEntry.ts +59 -17
  25. package/front_end/core/sdk/SourceMapScopesInfo.ts +8 -2
  26. package/front_end/entrypoints/heap_snapshot_worker/ContextAnalyzer.ts +635 -0
  27. package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshot.ts +26 -12
  28. package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshotLoader.ts +16 -2
  29. package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshotWorkerDispatcher.ts +4 -4
  30. package/front_end/entrypoints/heap_snapshot_worker/heap_snapshot_worker.ts +2 -0
  31. package/front_end/entrypoints/shell/shell.ts +1 -1
  32. package/front_end/generated/InspectorBackendCommands.ts +1 -1
  33. package/front_end/generated/protocol.ts +8 -2
  34. package/front_end/models/ai_assistance/DOMHelpers.ts +95 -0
  35. package/front_end/models/ai_assistance/EvaluateAction.ts +5 -42
  36. package/front_end/models/ai_assistance/ExtensionScope.ts +2 -31
  37. package/front_end/models/ai_assistance/agents/AiAgent.ts +2 -1
  38. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +27 -2
  39. package/front_end/models/ai_assistance/ai_assistance.ts +6 -4
  40. package/front_end/models/ai_assistance/contexts/DOMNodeContext.ts +10 -7
  41. package/front_end/models/ai_assistance/contexts/FileContext.ts +2 -10
  42. package/front_end/models/ai_assistance/skills/performance.md +4 -3
  43. package/front_end/models/ai_assistance/tools/GetSourceContent.ts +3 -2
  44. package/front_end/models/ai_assistance/tools/{GetFunctionCode.ts → GetTraceFunctionCode.ts} +26 -13
  45. package/front_end/models/ai_assistance/tools/{GetResourceContent.ts → GetTraceResourceContent.ts} +31 -11
  46. package/front_end/models/ai_assistance/tools/ListSources.ts +21 -14
  47. package/front_end/models/ai_assistance/tools/Tool.ts +2 -2
  48. package/front_end/models/ai_assistance/tools/ToolRegistry.ts +6 -6
  49. package/front_end/models/bindings/CompilerScriptMapping.ts +3 -10
  50. package/front_end/models/bindings/DebuggerLanguagePlugins.ts +48 -17
  51. package/front_end/models/bindings/ResourceScriptMapping.ts +2 -2
  52. package/front_end/models/bindings/StylesSourceMapping.ts +1 -1
  53. package/front_end/models/comment_manager/CD4ABridge.ts +55 -12
  54. package/front_end/models/comment_manager/CommentManager.ts +46 -91
  55. package/front_end/models/comment_manager/CommentThread.ts +145 -0
  56. package/front_end/models/comment_manager/comment_manager.ts +2 -0
  57. package/front_end/models/elements/DOMChanges.ts +238 -0
  58. package/front_end/models/elements/elements.ts +2 -0
  59. package/front_end/models/emulation/DeviceModeModel.ts +53 -0
  60. package/front_end/models/extensions/ExtensionAPI.ts +8 -6
  61. package/front_end/models/extensions/ExtensionEndpoint.ts +11 -8
  62. package/front_end/models/extensions/HostUrlPattern.ts +4 -3
  63. package/front_end/models/extensions/LanguageExtensionEndpoint.ts +3 -2
  64. package/front_end/models/extensions/RecorderExtensionEndpoint.ts +2 -1
  65. package/front_end/models/formatter/FormatterWorkerPool.ts +4 -6
  66. package/front_end/models/heap_snapshot/HeapSnapshotModel.ts +55 -0
  67. package/front_end/models/heap_snapshot/HeapSnapshotProxy.ts +18 -14
  68. package/front_end/models/issues_manager/IssuesManager.ts +5 -0
  69. package/front_end/models/issues_manager/WebInstallIssue.ts +63 -0
  70. package/front_end/models/issues_manager/descriptions/webInstallManifestMissingId.md +3 -0
  71. package/front_end/models/issues_manager/descriptions/webInstallManifestMissingNameOrShortName.md +3 -0
  72. package/front_end/models/issues_manager/descriptions/webInstallManifestParsingOrNetworkError.md +3 -0
  73. package/front_end/models/issues_manager/descriptions/webInstallNoManifest.md +3 -0
  74. package/front_end/models/issues_manager/descriptions/webInstallStartUrlInvalid.md +3 -0
  75. package/front_end/models/issues_manager/issues_manager.ts +2 -0
  76. package/front_end/models/workspace/UISourceCode.ts +20 -0
  77. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +7 -7
  78. package/front_end/panels/ai_assistance/components/AIv2MarkdownRenderer.ts +4 -10
  79. package/front_end/panels/ai_assistance/components/MarkdownRendererWithCodeBlock.ts +25 -5
  80. package/front_end/panels/browser_debugger/ObjectEventListenersSidebarPane.ts +2 -3
  81. package/front_end/panels/common/CommentThreadWidget.ts +221 -0
  82. package/front_end/{ui/comments → panels/common}/CommentsOverlayWidget.ts +117 -28
  83. package/front_end/{ui/comments → panels/common}/CommentsStatusBarPill.ts +5 -5
  84. package/front_end/panels/common/ExtensionServer.ts +2 -1
  85. package/front_end/panels/common/commentThreadWidget.css +173 -0
  86. package/front_end/{ui/comments → panels/common}/commentsOverlay.css +8 -1
  87. package/front_end/{ui/comments/comments-meta.ts → panels/common/common-meta.ts} +11 -11
  88. package/front_end/panels/common/common.ts +3 -0
  89. package/front_end/panels/elements/AdoptedStyleSheetTreeElement.ts +3 -3
  90. package/front_end/panels/elements/ElementsPanel.ts +5 -1
  91. package/front_end/panels/elements/ElementsTreeElement.ts +102 -21
  92. package/front_end/panels/elements/ElementsTreeOutline.ts +326 -91
  93. package/front_end/panels/elements/EventListenersWidget.ts +0 -1
  94. package/front_end/panels/elements/PropertiesWidget.ts +11 -10
  95. package/front_end/panels/elements/PropertyRenderer.ts +29 -25
  96. package/front_end/panels/elements/StylePropertyTreeElement.ts +6 -6
  97. package/front_end/panels/elements/elementsTreeOutline.css +7 -1
  98. package/front_end/panels/emulation/DeviceModeToolbar.ts +2 -3
  99. package/front_end/panels/event_listeners/EventListenersView.ts +235 -302
  100. package/front_end/panels/linear_memory_inspector/LinearMemoryInspectorController.ts +6 -7
  101. package/front_end/panels/linear_memory_inspector/components/linearMemoryInspector.css +5 -1
  102. package/front_end/panels/linear_memory_inspector/linear_memory_inspector-meta.ts +1 -1
  103. package/front_end/panels/mobile_throttling/ThrottlingSettingsTab.ts +10 -2
  104. package/front_end/panels/network/NetworkConfigView.ts +141 -116
  105. package/front_end/panels/network/NetworkPanel.ts +7 -4
  106. package/front_end/panels/network/RequestHeadersView.ts +1 -1
  107. package/front_end/panels/network/forward/BackendLinking.ts +5 -2
  108. package/front_end/panels/recorder/stepView.css +1 -0
  109. package/front_end/panels/security/SecurityPanel.ts +5 -5
  110. package/front_end/panels/security/SecurityPanelSidebar.ts +2 -11
  111. package/front_end/panels/settings/BackendLinkingSettingsTab.ts +7 -2
  112. package/front_end/panels/sources/DebuggerPlugin.ts +1 -1
  113. package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +11 -16
  114. package/front_end/panels/sources/sources-meta.ts +1 -1
  115. package/front_end/panels/timeline/TimelineTreeView.ts +11 -1
  116. package/front_end/panels/timeline/overlays/OverlaysImpl.ts +0 -3
  117. package/front_end/third_party/chromium/README.chromium +1 -1
  118. package/front_end/ui/comments/CommentOverlayManager.ts +89 -42
  119. package/front_end/ui/comments/comments.ts +0 -4
  120. package/front_end/ui/legacy/Treeoutline.ts +4 -0
  121. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +15 -8
  122. package/front_end/ui/legacy/components/perf_ui/FlameChart.ts +4 -0
  123. package/front_end/ui/visual_logging/KnownContextValues.ts +1 -0
  124. package/package.json +5 -5
@@ -20,8 +20,6 @@ export class ObjectEventListenersSidebarPane extends UI.Widget.VBox implements U
20
20
  this.contentElement.setAttribute('jslog', `${VisualLogging.section('sources.global-listeners')}`);
21
21
 
22
22
  this.eventListenersView = new EventListeners.EventListenersView.EventListenersView();
23
- this.eventListenersView.changeCallback = this.requestUpdate.bind(this);
24
- this.eventListenersView.enableDefaultTreeFocus = true;
25
23
  this.eventListenersView.show(this.element);
26
24
  this.setDefaultFocusedChild(this.eventListenersView);
27
25
  this.requestUpdate();
@@ -57,7 +55,8 @@ export class ObjectEventListenersSidebarPane extends UI.Widget.VBox implements U
57
55
  windowObjects.push(result.object);
58
56
  }
59
57
  }
60
- await this.eventListenersView.addObjects(windowObjects);
58
+ this.eventListenersView.objects = windowObjects;
59
+ await this.eventListenersView.updateComplete;
61
60
  }
62
61
 
63
62
  override wasShown(): void {
@@ -0,0 +1,221 @@
1
+ // Copyright 2026 The Chromium Authors
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ import '../../ui/components/tooltips/tooltips.js';
6
+
7
+ import * as i18n from '../../core/i18n/i18n.js';
8
+ import type * as CommentManager from '../../models/comment_manager/comment_manager.js';
9
+ import * as Input from '../../ui/components/input/input.js';
10
+ import * as MarkdownView from '../../ui/components/markdown_view/markdown_view.js';
11
+ import * as UI from '../../ui/legacy/legacy.js';
12
+ import * as Lit from '../../ui/lit/lit.js';
13
+
14
+ import commentThreadWidgetStyles from './commentThreadWidget.css.js';
15
+
16
+ const {html, render, Directives: {createRef, ref}} = Lit;
17
+
18
+ const UIStrings = {
19
+ /**
20
+ * @description Link text in the info tooltip for learning more about comments sent to the agent.
21
+ */
22
+ learnMore: 'Learn more',
23
+ /**
24
+ * @description Text next to the checkmark in the comment thread header indicating that comments have been sent to
25
+ * the agent.
26
+ */
27
+ sent: 'Sent',
28
+ /**
29
+ * @description Alt text for the checkmark icon in the comment thread header indicating that comments have been sent
30
+ * to the agent.
31
+ */
32
+ sentCheckmark: 'Sent checkmark',
33
+ /**
34
+ * @description Label for the agent response section in the comment thread.
35
+ */
36
+ response: 'Response:',
37
+ /**
38
+ * @description Label for the aria-label of the add comment button.
39
+ */
40
+ addCommentButton: 'Add comment',
41
+ /**
42
+ * @description aria-label for the comment text area.
43
+ */
44
+ commentInputAriaLabel: 'Comment input',
45
+ } as const;
46
+
47
+ const UIStringsNotTranslate = {
48
+ /**
49
+ * @description Disclaimer text in the comment thread info tooltip.
50
+ */
51
+ inputDisclaimer:
52
+ 'Comment strings, DOM hierarchy snippets, tracked CSS and DOM changes, Visual Element (VE) paths and signatures, and tracked presenter changes are sent to the connected third-party agent to assist with debugging and code updates.',
53
+ } as const;
54
+
55
+ const str_ = i18n.i18n.registerUIStrings('panels/common/CommentThreadWidget.ts', UIStrings);
56
+ const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
57
+ const lockedString = i18n.i18n.lockedString;
58
+
59
+ export interface ViewInput {
60
+ title: string;
61
+ comments: CommentManager.CommentManager.Comment[];
62
+ commentText: string;
63
+ textAreaRef: Lit.Directives.Ref<HTMLTextAreaElement>;
64
+ onLearnMoreClick: () => void;
65
+ onAddComment: (text: string) => void;
66
+ onCommentTextChange: (event: Event) => void;
67
+ }
68
+
69
+ export type ViewOutput = undefined;
70
+
71
+ export const DEFAULT_VIEW = (input: ViewInput, _output: ViewOutput, target: HTMLElement): void => {
72
+ const hasComment = input.comments.length > 0;
73
+
74
+ // clang-format off
75
+ render(html`
76
+ <style>${Input.textInputStyles}${commentThreadWidgetStyles}</style>
77
+ <div class="comment-thread-widget ${hasComment ? 'submitted' : ''}">
78
+ <div class="header">
79
+ <span class="selected-item">
80
+ <span class="selected-item-text">${input.title}</span>
81
+ </span>
82
+ ${hasComment ? html`
83
+ <div class="sent-status">
84
+ <devtools-icon
85
+ class="check-icon"
86
+ name="checkmark"
87
+ aria-label=${i18nString(UIStrings.sentCheckmark)}>
88
+ </devtools-icon>
89
+ <span>${i18nString(UIStrings.sent)}</span>
90
+ </div>
91
+ ` : Lit.nothing}
92
+ </div>
93
+
94
+ ${hasComment ? html`
95
+ ${input.comments.map(comment => comment.author === 'DEVELOPER' ? html`
96
+ <div class="comment-text">
97
+ ${comment.text}
98
+ </div>
99
+ ` : html`
100
+ <div class="agent-response">
101
+ <div class="elbow"></div>
102
+ <div class="response-content">
103
+ <div class="response-header">${i18nString(UIStrings.response)}</div>
104
+ ${MarkdownView.MarkdownView.renderTextAsMarkdown(
105
+ comment.text,
106
+ new MarkdownView.MarkdownView.MarkdownInsightRenderer(),
107
+ )}
108
+ </div>
109
+ </div>
110
+ `)}
111
+ ` : Lit.nothing}
112
+
113
+ ${!hasComment ? html`
114
+ <textarea
115
+ ${ref(input.textAreaRef)}
116
+ class="devtools-text-input input"
117
+ rows="1"
118
+ aria-label=${i18nString(UIStrings.commentInputAriaLabel)}
119
+ .value=${input.commentText}
120
+ @input=${input.onCommentTextChange}
121
+ @keydown=${(event: KeyboardEvent) => {
122
+ if (event.key === 'Enter' && !event.shiftKey && !event.isComposing) {
123
+ event.preventDefault();
124
+ input.onAddComment(input.commentText);
125
+ }
126
+ }}
127
+ ></textarea>
128
+ <div class="footer">
129
+ <devtools-icon
130
+ class="info-icon"
131
+ name="info"
132
+ aria-label="Info"
133
+ aria-details="comment-thread-info-tooltip"
134
+ tabindex="0"
135
+ ></devtools-icon>
136
+ <devtools-tooltip
137
+ id="comment-thread-info-tooltip"
138
+ variant="rich"
139
+ >
140
+ <div class="info-tooltip-container">
141
+ ${lockedString(UIStringsNotTranslate.inputDisclaimer)}
142
+ <button
143
+ class="tooltip-link"
144
+ role="link"
145
+ @click=${input.onLearnMoreClick}
146
+ >${i18nString(UIStrings.learnMore)}</button>
147
+ </div>
148
+ </devtools-tooltip>
149
+ <devtools-button
150
+ aria-label=${i18nString(UIStrings.addCommentButton)}
151
+ .disabled=${!input.commentText.trim()}
152
+ @click=${() => input.onAddComment(input.commentText)}>
153
+ ${i18nString(UIStrings.addCommentButton)}
154
+ </devtools-button>
155
+ </div>
156
+ ` : Lit.nothing}
157
+ </div>
158
+ `, target);
159
+ // clang-format on
160
+ };
161
+
162
+ type View = typeof DEFAULT_VIEW;
163
+
164
+ export class CommentThreadWidget extends UI.Widget.Widget {
165
+ title = 'Comment Thread';
166
+ #comments: CommentManager.CommentManager.Comment[] = [];
167
+ #commentText = '';
168
+ #textAreaRef = createRef<HTMLTextAreaElement>();
169
+ #view: View;
170
+ onAddComment?: (text: string) => void;
171
+
172
+ constructor(element?: HTMLElement, view: View = DEFAULT_VIEW) {
173
+ super(element);
174
+ this.#view = view;
175
+ }
176
+
177
+ override wasShown(): void {
178
+ super.wasShown();
179
+ this.requestUpdate();
180
+ void this.updateComplete.then(() => {
181
+ this.#textAreaRef.value?.focus({preventScroll: true});
182
+ });
183
+ }
184
+
185
+ set comments(comments: CommentManager.CommentManager.Comment[]) {
186
+ this.#comments = comments;
187
+ this.requestUpdate();
188
+ }
189
+
190
+ #handleLearnMoreClick = (): void => {
191
+ // TODO: wire up the learn more click
192
+ };
193
+
194
+ #handleAddComment = (text: string): void => {
195
+ const commentText = text.trim();
196
+ if (commentText && this.onAddComment) {
197
+ this.onAddComment(commentText);
198
+ this.#commentText = '';
199
+ this.requestUpdate();
200
+ }
201
+ };
202
+
203
+ #handleCommentTextChange = (event: Event): void => {
204
+ const input = event.target as HTMLTextAreaElement;
205
+ this.#commentText = input.value;
206
+ this.requestUpdate();
207
+ };
208
+
209
+ override performUpdate(): void {
210
+ const viewInput: ViewInput = {
211
+ title: this.title,
212
+ comments: this.#comments,
213
+ commentText: this.#commentText,
214
+ textAreaRef: this.#textAreaRef,
215
+ onLearnMoreClick: this.#handleLearnMoreClick,
216
+ onAddComment: this.#handleAddComment,
217
+ onCommentTextChange: this.#handleCommentTextChange,
218
+ };
219
+ this.#view(viewInput, undefined, this.contentElement);
220
+ }
221
+ }
@@ -5,29 +5,41 @@
5
5
  import type * as Common from '../../core/common/common.js';
6
6
  import * as Root from '../../core/root/root.js';
7
7
  import * as CommentManager from '../../models/comment_manager/comment_manager.js';
8
+ import * as Comments from '../../ui/comments/comments.js';
8
9
  import * as UI from '../../ui/legacy/legacy.js';
9
10
  import * as Lit from '../../ui/lit/lit.js';
10
11
 
11
- import {
12
- CommentOverlayManager,
13
- Events as CommentOverlayManagerEvents,
14
- type HighlightRectData,
15
- type HoverHighlightData,
16
- type PinPositionData,
17
- } from './CommentOverlayManager.js';
18
12
  import commentsOverlayStyles from './commentsOverlay.css.js';
13
+ import {CommentThreadWidget} from './CommentThreadWidget.js';
19
14
 
20
- const {html, render, nothing, Directives: {styleMap}} = Lit;
15
+ const {
16
+ html,
17
+ render,
18
+ nothing,
19
+ Directives: {repeat, styleMap},
20
+ } = Lit;
21
21
 
22
22
  export interface ViewInput {
23
- pins: PinPositionData[];
24
- highlights: HighlightRectData[];
25
- hoverHighlight: HoverHighlightData|null;
23
+ pins: Comments.CommentOverlayManager.PinPositionData[];
24
+ highlights: Comments.CommentOverlayManager.HighlightRectData[];
25
+ hoverHighlight: Comments.CommentOverlayManager.HoverHighlightData|null;
26
26
  commentMode: boolean;
27
27
  onPinClick: (threadId: string) => void;
28
+ activeThread: CommentManager.CommentManager.CommentThread|null;
29
+ activePin: Comments.CommentOverlayManager.PinPositionData|null;
30
+ onAddComment: (text: string) => void;
28
31
  }
29
32
 
30
- export type View = (input: ViewInput, output: undefined, target: HTMLElement) => void;
33
+ export type View = (
34
+ input: ViewInput,
35
+ output: undefined,
36
+ target: HTMLElement,
37
+ ) => void;
38
+
39
+ const POPUP_MARGIN = 8;
40
+ const PIN_HEIGHT = 30;
41
+ const POPUP_WIDTH = 288;
42
+ const POPUP_HEIGHT = 220;
31
43
 
32
44
  const DEFAULT_VIEW: View = (input: ViewInput, _output: undefined, target: HTMLElement): void => {
33
45
  // clang-format off
@@ -48,7 +60,6 @@ const DEFAULT_VIEW: View = (input: ViewInput, _output: undefined, target: HTMLEl
48
60
  ${input.highlights.map(h => h.visible ? html`
49
61
  <div
50
62
  class="comment-anchor-highlight"
51
- data-comment-id=${h.id}
52
63
  style=${styleMap({
53
64
  top: `${h.top}px`,
54
65
  left: `${h.left}px`,
@@ -60,7 +71,6 @@ const DEFAULT_VIEW: View = (input: ViewInput, _output: undefined, target: HTMLEl
60
71
  ${input.pins.map(p => p.visible ? html`
61
72
  <div
62
73
  class="comment-pin"
63
- data-comment-id=${p.id}
64
74
  style=${styleMap({
65
75
  top: `${p.top}px`,
66
76
  left: `${p.left}px`,
@@ -69,28 +79,57 @@ const DEFAULT_VIEW: View = (input: ViewInput, _output: undefined, target: HTMLEl
69
79
  <div class="comment-cursor">${p.index}</div>
70
80
  </div>
71
81
  ` : nothing)}
82
+ ${input.activePin && input.activeThread ? repeat(
83
+ [{pin: input.activePin, thread: input.activeThread}],
84
+ item => item.thread.id,
85
+ item => html`
86
+ <div
87
+ class="comment-popup-widget"
88
+ style=${styleMap({
89
+ top: `${Math.min(
90
+ Math.max(POPUP_MARGIN, item.pin.top + PIN_HEIGHT),
91
+ Math.max(POPUP_MARGIN, target.clientHeight - POPUP_HEIGHT),
92
+ )}px`,
93
+ left: `${Math.min(
94
+ Math.max(POPUP_MARGIN, item.pin.left),
95
+ Math.max(POPUP_MARGIN, target.clientWidth - POPUP_WIDTH - POPUP_MARGIN),
96
+ )}px`,
97
+ })}>
98
+ ${UI.Widget.widget(CommentThreadWidget, {
99
+ comments: [...item.thread.comments],
100
+ onAddComment: input.onAddComment,
101
+ })}
102
+ </div>
103
+ `,
104
+ ) : nothing}
72
105
  </div>
73
106
  `, target);
74
107
  // clang-format on
75
108
  };
76
109
 
77
110
  export class CommentsOverlayWidget extends UI.Widget.Widget {
111
+ static override readonly INJECT: readonly[typeof CommentManager.CommentManager.CommentManager] =
112
+ [CommentManager.CommentManager.CommentManager] as const;
113
+
78
114
  readonly #view: View;
79
115
  readonly #commentManager: CommentManager.CommentManager.CommentManager;
80
- #commentOverlayManager: CommentOverlayManager;
116
+ #commentOverlayManager: Comments.CommentOverlayManager.CommentOverlayManager;
117
+ #activeThreadId: string|null = null;
81
118
 
82
119
  constructor(
83
120
  element: HTMLElement|undefined,
84
- commentManager: CommentManager.CommentManager.CommentManager,
121
+ [commentManager]: UI.Widget.WidgetDependencies<typeof CommentsOverlayWidget>,
85
122
  view: View = DEFAULT_VIEW,
86
123
  ) {
87
124
  super(element, {useShadowDom: false});
88
125
  this.#view = view;
89
126
  this.#commentManager = commentManager;
90
- this.#commentOverlayManager = new CommentOverlayManager(this.#commentManager);
127
+ this.#commentOverlayManager = new Comments.CommentOverlayManager.CommentOverlayManager(
128
+ this.#commentManager,
129
+ );
91
130
  }
92
131
 
93
- setOverlayManagerForTest(overlayManager: CommentOverlayManager): void {
132
+ setOverlayManagerForTest(overlayManager: Comments.CommentOverlayManager.CommentOverlayManager): void {
94
133
  this.#commentOverlayManager = overlayManager;
95
134
  }
96
135
 
@@ -98,12 +137,12 @@ export class CommentsOverlayWidget extends UI.Widget.Widget {
98
137
  super.wasShown();
99
138
  this.#commentOverlayManager.start();
100
139
  this.#commentOverlayManager.addEventListener(
101
- CommentOverlayManagerEvents.POSITIONS_UPDATED,
140
+ Comments.CommentOverlayManager.Events.POSITIONS_UPDATED,
102
141
  this.#onStateChanged,
103
142
  this,
104
143
  );
105
144
  this.#commentOverlayManager.addEventListener(
106
- CommentOverlayManagerEvents.HOVER_HIGHLIGHT_CHANGED,
145
+ Comments.CommentOverlayManager.Events.HOVER_HIGHLIGHT_CHANGED,
107
146
  this.#onStateChanged,
108
147
  this,
109
148
  );
@@ -125,12 +164,12 @@ export class CommentsOverlayWidget extends UI.Widget.Widget {
125
164
  override willHide(): void {
126
165
  this.#commentOverlayManager.stop();
127
166
  this.#commentOverlayManager.removeEventListener(
128
- CommentOverlayManagerEvents.POSITIONS_UPDATED,
167
+ Comments.CommentOverlayManager.Events.POSITIONS_UPDATED,
129
168
  this.#onStateChanged,
130
169
  this,
131
170
  );
132
171
  this.#commentOverlayManager.removeEventListener(
133
- CommentOverlayManagerEvents.HOVER_HIGHLIGHT_CHANGED,
172
+ Comments.CommentOverlayManager.Events.HOVER_HIGHLIGHT_CHANGED,
134
173
  this.#onStateChanged,
135
174
  this,
136
175
  );
@@ -154,24 +193,62 @@ export class CommentsOverlayWidget extends UI.Widget.Widget {
154
193
  CommentManager.CommentManager.EventTypes[CommentManager.CommentManager.Events.COMMENT_MODE_CHANGED]>,
155
194
  ): void {
156
195
  const isModeActive = event.data;
157
- const action = UI.ActionRegistry.ActionRegistry.instance().getAction('comments.toggle-comment-mode');
196
+ if (!isModeActive) {
197
+ this.#activeThreadId = null;
198
+ }
199
+ const action = UI.ActionRegistry.ActionRegistry.instance().getAction(
200
+ 'comments.toggle-comment-mode',
201
+ );
158
202
  action?.setToggled(isModeActive);
159
203
  this.requestUpdate();
160
204
  }
161
205
 
162
206
  #onStateChanged(): void {
207
+ const draftThread = this.#commentManager.getCommentThreads().find(t => t.status === 'DRAFT');
208
+ if (draftThread) {
209
+ this.#activeThreadId = draftThread.id;
210
+ } else if (this.#activeThreadId && !this.#commentManager.getCommentThread(this.#activeThreadId)) {
211
+ this.#activeThreadId = null;
212
+ }
163
213
  this.requestUpdate();
164
214
  }
165
215
 
166
- #handlePinClick = (_threadId: string): void => {};
216
+ #handlePinClick = (threadId: string): void => {
217
+ const thread = this.#commentManager.getCommentThread(threadId);
218
+ if (this.#activeThreadId === threadId) {
219
+ if (thread?.status === 'DRAFT') {
220
+ this.#commentOverlayManager.clearDraftThreads();
221
+ }
222
+ this.#activeThreadId = null;
223
+ } else {
224
+ this.#commentOverlayManager.clearDraftThreads();
225
+ this.#activeThreadId = threadId;
226
+ }
227
+ this.requestUpdate();
228
+ };
167
229
 
168
230
  override performUpdate(): void {
231
+ const pins = this.#commentOverlayManager.getPinPositions();
232
+ const highlights = this.#commentOverlayManager.getHighlightRects();
233
+
234
+ let activePin: Comments.CommentOverlayManager.PinPositionData|null = null;
235
+ let activeThread: CommentManager.CommentManager.CommentThread|null = null;
236
+ if (this.#activeThreadId) {
237
+ activePin = pins.find(p => p.id === this.#activeThreadId) ?? null;
238
+ activeThread = this.#commentManager.getCommentThread(this.#activeThreadId) ?? null;
239
+ }
240
+
169
241
  const viewInput: ViewInput = {
170
- pins: this.#commentOverlayManager.getPinPositions(),
171
- highlights: this.#commentOverlayManager.getHighlightRects(),
242
+ pins,
243
+ highlights,
172
244
  hoverHighlight: this.#commentOverlayManager.getHoverHighlight(),
173
245
  commentMode: this.#commentManager.isCommentMode(),
174
246
  onPinClick: this.#handlePinClick,
247
+ activeThread,
248
+ activePin,
249
+ onAddComment: (text: string) => {
250
+ activeThread?.save(text);
251
+ },
175
252
  };
176
253
  this.#view(viewInput, undefined, this.contentElement);
177
254
  }
@@ -192,13 +269,25 @@ export class ActionDelegate implements UI.ActionRegistration.ActionDelegate {
192
269
  handleAction(_context: UI.Context.Context, actionId: string): boolean {
193
270
  if (actionId === 'comments.toggle-comment-mode') {
194
271
  if (!widgetInstance) {
195
- widgetInstance = new CommentsOverlayWidget(undefined, this.#commentManager);
272
+ widgetInstance = new CommentsOverlayWidget(
273
+ undefined,
274
+ [this.#commentManager],
275
+ );
196
276
  widgetInstance.markAsRoot();
197
277
  widgetInstance.show(document.body);
198
278
  }
199
- this.#commentManager.setCommentMode(!this.#commentManager.isCommentMode());
279
+ this.#commentManager.setCommentMode(
280
+ !this.#commentManager.isCommentMode(),
281
+ );
200
282
  return true;
201
283
  }
202
284
  return false;
203
285
  }
286
+
287
+ static resetForTest(): void {
288
+ if (widgetInstance) {
289
+ widgetInstance.detach();
290
+ widgetInstance = null;
291
+ }
292
+ }
204
293
  }
@@ -4,9 +4,9 @@
4
4
 
5
5
  import * as i18n from '../../core/i18n/i18n.js';
6
6
  import * as CommentManager from '../../models/comment_manager/comment_manager.js';
7
- import * as UI from '../legacy/legacy.js';
8
- import * as Lit from '../lit/lit.js';
9
- import * as VisualLogging from '../visual_logging/visual_logging.js';
7
+ import * as UI from '../../ui/legacy/legacy.js';
8
+ import * as Lit from '../../ui/lit/lit.js';
9
+ import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
10
10
 
11
11
  const UIStrings = {
12
12
  /**
@@ -15,7 +15,7 @@ const UIStrings = {
15
15
  */
16
16
  commentsCount: 'Comments ({PH1})',
17
17
  } as const;
18
- const str_ = i18n.i18n.registerUIStrings('ui/comments/CommentsStatusBarPill.ts', UIStrings);
18
+ const str_ = i18n.i18n.registerUIStrings('panels/common/CommentsStatusBarPill.ts', UIStrings);
19
19
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
20
20
 
21
21
  const {html, render} = Lit;
@@ -86,7 +86,7 @@ export class CommentsStatusBarPill extends UI.Widget.Widget {
86
86
 
87
87
  override performUpdate(): void {
88
88
  const viewInput: ViewInput = {
89
- threads: this.#commentManager.getCommentThreads(),
89
+ threads: this.#commentManager.getCommentThreads().filter(thread => thread.status !== 'DRAFT'),
90
90
  onPillClick: this.#handlePillClick,
91
91
  };
92
92
  this.#view(viewInput, undefined, this.contentElement);
@@ -1287,7 +1287,8 @@ export class ExtensionServer extends Common.ObjectWrapper.ObjectWrapper<EventTyp
1287
1287
  if (scriptFiles.length > 0) {
1288
1288
  for (const script of scriptFiles) {
1289
1289
  const resourceFile = debuggerBindingsInstance.scriptFile(resource.uiSourceCode, script.debuggerModel);
1290
- resourceFile?.addSourceMapURL(message.sourceMapURL as Platform.DevToolsPath.UrlString);
1290
+ resourceFile?.addSourceMapURL(message.sourceMapURL as Platform.DevToolsPath.UrlString,
1291
+ SDK.SourceMap.SourceMapProvenance.EXTENSION);
1291
1292
  }
1292
1293
  }
1293
1294