chrome-devtools-frontend 1.0.1697998 → 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.
- package/.agents/skills/version-control/SKILL.md +21 -9
- package/front_end/core/platform/HostRuntime.ts +12 -0
- package/front_end/core/platform/api/HostRuntime.ts +13 -0
- package/front_end/core/platform/browser/HostRuntime.ts +34 -0
- package/front_end/core/platform/node/HostRuntime.ts +40 -0
- package/front_end/core/sdk/AnimationModel.ts +12 -98
- package/front_end/core/sdk/CSSModel.ts +4 -2
- package/front_end/core/sdk/CSSPropertyParser.ts +4 -4
- package/front_end/core/sdk/CSSPropertyParserMatchers.ts +4 -44
- package/front_end/core/sdk/Connections.ts +6 -1
- package/front_end/core/sdk/ConsoleModel.ts +1 -12
- package/front_end/core/sdk/DOMModel.ts +3 -51
- package/front_end/core/sdk/DebuggerModel.ts +9 -8
- package/front_end/core/sdk/NetworkRequest.ts +1 -1
- package/front_end/core/sdk/PageFunctions.ts +187 -0
- package/front_end/core/sdk/Resource.ts +1 -1
- package/front_end/core/sdk/RuntimeModel.ts +1 -20
- package/front_end/core/sdk/Script.ts +21 -0
- package/front_end/core/sdk/SourceMap.ts +15 -2
- package/front_end/core/sdk/SourceMapCache.ts +13 -10
- package/front_end/core/sdk/SourceMapManager.ts +11 -9
- package/front_end/core/sdk/SourceMapScopeChainEntry.ts +59 -17
- package/front_end/core/sdk/SourceMapScopesInfo.ts +8 -2
- package/front_end/entrypoints/heap_snapshot_worker/ContextAnalyzer.ts +635 -0
- package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshot.ts +26 -12
- package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshotLoader.ts +16 -2
- package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshotWorkerDispatcher.ts +4 -4
- package/front_end/entrypoints/heap_snapshot_worker/heap_snapshot_worker.ts +2 -0
- package/front_end/entrypoints/shell/shell.ts +1 -1
- package/front_end/models/ai_assistance/DOMHelpers.ts +95 -0
- package/front_end/models/ai_assistance/EvaluateAction.ts +5 -42
- package/front_end/models/ai_assistance/ExtensionScope.ts +2 -31
- package/front_end/models/ai_assistance/agents/AiAgent.ts +2 -1
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +3 -4
- package/front_end/models/ai_assistance/ai_assistance.ts +2 -0
- package/front_end/models/ai_assistance/contexts/DOMNodeContext.ts +10 -7
- package/front_end/models/ai_assistance/contexts/FileContext.ts +2 -10
- package/front_end/models/ai_assistance/tools/GetSourceContent.ts +3 -2
- package/front_end/models/ai_assistance/tools/ListSources.ts +21 -14
- package/front_end/models/bindings/CompilerScriptMapping.ts +3 -10
- package/front_end/models/bindings/DebuggerLanguagePlugins.ts +48 -17
- package/front_end/models/bindings/ResourceScriptMapping.ts +2 -2
- package/front_end/models/bindings/StylesSourceMapping.ts +1 -1
- package/front_end/models/comment_manager/CD4ABridge.ts +55 -12
- package/front_end/models/comment_manager/CommentManager.ts +46 -91
- package/front_end/models/comment_manager/CommentThread.ts +145 -0
- package/front_end/models/comment_manager/comment_manager.ts +2 -0
- package/front_end/models/emulation/DeviceModeModel.ts +53 -0
- package/front_end/models/extensions/ExtensionAPI.ts +8 -6
- package/front_end/models/extensions/ExtensionEndpoint.ts +11 -8
- package/front_end/models/extensions/HostUrlPattern.ts +4 -3
- package/front_end/models/extensions/LanguageExtensionEndpoint.ts +3 -2
- package/front_end/models/extensions/RecorderExtensionEndpoint.ts +2 -1
- package/front_end/models/formatter/FormatterWorkerPool.ts +4 -6
- package/front_end/models/heap_snapshot/HeapSnapshotModel.ts +55 -0
- package/front_end/models/heap_snapshot/HeapSnapshotProxy.ts +18 -14
- package/front_end/models/issues_manager/IssuesManager.ts +5 -0
- package/front_end/models/issues_manager/WebInstallIssue.ts +63 -0
- package/front_end/models/issues_manager/descriptions/webInstallManifestMissingId.md +3 -0
- package/front_end/models/issues_manager/descriptions/webInstallManifestMissingNameOrShortName.md +3 -0
- package/front_end/models/issues_manager/descriptions/webInstallManifestParsingOrNetworkError.md +3 -0
- package/front_end/models/issues_manager/descriptions/webInstallNoManifest.md +3 -0
- package/front_end/models/issues_manager/descriptions/webInstallStartUrlInvalid.md +3 -0
- package/front_end/models/issues_manager/issues_manager.ts +2 -0
- package/front_end/models/workspace/UISourceCode.ts +20 -0
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +4 -6
- package/front_end/panels/ai_assistance/components/AIv2MarkdownRenderer.ts +4 -10
- package/front_end/{ui/comments → panels/common}/CommentThreadWidget.ts +4 -4
- package/front_end/{ui/comments → panels/common}/CommentsOverlayWidget.ts +39 -62
- package/front_end/{ui/comments → panels/common}/CommentsStatusBarPill.ts +5 -5
- package/front_end/panels/common/ExtensionServer.ts +2 -1
- package/front_end/{ui/comments → panels/common}/commentsOverlay.css +2 -1
- package/front_end/{ui/comments/comments-meta.ts → panels/common/common-meta.ts} +11 -11
- package/front_end/panels/common/common.ts +3 -0
- package/front_end/panels/elements/AdoptedStyleSheetTreeElement.ts +3 -3
- package/front_end/panels/elements/ElementsPanel.ts +5 -1
- package/front_end/panels/elements/ElementsTreeElement.ts +4 -1
- package/front_end/panels/elements/ElementsTreeOutline.ts +58 -51
- package/front_end/panels/elements/PropertiesWidget.ts +11 -10
- package/front_end/panels/elements/PropertyRenderer.ts +29 -25
- package/front_end/panels/elements/StylePropertyTreeElement.ts +6 -6
- package/front_end/panels/elements/elementsTreeOutline.css +7 -1
- package/front_end/panels/emulation/DeviceModeToolbar.ts +2 -3
- package/front_end/panels/event_listeners/EventListenersView.ts +33 -44
- package/front_end/panels/linear_memory_inspector/LinearMemoryInspectorController.ts +6 -7
- package/front_end/panels/linear_memory_inspector/components/linearMemoryInspector.css +5 -1
- package/front_end/panels/linear_memory_inspector/linear_memory_inspector-meta.ts +1 -1
- package/front_end/panels/recorder/stepView.css +1 -0
- package/front_end/panels/security/SecurityPanel.ts +5 -5
- package/front_end/panels/security/SecurityPanelSidebar.ts +2 -11
- package/front_end/panels/sources/DebuggerPlugin.ts +1 -1
- package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +11 -16
- package/front_end/panels/sources/sources-meta.ts +1 -1
- package/front_end/panels/timeline/overlays/OverlaysImpl.ts +0 -3
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/ui/comments/CommentOverlayManager.ts +28 -110
- package/front_end/ui/comments/comments.ts +0 -6
- package/front_end/ui/legacy/Treeoutline.ts +4 -0
- package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +14 -7
- package/front_end/ui/visual_logging/KnownContextValues.ts +1 -0
- package/package.json +1 -1
- /package/front_end/{ui/comments → panels/common}/commentThreadWidget.css +0 -0
|
@@ -0,0 +1,63 @@
|
|
|
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 type * as SDK from '../../core/sdk/sdk.js';
|
|
6
|
+
import * as Protocol from '../../generated/protocol.js';
|
|
7
|
+
|
|
8
|
+
import {Issue, IssueCategory, IssueKind} from './Issue.js';
|
|
9
|
+
import type {MarkdownIssueDescription} from './MarkdownIssueDescription.js';
|
|
10
|
+
|
|
11
|
+
export class WebInstallIssue extends Issue<Protocol.Audits.WebInstallIssueDetails> {
|
|
12
|
+
constructor(issueDetails: Protocol.Audits.WebInstallIssueDetails, issuesModel: SDK.IssuesModel.IssuesModel|null) {
|
|
13
|
+
super(`${Protocol.Audits.InspectorIssueCode.WebInstallIssue}::${issueDetails.reason}`, issueDetails, issuesModel);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
override requests(): Protocol.Audits.AffectedRequest[] {
|
|
17
|
+
const {manifestUrl, reason} = this.details();
|
|
18
|
+
if (reason === Protocol.Audits.WebInstallIssueReason.NoManifest || !manifestUrl) {
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
21
|
+
return [{url: manifestUrl}];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
getCategory(): IssueCategory {
|
|
25
|
+
return IssueCategory.OTHER;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
getDescription(): MarkdownIssueDescription|null {
|
|
29
|
+
switch (this.details().reason) {
|
|
30
|
+
case Protocol.Audits.WebInstallIssueReason.ManifestParsingOrNetworkError:
|
|
31
|
+
return {file: 'webInstallManifestParsingOrNetworkError.md', links: []};
|
|
32
|
+
case Protocol.Audits.WebInstallIssueReason.StartUrlInvalid:
|
|
33
|
+
return {file: 'webInstallStartUrlInvalid.md', links: []};
|
|
34
|
+
case Protocol.Audits.WebInstallIssueReason.ManifestMissingNameOrShortName:
|
|
35
|
+
return {file: 'webInstallManifestMissingNameOrShortName.md', links: []};
|
|
36
|
+
case Protocol.Audits.WebInstallIssueReason.ManifestMissingId:
|
|
37
|
+
return {file: 'webInstallManifestMissingId.md', links: []};
|
|
38
|
+
case Protocol.Audits.WebInstallIssueReason.NoManifest:
|
|
39
|
+
return {file: 'webInstallNoManifest.md', links: []};
|
|
40
|
+
default:
|
|
41
|
+
console.warn('Unknown WebInstallIssueReason:', this.details().reason);
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
getKind(): IssueKind {
|
|
47
|
+
return IssueKind.PAGE_ERROR;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
primaryKey(): string {
|
|
51
|
+
return JSON.stringify(this.details());
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
static fromInspectorIssue(issuesModel: SDK.IssuesModel.IssuesModel|null,
|
|
55
|
+
inspectorIssue: Protocol.Audits.InspectorIssue): WebInstallIssue[] {
|
|
56
|
+
const details = inspectorIssue.details.webInstallIssueDetails;
|
|
57
|
+
if (!details) {
|
|
58
|
+
console.warn('Web install issue without details received.');
|
|
59
|
+
return [];
|
|
60
|
+
}
|
|
61
|
+
return [new WebInstallIssue(details, issuesModel)];
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -36,6 +36,7 @@ import * as SourceFrameIssuesManager from './SourceFrameIssuesManager.js';
|
|
|
36
36
|
import * as SRIMessageSignatureIssue from './SRIMessageSignatureIssue.js';
|
|
37
37
|
import * as StylesheetLoadingIssue from './StylesheetLoadingIssue.js';
|
|
38
38
|
import * as UnencodedDigestIssue from './UnencodedDigestIssue.js';
|
|
39
|
+
import * as WebInstallIssue from './WebInstallIssue.js';
|
|
39
40
|
|
|
40
41
|
export {
|
|
41
42
|
ClientHintIssue,
|
|
@@ -72,4 +73,5 @@ export {
|
|
|
72
73
|
SRIMessageSignatureIssue,
|
|
73
74
|
StylesheetLoadingIssue,
|
|
74
75
|
UnencodedDigestIssue,
|
|
76
|
+
WebInstallIssue,
|
|
75
77
|
};
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import * as Common from '../../core/common/common.js';
|
|
8
8
|
import * as i18n from '../../core/i18n/i18n.js';
|
|
9
9
|
import * as Platform from '../../core/platform/platform.js';
|
|
10
|
+
import * as SDK from '../../core/sdk/sdk.js';
|
|
10
11
|
import * as TextUtils from '../../core/text_utils/text_utils.js';
|
|
11
12
|
|
|
12
13
|
import {IgnoreListManager} from './IgnoreListManager.js';
|
|
@@ -29,6 +30,7 @@ export class UISourceCode extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
|
|
|
29
30
|
TextUtils.ContentProvider.ContentProvider {
|
|
30
31
|
readonly #origin: Platform.DevToolsPath.UrlString;
|
|
31
32
|
readonly #parentURL: Platform.DevToolsPath.UrlString;
|
|
33
|
+
#securityOrigin?: SDK.SecurityOrigin.SecurityOrigin;
|
|
32
34
|
#project: Project;
|
|
33
35
|
#url: Platform.DevToolsPath.UrlString;
|
|
34
36
|
#name: string;
|
|
@@ -110,6 +112,23 @@ export class UISourceCode extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
|
|
|
110
112
|
return this.#origin;
|
|
111
113
|
}
|
|
112
114
|
|
|
115
|
+
/**
|
|
116
|
+
* Returns the security origin for this source code.
|
|
117
|
+
* Prefers the project security origin if available. If the project does not
|
|
118
|
+
* define a security origin, derives it from the source code's URL and caches
|
|
119
|
+
* the result until the source code is renamed.
|
|
120
|
+
*/
|
|
121
|
+
securityOrigin(): SDK.SecurityOrigin.SecurityOrigin {
|
|
122
|
+
const projectOrigin = this.#project.securityOrigin?.();
|
|
123
|
+
if (projectOrigin) {
|
|
124
|
+
return projectOrigin;
|
|
125
|
+
}
|
|
126
|
+
if (!this.#securityOrigin) {
|
|
127
|
+
this.#securityOrigin = SDK.SecurityOrigin.SecurityOrigin.create(this.#url);
|
|
128
|
+
}
|
|
129
|
+
return this.#securityOrigin;
|
|
130
|
+
}
|
|
131
|
+
|
|
113
132
|
fullDisplayName(): string {
|
|
114
133
|
return this.#project.fullDisplayName(this);
|
|
115
134
|
}
|
|
@@ -150,6 +169,7 @@ export class UISourceCode extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
|
|
|
150
169
|
#updateName(
|
|
151
170
|
name: Platform.DevToolsPath.RawPathString, url: Platform.DevToolsPath.UrlString,
|
|
152
171
|
contentType?: Common.ResourceType.ResourceType): void {
|
|
172
|
+
this.#securityOrigin = undefined;
|
|
153
173
|
const oldURL = this.#url;
|
|
154
174
|
this.#name = name;
|
|
155
175
|
if (url) {
|
|
@@ -282,12 +282,10 @@ async function getEmptyStateSuggestions(conversation?: AiAssistanceModel.AiConve
|
|
|
282
282
|
}
|
|
283
283
|
}
|
|
284
284
|
|
|
285
|
-
function createV2MarkdownRenderer(conversation
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
options.getEstablishedOrigin = () => conversation.origin;
|
|
290
|
-
}
|
|
285
|
+
function createV2MarkdownRenderer(conversation: AiAssistanceModel.AiConversation.AiConversation): AIv2MarkdownRenderer {
|
|
286
|
+
const options: AIv2MarkdownRendererOptions = {
|
|
287
|
+
getOriginLock: () => conversation.getOriginLock(),
|
|
288
|
+
};
|
|
291
289
|
const primaryTarget = SDK.TargetManager.TargetManager.instance().primaryPageTarget();
|
|
292
290
|
const domModel = primaryTarget?.model(SDK.DOMModel.DOMModel);
|
|
293
291
|
const resourceTreeModel = primaryTarget?.model(SDK.ResourceTreeModel.ResourceTreeModel);
|
|
@@ -21,13 +21,10 @@ export interface AIv2MarkdownRendererOptions {
|
|
|
21
21
|
mainFrameId?: string;
|
|
22
22
|
mainDocumentURL?: Platform.DevToolsPath.UrlString;
|
|
23
23
|
/**
|
|
24
|
-
* Retrieves the
|
|
24
|
+
* Retrieves the origin lock for the active conversation.
|
|
25
25
|
* Required to authorize #file-<id> links and prevent cross-origin file leakage.
|
|
26
|
-
*
|
|
27
|
-
* TODO(crbug.com/559522248): Defer renderer instantiation until a conversation
|
|
28
|
-
* starts so this origin can be passed as a mandatory, non-getter property.
|
|
29
26
|
*/
|
|
30
|
-
|
|
27
|
+
getOriginLock: () => AiAssistanceModel.Tool.OriginLockState;
|
|
31
28
|
lookupTraceEvent?: (key: string) => Trace.Types.Events.Event | null;
|
|
32
29
|
}
|
|
33
30
|
|
|
@@ -45,7 +42,7 @@ type ParsedLink = {
|
|
|
45
42
|
* the only markdown renderer used by AI assistance.
|
|
46
43
|
*/
|
|
47
44
|
export class AIv2MarkdownRenderer extends MarkdownView.MarkdownView.MarkdownInsightRenderer {
|
|
48
|
-
constructor(private readonly options: AIv2MarkdownRendererOptions
|
|
45
|
+
constructor(private readonly options: AIv2MarkdownRendererOptions) {
|
|
49
46
|
super();
|
|
50
47
|
}
|
|
51
48
|
|
|
@@ -119,10 +116,7 @@ export class AIv2MarkdownRenderer extends MarkdownView.MarkdownView.MarkdownInsi
|
|
|
119
116
|
}
|
|
120
117
|
if (href.startsWith('#file-')) {
|
|
121
118
|
const fileId = Number(href.substring(6));
|
|
122
|
-
const
|
|
123
|
-
const file = (origin && Number.isInteger(fileId) && fileId > 0) ?
|
|
124
|
-
AiAssistanceModel.ListSources.ListSourcesTool.getSourceById(fileId, origin) :
|
|
125
|
-
undefined;
|
|
119
|
+
const file = AiAssistanceModel.ListSources.ListSourcesTool.getSourceById(fileId, this.options.getOriginLock());
|
|
126
120
|
|
|
127
121
|
if (file) {
|
|
128
122
|
return this.#revealableLink(file, file.name());
|
|
@@ -2,14 +2,14 @@
|
|
|
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 '
|
|
5
|
+
import '../../ui/components/tooltips/tooltips.js';
|
|
6
6
|
|
|
7
7
|
import * as i18n from '../../core/i18n/i18n.js';
|
|
8
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';
|
|
9
11
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
10
12
|
import * as Lit from '../../ui/lit/lit.js';
|
|
11
|
-
import * as Input from '../components/input/input.js';
|
|
12
|
-
import * as MarkdownView from '../components/markdown_view/markdown_view.js';
|
|
13
13
|
|
|
14
14
|
import commentThreadWidgetStyles from './commentThreadWidget.css.js';
|
|
15
15
|
|
|
@@ -52,7 +52,7 @@ const UIStringsNotTranslate = {
|
|
|
52
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
53
|
} as const;
|
|
54
54
|
|
|
55
|
-
const str_ = i18n.i18n.registerUIStrings('
|
|
55
|
+
const str_ = i18n.i18n.registerUIStrings('panels/common/CommentThreadWidget.ts', UIStrings);
|
|
56
56
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
57
57
|
const lockedString = i18n.i18n.lockedString;
|
|
58
58
|
|
|
@@ -5,18 +5,10 @@
|
|
|
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 PendingHighlightRectData,
|
|
17
|
-
type PendingPinPositionData,
|
|
18
|
-
type PinPositionData,
|
|
19
|
-
} from './CommentOverlayManager.js';
|
|
20
12
|
import commentsOverlayStyles from './commentsOverlay.css.js';
|
|
21
13
|
import {CommentThreadWidget} from './CommentThreadWidget.js';
|
|
22
14
|
|
|
@@ -27,18 +19,14 @@ const {
|
|
|
27
19
|
Directives: {repeat, styleMap},
|
|
28
20
|
} = Lit;
|
|
29
21
|
|
|
30
|
-
export type ViewHighlightRectData = HighlightRectData|PendingHighlightRectData;
|
|
31
|
-
|
|
32
22
|
export interface ViewInput {
|
|
33
|
-
pins: PinPositionData[];
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
hoverHighlight: HoverHighlightData|null;
|
|
23
|
+
pins: Comments.CommentOverlayManager.PinPositionData[];
|
|
24
|
+
highlights: Comments.CommentOverlayManager.HighlightRectData[];
|
|
25
|
+
hoverHighlight: Comments.CommentOverlayManager.HoverHighlightData|null;
|
|
37
26
|
commentMode: boolean;
|
|
38
27
|
onPinClick: (threadId: string) => void;
|
|
39
28
|
activeThread: CommentManager.CommentManager.CommentThread|null;
|
|
40
|
-
activePin: PinPositionData|
|
|
41
|
-
activeTargetKey: unknown;
|
|
29
|
+
activePin: Comments.CommentOverlayManager.PinPositionData|null;
|
|
42
30
|
onAddComment: (text: string) => void;
|
|
43
31
|
}
|
|
44
32
|
|
|
@@ -72,7 +60,6 @@ const DEFAULT_VIEW: View = (input: ViewInput, _output: undefined, target: HTMLEl
|
|
|
72
60
|
${input.highlights.map(h => h.visible ? html`
|
|
73
61
|
<div
|
|
74
62
|
class="comment-anchor-highlight"
|
|
75
|
-
data-comment-id=${('id' in h && h.id) || nothing}
|
|
76
63
|
style=${styleMap({
|
|
77
64
|
top: `${h.top}px`,
|
|
78
65
|
left: `${h.left}px`,
|
|
@@ -81,20 +68,9 @@ const DEFAULT_VIEW: View = (input: ViewInput, _output: undefined, target: HTMLEl
|
|
|
81
68
|
})}>
|
|
82
69
|
</div>
|
|
83
70
|
` : nothing)}
|
|
84
|
-
${input.pendingPin && input.pendingPin.visible ? html`
|
|
85
|
-
<div
|
|
86
|
-
class="comment-pin"
|
|
87
|
-
style=${styleMap({
|
|
88
|
-
top: `${input.pendingPin.top}px`,
|
|
89
|
-
left: `${input.pendingPin.left}px`,
|
|
90
|
-
})}>
|
|
91
|
-
<div class="comment-cursor">${input.pendingPin.index}</div>
|
|
92
|
-
</div>
|
|
93
|
-
` : nothing}
|
|
94
71
|
${input.pins.map(p => p.visible ? html`
|
|
95
72
|
<div
|
|
96
73
|
class="comment-pin"
|
|
97
|
-
data-comment-id=${p.id}
|
|
98
74
|
style=${styleMap({
|
|
99
75
|
top: `${p.top}px`,
|
|
100
76
|
left: `${p.left}px`,
|
|
@@ -103,9 +79,9 @@ const DEFAULT_VIEW: View = (input: ViewInput, _output: undefined, target: HTMLEl
|
|
|
103
79
|
<div class="comment-cursor">${p.index}</div>
|
|
104
80
|
</div>
|
|
105
81
|
` : nothing)}
|
|
106
|
-
${input.activePin ? repeat(
|
|
107
|
-
[{pin: input.activePin,
|
|
108
|
-
item => item.
|
|
82
|
+
${input.activePin && input.activeThread ? repeat(
|
|
83
|
+
[{pin: input.activePin, thread: input.activeThread}],
|
|
84
|
+
item => item.thread.id,
|
|
109
85
|
item => html`
|
|
110
86
|
<div
|
|
111
87
|
class="comment-popup-widget"
|
|
@@ -120,7 +96,7 @@ const DEFAULT_VIEW: View = (input: ViewInput, _output: undefined, target: HTMLEl
|
|
|
120
96
|
)}px`,
|
|
121
97
|
})}>
|
|
122
98
|
${UI.Widget.widget(CommentThreadWidget, {
|
|
123
|
-
comments:
|
|
99
|
+
comments: [...item.thread.comments],
|
|
124
100
|
onAddComment: input.onAddComment,
|
|
125
101
|
})}
|
|
126
102
|
</div>
|
|
@@ -137,7 +113,7 @@ export class CommentsOverlayWidget extends UI.Widget.Widget {
|
|
|
137
113
|
|
|
138
114
|
readonly #view: View;
|
|
139
115
|
readonly #commentManager: CommentManager.CommentManager.CommentManager;
|
|
140
|
-
#commentOverlayManager: CommentOverlayManager;
|
|
116
|
+
#commentOverlayManager: Comments.CommentOverlayManager.CommentOverlayManager;
|
|
141
117
|
#activeThreadId: string|null = null;
|
|
142
118
|
|
|
143
119
|
constructor(
|
|
@@ -148,12 +124,12 @@ export class CommentsOverlayWidget extends UI.Widget.Widget {
|
|
|
148
124
|
super(element, {useShadowDom: false});
|
|
149
125
|
this.#view = view;
|
|
150
126
|
this.#commentManager = commentManager;
|
|
151
|
-
this.#commentOverlayManager = new CommentOverlayManager(
|
|
127
|
+
this.#commentOverlayManager = new Comments.CommentOverlayManager.CommentOverlayManager(
|
|
152
128
|
this.#commentManager,
|
|
153
129
|
);
|
|
154
130
|
}
|
|
155
131
|
|
|
156
|
-
setOverlayManagerForTest(overlayManager: CommentOverlayManager): void {
|
|
132
|
+
setOverlayManagerForTest(overlayManager: Comments.CommentOverlayManager.CommentOverlayManager): void {
|
|
157
133
|
this.#commentOverlayManager = overlayManager;
|
|
158
134
|
}
|
|
159
135
|
|
|
@@ -161,12 +137,12 @@ export class CommentsOverlayWidget extends UI.Widget.Widget {
|
|
|
161
137
|
super.wasShown();
|
|
162
138
|
this.#commentOverlayManager.start();
|
|
163
139
|
this.#commentOverlayManager.addEventListener(
|
|
164
|
-
|
|
140
|
+
Comments.CommentOverlayManager.Events.POSITIONS_UPDATED,
|
|
165
141
|
this.#onStateChanged,
|
|
166
142
|
this,
|
|
167
143
|
);
|
|
168
144
|
this.#commentOverlayManager.addEventListener(
|
|
169
|
-
|
|
145
|
+
Comments.CommentOverlayManager.Events.HOVER_HIGHLIGHT_CHANGED,
|
|
170
146
|
this.#onStateChanged,
|
|
171
147
|
this,
|
|
172
148
|
);
|
|
@@ -188,12 +164,12 @@ export class CommentsOverlayWidget extends UI.Widget.Widget {
|
|
|
188
164
|
override willHide(): void {
|
|
189
165
|
this.#commentOverlayManager.stop();
|
|
190
166
|
this.#commentOverlayManager.removeEventListener(
|
|
191
|
-
|
|
167
|
+
Comments.CommentOverlayManager.Events.POSITIONS_UPDATED,
|
|
192
168
|
this.#onStateChanged,
|
|
193
169
|
this,
|
|
194
170
|
);
|
|
195
171
|
this.#commentOverlayManager.removeEventListener(
|
|
196
|
-
|
|
172
|
+
Comments.CommentOverlayManager.Events.HOVER_HIGHLIGHT_CHANGED,
|
|
197
173
|
this.#onStateChanged,
|
|
198
174
|
this,
|
|
199
175
|
);
|
|
@@ -217,6 +193,9 @@ export class CommentsOverlayWidget extends UI.Widget.Widget {
|
|
|
217
193
|
CommentManager.CommentManager.EventTypes[CommentManager.CommentManager.Events.COMMENT_MODE_CHANGED]>,
|
|
218
194
|
): void {
|
|
219
195
|
const isModeActive = event.data;
|
|
196
|
+
if (!isModeActive) {
|
|
197
|
+
this.#activeThreadId = null;
|
|
198
|
+
}
|
|
220
199
|
const action = UI.ActionRegistry.ActionRegistry.instance().getAction(
|
|
221
200
|
'comments.toggle-comment-mode',
|
|
222
201
|
);
|
|
@@ -225,17 +204,24 @@ export class CommentsOverlayWidget extends UI.Widget.Widget {
|
|
|
225
204
|
}
|
|
226
205
|
|
|
227
206
|
#onStateChanged(): void {
|
|
228
|
-
|
|
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)) {
|
|
229
211
|
this.#activeThreadId = null;
|
|
230
212
|
}
|
|
231
213
|
this.requestUpdate();
|
|
232
214
|
}
|
|
233
215
|
|
|
234
216
|
#handlePinClick = (threadId: string): void => {
|
|
235
|
-
this.#
|
|
217
|
+
const thread = this.#commentManager.getCommentThread(threadId);
|
|
236
218
|
if (this.#activeThreadId === threadId) {
|
|
219
|
+
if (thread?.status === 'DRAFT') {
|
|
220
|
+
this.#commentOverlayManager.clearDraftThreads();
|
|
221
|
+
}
|
|
237
222
|
this.#activeThreadId = null;
|
|
238
223
|
} else {
|
|
224
|
+
this.#commentOverlayManager.clearDraftThreads();
|
|
239
225
|
this.#activeThreadId = threadId;
|
|
240
226
|
}
|
|
241
227
|
this.requestUpdate();
|
|
@@ -243,41 +229,25 @@ export class CommentsOverlayWidget extends UI.Widget.Widget {
|
|
|
243
229
|
|
|
244
230
|
override performUpdate(): void {
|
|
245
231
|
const pins = this.#commentOverlayManager.getPinPositions();
|
|
246
|
-
const
|
|
247
|
-
const pendingPin = draft?.pin ?? null;
|
|
248
|
-
const highlights: ViewHighlightRectData[] = [
|
|
249
|
-
...this.#commentOverlayManager.getHighlightRects(),
|
|
250
|
-
];
|
|
251
|
-
|
|
252
|
-
if (draft?.highlight) {
|
|
253
|
-
highlights.push(draft.highlight);
|
|
254
|
-
}
|
|
232
|
+
const highlights = this.#commentOverlayManager.getHighlightRects();
|
|
255
233
|
|
|
256
|
-
let activePin: PinPositionData|
|
|
234
|
+
let activePin: Comments.CommentOverlayManager.PinPositionData|null = null;
|
|
257
235
|
let activeThread: CommentManager.CommentManager.CommentThread|null = null;
|
|
258
|
-
if (
|
|
259
|
-
activePin = pendingPin;
|
|
260
|
-
} else if (this.#activeThreadId) {
|
|
236
|
+
if (this.#activeThreadId) {
|
|
261
237
|
activePin = pins.find(p => p.id === this.#activeThreadId) ?? null;
|
|
262
238
|
activeThread = this.#commentManager.getCommentThread(this.#activeThreadId) ?? null;
|
|
263
239
|
}
|
|
264
240
|
|
|
265
241
|
const viewInput: ViewInput = {
|
|
266
242
|
pins,
|
|
267
|
-
pendingPin,
|
|
268
243
|
highlights,
|
|
269
244
|
hoverHighlight: this.#commentOverlayManager.getHoverHighlight(),
|
|
270
245
|
commentMode: this.#commentManager.isCommentMode(),
|
|
271
246
|
onPinClick: this.#handlePinClick,
|
|
272
247
|
activeThread,
|
|
273
248
|
activePin,
|
|
274
|
-
activeTargetKey: draft ?? activeThread,
|
|
275
249
|
onAddComment: (text: string) => {
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
if (pendingDraft) {
|
|
279
|
-
this.#commentOverlayManager.createComment(pendingDraft.element, text, {pendingDraft});
|
|
280
|
-
}
|
|
250
|
+
activeThread?.save(text);
|
|
281
251
|
},
|
|
282
252
|
};
|
|
283
253
|
this.#view(viewInput, undefined, this.contentElement);
|
|
@@ -313,4 +283,11 @@ export class ActionDelegate implements UI.ActionRegistration.ActionDelegate {
|
|
|
313
283
|
}
|
|
314
284
|
return false;
|
|
315
285
|
}
|
|
286
|
+
|
|
287
|
+
static resetForTest(): void {
|
|
288
|
+
if (widgetInstance) {
|
|
289
|
+
widgetInstance.detach();
|
|
290
|
+
widgetInstance = null;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
316
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 '
|
|
8
|
-
import * as Lit from '
|
|
9
|
-
import * as VisualLogging from '
|
|
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('
|
|
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
|
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
position: fixed;
|
|
11
11
|
inset: 0;
|
|
12
12
|
pointer-events: none;
|
|
13
|
-
/* Needs to be above regular panel widgets (e.g. flame chart at z-index 2000)
|
|
13
|
+
/* Needs to be above regular panel widgets (e.g. flame chart at z-index 2000)
|
|
14
|
+
but below floating glass panes (which start at z-index 3000). */
|
|
14
15
|
z-index: 2500;
|
|
15
16
|
overflow: hidden;
|
|
16
17
|
width: 100vw;
|
|
@@ -6,7 +6,7 @@ import * as i18n from '../../core/i18n/i18n.js';
|
|
|
6
6
|
import type * as Root from '../../core/root/root.js';
|
|
7
7
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
8
8
|
|
|
9
|
-
import type * as
|
|
9
|
+
import type * as Common from './common.js';
|
|
10
10
|
|
|
11
11
|
const UIStrings = {
|
|
12
12
|
/**
|
|
@@ -22,16 +22,16 @@ const UIStrings = {
|
|
|
22
22
|
*/
|
|
23
23
|
comments: 'Comments',
|
|
24
24
|
} as const;
|
|
25
|
-
const str_ = i18n.i18n.registerUIStrings('
|
|
25
|
+
const str_ = i18n.i18n.registerUIStrings('panels/common/common-meta.ts', UIStrings);
|
|
26
26
|
const i18nLazyString = i18n.i18n.getLazilyComputedLocalizedString.bind(undefined, str_);
|
|
27
27
|
|
|
28
|
-
let
|
|
28
|
+
let loadedCommonModule: (typeof Common|undefined);
|
|
29
29
|
|
|
30
|
-
async function
|
|
31
|
-
if (!
|
|
32
|
-
|
|
30
|
+
async function loadCommonModule(): Promise<typeof Common> {
|
|
31
|
+
if (!loadedCommonModule) {
|
|
32
|
+
loadedCommonModule = await import('./common.js');
|
|
33
33
|
}
|
|
34
|
-
return
|
|
34
|
+
return loadedCommonModule;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
function isCommentsEnabled(config?: Root.Runtime.HostConfig): boolean {
|
|
@@ -46,8 +46,8 @@ UI.ViewManager.registerViewExtension({
|
|
|
46
46
|
commandPrompt: i18nLazyString(UIStrings.showComments),
|
|
47
47
|
title: i18nLazyString(UIStrings.comments),
|
|
48
48
|
async loadView(universe) {
|
|
49
|
-
const
|
|
50
|
-
return new
|
|
49
|
+
const Common = await loadCommonModule();
|
|
50
|
+
return new Common.CommentsStatusBarPill.CommentsStatusBarPill(undefined, [universe.commentManager]);
|
|
51
51
|
},
|
|
52
52
|
});
|
|
53
53
|
|
|
@@ -59,8 +59,8 @@ UI.ActionRegistration.registerActionExtension({
|
|
|
59
59
|
toggleable: true,
|
|
60
60
|
condition: isCommentsEnabled,
|
|
61
61
|
async loadActionDelegate() {
|
|
62
|
-
const
|
|
63
|
-
return new
|
|
62
|
+
const Common = await loadCommonModule();
|
|
63
|
+
return new Common.CommentsOverlayWidget.ActionDelegate();
|
|
64
64
|
},
|
|
65
65
|
});
|
|
66
66
|
|
|
@@ -13,3 +13,6 @@ export * as ExtensionView from './ExtensionView.js';
|
|
|
13
13
|
export * as PersistenceUtils from './PersistenceUtils.js';
|
|
14
14
|
export * as DOMLinkifier from './DOMLinkifier.js';
|
|
15
15
|
export * as ExtensionIframe from './ExtensionView.js';
|
|
16
|
+
export * as CommentThreadWidget from './CommentThreadWidget.js';
|
|
17
|
+
export * as CommentsOverlayWidget from './CommentsOverlayWidget.js';
|
|
18
|
+
export * as CommentsStatusBarPill from './CommentsStatusBarPill.js';
|
|
@@ -20,7 +20,7 @@ const {Directives: {ref}, html, render} = Lit;
|
|
|
20
20
|
|
|
21
21
|
export class AdoptedStyleSheetSetTreeElement extends UI.TreeOutline.TreeElement {
|
|
22
22
|
constructor(readonly adoptedStyleSheets: SDK.DOMModel.AdoptedStyleSheet[]) {
|
|
23
|
-
super('');
|
|
23
|
+
super('', undefined, 'adopted-style-sheets');
|
|
24
24
|
const documentElement = this.listItemElement.createChild('span');
|
|
25
25
|
UI.UIUtils.createTextChild(documentElement, '#adopted-style-sheets');
|
|
26
26
|
for (const adoptedStyleSheet of adoptedStyleSheets) {
|
|
@@ -33,7 +33,7 @@ export class AdoptedStyleSheetTreeElement extends UI.TreeOutline.TreeElement {
|
|
|
33
33
|
private eventListener: Common.EventTarget.EventDescriptor|null = null;
|
|
34
34
|
|
|
35
35
|
constructor(readonly adoptedStyleSheet: SDK.DOMModel.AdoptedStyleSheet) {
|
|
36
|
-
super('');
|
|
36
|
+
super('', undefined, 'adopted-style-sheet');
|
|
37
37
|
const header = adoptedStyleSheet.cssModel.styleSheetHeaderForId(adoptedStyleSheet.id);
|
|
38
38
|
if (header) {
|
|
39
39
|
AdoptedStyleSheetTreeElement.createContents(header, this);
|
|
@@ -79,7 +79,7 @@ export class AdoptedStyleSheetContentsTreeElement extends UI.TreeOutline.TreeEle
|
|
|
79
79
|
private readonly widgetWrapper: HTMLElement;
|
|
80
80
|
|
|
81
81
|
constructor(styleSheetHeader: SDK.CSSStyleSheetHeader.CSSStyleSheetHeader) {
|
|
82
|
-
super('');
|
|
82
|
+
super('', undefined, 'adopted-style-sheet-contents');
|
|
83
83
|
this.widgetWrapper = document.createElement('div');
|
|
84
84
|
this.widgetWrapper.style.display = 'contents';
|
|
85
85
|
this.title = this.widgetWrapper;
|
|
@@ -228,6 +228,10 @@ export class ElementsPanel extends UI.Panel.Panel implements UI.SearchableView.S
|
|
|
228
228
|
return this.#domTreeWidget.getTreeOutlineForTesting();
|
|
229
229
|
}
|
|
230
230
|
|
|
231
|
+
getDOMTreeWidgetForTesting(): DOMTreeWidget {
|
|
232
|
+
return this.#domTreeWidget;
|
|
233
|
+
}
|
|
234
|
+
|
|
231
235
|
constructor(
|
|
232
236
|
targetManager?: SDK.TargetManager.TargetManager,
|
|
233
237
|
settings?: Common.Settings.Settings,
|
|
@@ -1300,7 +1304,7 @@ export class ElementsPanel extends UI.Panel.Panel implements UI.SearchableView.S
|
|
|
1300
1304
|
}
|
|
1301
1305
|
|
|
1302
1306
|
toggleHideElement(node: SDK.DOMModel.DOMNode): void {
|
|
1303
|
-
this.#domTreeWidget.toggleHideElement(node);
|
|
1307
|
+
void this.#domTreeWidget.toggleHideElement(node);
|
|
1304
1308
|
}
|
|
1305
1309
|
|
|
1306
1310
|
toggleEditAsHTML(node: SDK.DOMModel.DOMNode): void {
|