chrome-devtools-frontend 1.0.1649421 → 1.0.1650100
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/front_end/core/sdk/CSSMetadata.ts +38 -2
- package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshot.ts +15 -0
- package/front_end/generated/Deprecation.ts +8 -0
- package/front_end/generated/SupportedCSSProperties.js +342 -114
- package/front_end/models/ai_assistance/AiConversation.ts +2 -1
- package/front_end/models/ai_assistance/agents/AccessibilityAgent.ts +10 -57
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +1 -1
- package/front_end/models/ai_assistance/ai_assistance.ts +2 -0
- package/front_end/models/ai_assistance/contexts/AccessibilityContext.snapshot.txt +26 -0
- package/front_end/models/ai_assistance/contexts/AccessibilityContext.ts +63 -0
- package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +3 -2
- package/front_end/models/javascript_metadata/NativeFunctions.js +2 -2
- package/front_end/models/stack_trace/DetailedErrorStackParser.ts +18 -0
- package/front_end/models/stack_trace/stack_trace.ts +0 -4
- package/front_end/panels/accessibility/ARIAAttributesView.ts +1 -0
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +5 -5
- package/front_end/panels/ai_assistance/components/ChatInput.ts +1 -1
- package/front_end/panels/console/ConsolePinPane.ts +1 -0
- package/front_end/panels/elements/ElementsTreeElement.ts +97 -57
- package/front_end/panels/profiler/HeapSnapshotView.ts +6 -0
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/ui/legacy/components/source_frame/SourceFrame.ts +10 -10
- package/front_end/ui/legacy/components/utils/Linkifier.ts +12 -6
- package/package.json +1 -1
- package/front_end/models/stack_trace/ErrorStackParser.ts +0 -174
|
@@ -11,7 +11,7 @@ import type * as Trace from '../../models/trace/trace.js';
|
|
|
11
11
|
import * as Greendev from '../greendev/greendev.js';
|
|
12
12
|
import type * as NetworkTimeCalculator from '../network_time_calculator/network_time_calculator.js';
|
|
13
13
|
|
|
14
|
-
import {AccessibilityAgent
|
|
14
|
+
import {AccessibilityAgent} from './agents/AccessibilityAgent.js';
|
|
15
15
|
import {
|
|
16
16
|
type AgentOptions,
|
|
17
17
|
type AiAgent,
|
|
@@ -33,6 +33,7 @@ import {StylingAgent} from './agents/StylingAgent.js';
|
|
|
33
33
|
import {AiAgent2} from './AiAgent2.js';
|
|
34
34
|
import {AiHistoryStorage, ConversationType, type SerializedConversation} from './AiHistoryStorage.js';
|
|
35
35
|
import type {ChangeManager} from './ChangeManager.js';
|
|
36
|
+
import {AccessibilityContext} from './contexts/AccessibilityContext.js';
|
|
36
37
|
import {DOMNodeContext} from './contexts/DOMNodeContext.js';
|
|
37
38
|
import {FileContext} from './contexts/FileContext.js';
|
|
38
39
|
import {RequestContext} from './contexts/RequestContext.js';
|
|
@@ -19,9 +19,8 @@ import {ToolRegistry} from '../tools/ToolRegistry.js';
|
|
|
19
19
|
import {
|
|
20
20
|
AiAgent,
|
|
21
21
|
type AiWidget,
|
|
22
|
-
type ContextDetail,
|
|
23
22
|
type ContextResponse,
|
|
24
|
-
ConversationContext,
|
|
23
|
+
type ConversationContext,
|
|
25
24
|
type RequestOptions,
|
|
26
25
|
ResponseType,
|
|
27
26
|
} from './AiAgent.js';
|
|
@@ -81,31 +80,6 @@ If the user asks a question that requires an investigation of a problem, use thi
|
|
|
81
80
|
- [Suggestion 2]
|
|
82
81
|
`;
|
|
83
82
|
|
|
84
|
-
export class AccessibilityContext extends ConversationContext<LHModel.ReporterTypes.ReportJSON> {
|
|
85
|
-
#lh: LHModel.ReporterTypes.ReportJSON;
|
|
86
|
-
|
|
87
|
-
constructor(report: LHModel.ReporterTypes.ReportJSON) {
|
|
88
|
-
super();
|
|
89
|
-
this.#lh = report;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
#url(): string {
|
|
93
|
-
return this.#lh.finalUrl ?? this.#lh.finalDisplayedUrl;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
override getURL(): string {
|
|
97
|
-
return this.#url();
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
override getItem(): LHModel.ReporterTypes.ReportJSON {
|
|
101
|
-
return this.#lh;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
override getTitle(): string {
|
|
105
|
-
return `Lighthouse report: ${this.#url()}`;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
83
|
/**
|
|
110
84
|
* One agent instance handles one conversation. Create a new agent
|
|
111
85
|
* instance for a new conversation.
|
|
@@ -184,10 +158,13 @@ export class AccessibilityAgent extends AiAgent<LHModel.ReporterTypes.ReportJSON
|
|
|
184
158
|
return;
|
|
185
159
|
}
|
|
186
160
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
161
|
+
const details = await lhr.getUserFacingDetails();
|
|
162
|
+
if (details) {
|
|
163
|
+
yield {
|
|
164
|
+
type: ResponseType.CONTEXT,
|
|
165
|
+
details,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
191
168
|
}
|
|
192
169
|
|
|
193
170
|
async #resolvePathToNode(path: string): Promise<SDK.DOMModel.DOMNode|null> {
|
|
@@ -517,38 +494,14 @@ export class AccessibilityAgent extends AiAgent<LHModel.ReporterTypes.ReportJSON
|
|
|
517
494
|
});
|
|
518
495
|
}
|
|
519
496
|
|
|
520
|
-
/**
|
|
521
|
-
* This is the initial payload we send at the start of a conversation.
|
|
522
|
-
* Because the agent is focused on Accessibility, we include the
|
|
523
|
-
* Accessibility Audits summary in the payload to avoid an extra round step of
|
|
524
|
-
* the AI querying them.
|
|
525
|
-
*/
|
|
526
|
-
#getInitialPayload(context: ConversationContext<LHModel.ReporterTypes.ReportJSON>): string {
|
|
527
|
-
const report = context.getItem();
|
|
528
|
-
const formatter = new LighthouseFormatter();
|
|
529
|
-
const summary = formatter.summary(report);
|
|
530
|
-
const audits = formatter.audits(report, 'accessibility');
|
|
531
|
-
const allFailed = Object.values(report.categories).every(category => category.score === null);
|
|
532
|
-
if (allFailed) {
|
|
533
|
-
return '**CRITICAL**: The Lighthouse report failed to record or all category scores are error/unavailable (n/a). This indicates a failed run or missing data.';
|
|
534
|
-
}
|
|
535
|
-
return `# Lighthouse Report:\n${summary}\n${audits}`;
|
|
536
|
-
}
|
|
537
|
-
|
|
538
497
|
override async enhanceQuery(query: string, lhr: ConversationContext<LHModel.ReporterTypes.ReportJSON>|null):
|
|
539
498
|
Promise<string> {
|
|
540
499
|
this.clearDeclaredFunctions();
|
|
541
500
|
if (lhr) {
|
|
542
501
|
this.#declareFunctions();
|
|
543
502
|
}
|
|
544
|
-
const
|
|
503
|
+
const promptDetails = lhr ? await lhr.getPromptDetails() : null;
|
|
504
|
+
const enhancedQuery = promptDetails ? `${promptDetails}\n# User request:\n\n` : '';
|
|
545
505
|
return `${enhancedQuery}${query}`;
|
|
546
506
|
}
|
|
547
|
-
|
|
548
|
-
#createContextDetails(lhr: ConversationContext<LHModel.ReporterTypes.ReportJSON>):
|
|
549
|
-
[ContextDetail, ...ContextDetail[]] {
|
|
550
|
-
return [
|
|
551
|
-
{title: 'Lighthouse report', text: this.#getInitialPayload(lhr)},
|
|
552
|
-
];
|
|
553
|
-
}
|
|
554
507
|
}
|
|
@@ -14,13 +14,13 @@ import * as NetworkTimeCalculator from '../../network_time_calculator/network_ti
|
|
|
14
14
|
import type * as Trace from '../../trace/trace.js';
|
|
15
15
|
import * as Workspace from '../../workspace/workspace.js';
|
|
16
16
|
import {isOpaqueOrigin} from '../AiOrigins.js';
|
|
17
|
+
import {AccessibilityContext} from '../contexts/AccessibilityContext.js';
|
|
17
18
|
import {DOMNodeContext} from '../contexts/DOMNodeContext.js';
|
|
18
19
|
import {FileContext} from '../contexts/FileContext.js';
|
|
19
20
|
import {getRequestContextOrigin, RequestContext} from '../contexts/RequestContext.js';
|
|
20
21
|
import {debugLog} from '../debug.js';
|
|
21
22
|
import {StorageItem} from '../StorageItem.js';
|
|
22
23
|
|
|
23
|
-
import {AccessibilityContext} from './AccessibilityAgent.js';
|
|
24
24
|
import {
|
|
25
25
|
type AgentOptions,
|
|
26
26
|
AiAgent,
|
|
@@ -22,6 +22,7 @@ import * as AiOrigins from './AiOrigins.js';
|
|
|
22
22
|
import * as AiUtils from './AiUtils.js';
|
|
23
23
|
import * as BuiltInAi from './BuiltInAi.js';
|
|
24
24
|
import * as ChangeManager from './ChangeManager.js';
|
|
25
|
+
import * as AccessibilityContext from './contexts/AccessibilityContext.js';
|
|
25
26
|
import * as DOMNodeContext from './contexts/DOMNodeContext.js';
|
|
26
27
|
import * as FileContext from './contexts/FileContext.js';
|
|
27
28
|
import * as RequestContext from './contexts/RequestContext.js';
|
|
@@ -50,6 +51,7 @@ import * as ToolRegistry from './tools/ToolRegistry.js';
|
|
|
50
51
|
|
|
51
52
|
export {
|
|
52
53
|
AccessibilityAgent,
|
|
54
|
+
AccessibilityContext,
|
|
53
55
|
AgentProject,
|
|
54
56
|
AiAgent,
|
|
55
57
|
AiAgent2,
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
Title: AccessibilityContext should return prompt details correctly
|
|
2
|
+
Content:
|
|
3
|
+
# Lighthouse Report:
|
|
4
|
+
# Lighthouse Report Summary
|
|
5
|
+
URL: https://example.com
|
|
6
|
+
Fetch Time: 2026-03-12
|
|
7
|
+
Lighthouse Version: 1.0.0
|
|
8
|
+
|
|
9
|
+
## Category Scores
|
|
10
|
+
- Accessibility: 50
|
|
11
|
+
# Audits for Accessibility
|
|
12
|
+
|
|
13
|
+
The following audits in this category have a score below 90 and may need attention:
|
|
14
|
+
- **Accessibility Audit**: 50 (Fail)
|
|
15
|
+
* Description of accessibility audit
|
|
16
|
+
=== end content
|
|
17
|
+
|
|
18
|
+
Title: AccessibilityContext should return user facing details correctly
|
|
19
|
+
Content:
|
|
20
|
+
[
|
|
21
|
+
{
|
|
22
|
+
"title": "Lighthouse report",
|
|
23
|
+
"text": "# Lighthouse Report:\n# Lighthouse Report Summary\nURL: https://example.com\nFetch Time: 2026-03-12\nLighthouse Version: 1.0.0\n\n## Category Scores\n- Accessibility: 50\n# Audits for Accessibility\n\nThe following audits in this category have a score below 90 and may need attention:\n- **Accessibility Audit**: 50 (Fail)\n * Description of accessibility audit"
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
=== end content
|
|
@@ -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 LHModel from '../../lighthouse/lighthouse.js';
|
|
6
|
+
import {type ContextDetail, ConversationContext} from '../agents/AiAgent.js';
|
|
7
|
+
import {LighthouseFormatter} from '../data_formatters/LighthouseFormatter.js';
|
|
8
|
+
|
|
9
|
+
export class AccessibilityContext extends ConversationContext<LHModel.ReporterTypes.ReportJSON> {
|
|
10
|
+
readonly #lh: LHModel.ReporterTypes.ReportJSON;
|
|
11
|
+
#cachedPayload: string|null = null;
|
|
12
|
+
|
|
13
|
+
constructor(report: LHModel.ReporterTypes.ReportJSON) {
|
|
14
|
+
super();
|
|
15
|
+
this.#lh = report;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
#url(): string {
|
|
19
|
+
return this.#lh.finalUrl ?? this.#lh.finalDisplayedUrl;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
override getURL(): string {
|
|
23
|
+
return this.#url();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
override getItem(): LHModel.ReporterTypes.ReportJSON {
|
|
27
|
+
return this.#lh;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
override getTitle(): string {
|
|
31
|
+
return `Lighthouse report: ${this.#url()}`;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
#getInitialPayload(): string {
|
|
35
|
+
if (this.#cachedPayload !== null) {
|
|
36
|
+
return this.#cachedPayload;
|
|
37
|
+
}
|
|
38
|
+
const formatter = new LighthouseFormatter();
|
|
39
|
+
const summary = formatter.summary(this.#lh);
|
|
40
|
+
const audits = formatter.audits(this.#lh, 'accessibility');
|
|
41
|
+
const allFailed = Object.values(this.#lh.categories).every(category => category.score === null);
|
|
42
|
+
if (allFailed) {
|
|
43
|
+
this.#cachedPayload =
|
|
44
|
+
'**CRITICAL**: The Lighthouse report failed to record or all category scores are error/unavailable (n/a). This indicates a failed run or missing data.';
|
|
45
|
+
} else {
|
|
46
|
+
this.#cachedPayload = `# Lighthouse Report:\n${summary}\n${audits}`;
|
|
47
|
+
}
|
|
48
|
+
return this.#cachedPayload;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
override async getPromptDetails(): Promise<string|null> {
|
|
52
|
+
return this.#getInitialPayload();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
override async getUserFacingDetails(): Promise<[ContextDetail, ...ContextDetail[]]|null> {
|
|
56
|
+
return [
|
|
57
|
+
{
|
|
58
|
+
title: 'Lighthouse report',
|
|
59
|
+
text: this.#getInitialPayload(),
|
|
60
|
+
},
|
|
61
|
+
];
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -7,7 +7,7 @@ import * as Platform from '../../core/platform/platform.js';
|
|
|
7
7
|
import * as Root from '../../core/root/root.js';
|
|
8
8
|
import * as SDK from '../../core/sdk/sdk.js';
|
|
9
9
|
import * as Protocol from '../../generated/protocol.js';
|
|
10
|
-
import * as StackTrace from '../stack_trace/stack_trace.js';
|
|
10
|
+
import type * as StackTrace from '../stack_trace/stack_trace.js';
|
|
11
11
|
// eslint-disable-next-line @devtools/es-modules-import
|
|
12
12
|
import * as StackTraceImpl from '../stack_trace/stack_trace_impl.js';
|
|
13
13
|
import type * as TextUtils from '../text_utils/text_utils.js';
|
|
@@ -254,7 +254,8 @@ export class DebuggerWorkspaceBinding implements SDK.TargetManager.SDKModelObser
|
|
|
254
254
|
|
|
255
255
|
const issueSummary = fetchedExceptionDetails?.exceptionMetaData?.issueSummary;
|
|
256
256
|
if (typeof issueSummary === 'string') {
|
|
257
|
-
errorStack =
|
|
257
|
+
errorStack =
|
|
258
|
+
StackTraceImpl.DetailedErrorStackParser.concatErrorDescriptionAndIssueSummary(errorStack, issueSummary);
|
|
258
259
|
}
|
|
259
260
|
|
|
260
261
|
if (!stackTrace) {
|
|
@@ -1430,7 +1430,7 @@ export const NativeFunctions = [
|
|
|
1430
1430
|
},
|
|
1431
1431
|
{
|
|
1432
1432
|
name: "add",
|
|
1433
|
-
signatures: [["
|
|
1433
|
+
signatures: [["install_paths"]],
|
|
1434
1434
|
receivers: ["SubApps"]
|
|
1435
1435
|
},
|
|
1436
1436
|
{
|
|
@@ -2005,7 +2005,7 @@ export const NativeFunctions = [
|
|
|
2005
2005
|
},
|
|
2006
2006
|
{
|
|
2007
2007
|
name: "remove",
|
|
2008
|
-
signatures: [["
|
|
2008
|
+
signatures: [["manifest_ids"]],
|
|
2009
2009
|
receivers: ["SubApps"]
|
|
2010
2010
|
},
|
|
2011
2011
|
{
|
|
@@ -212,3 +212,21 @@ export function augmentRawFramesWithScriptIds(
|
|
|
212
212
|
augmentFrame(rawFrame);
|
|
213
213
|
}
|
|
214
214
|
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Combines the error description (essentially the `Error#stack` property value)
|
|
218
|
+
* with the `issueSummary`.
|
|
219
|
+
*
|
|
220
|
+
* @param description the `description` property of the `Error` remote object.
|
|
221
|
+
* @param issueSummary the optional `issueSummary` of the `exceptionMetaData`.
|
|
222
|
+
* @returns the enriched description.
|
|
223
|
+
* @see https://goo.gle/devtools-reduce-network-noise-design
|
|
224
|
+
*/
|
|
225
|
+
export function concatErrorDescriptionAndIssueSummary(description: string, issueSummary: string): string {
|
|
226
|
+
// Insert the issue summary right after the error message.
|
|
227
|
+
const pos = description.indexOf('\n');
|
|
228
|
+
const prefix = pos === -1 ? description : description.substring(0, pos);
|
|
229
|
+
const suffix = pos === -1 ? '' : description.substring(pos);
|
|
230
|
+
description = `${prefix}. ${issueSummary}${suffix}`;
|
|
231
|
+
return description;
|
|
232
|
+
}
|
|
@@ -2,12 +2,8 @@
|
|
|
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 ErrorStackParser from './ErrorStackParser.js';
|
|
6
5
|
import * as StackTrace from './StackTrace.js';
|
|
7
6
|
|
|
8
7
|
export {
|
|
9
|
-
// TODO(crbug.com/485142682): Move to stack_trace_impl.js once all usage
|
|
10
|
-
// goes through createStackTraceFromErrorObject.
|
|
11
|
-
ErrorStackParser,
|
|
12
8
|
StackTrace,
|
|
13
9
|
};
|
|
@@ -79,6 +79,7 @@ export const DEFAULT_VIEW: View = (input, output, target) => {
|
|
|
79
79
|
<devtools-prompt
|
|
80
80
|
completions=completions
|
|
81
81
|
class="monospace"
|
|
82
|
+
value=${attribute.value}
|
|
82
83
|
@mousedown=${onStartEditing.bind(null, attribute)}
|
|
83
84
|
.completionTimeout=${0}
|
|
84
85
|
?editing=${input.attributeBeingEdited === attribute}
|
|
@@ -623,12 +623,12 @@ function createFileContext(file: Workspace.UISourceCode.UISourceCode|null): AiAs
|
|
|
623
623
|
return new AiAssistanceModel.FileContext.FileContext(file);
|
|
624
624
|
}
|
|
625
625
|
|
|
626
|
-
function createAccessibilityContext(report: LighthousePanel.LighthousePanel.ActiveLighthouseReport|
|
|
627
|
-
|
|
626
|
+
function createAccessibilityContext(report: LighthousePanel.LighthousePanel.ActiveLighthouseReport|
|
|
627
|
+
null): AiAssistanceModel.AccessibilityContext.AccessibilityContext|null {
|
|
628
628
|
if (!report) {
|
|
629
629
|
return null;
|
|
630
630
|
}
|
|
631
|
-
return new AiAssistanceModel.
|
|
631
|
+
return new AiAssistanceModel.AccessibilityContext.AccessibilityContext(report.report);
|
|
632
632
|
}
|
|
633
633
|
|
|
634
634
|
function createRequestContext(request: SDK.NetworkRequest.NetworkRequest|
|
|
@@ -710,7 +710,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
710
710
|
#selectedPerformanceTrace: AiAssistanceModel.PerformanceAgent.PerformanceTraceContext|null = null;
|
|
711
711
|
#selectedRequest: AiAssistanceModel.RequestContext.RequestContext|null = null;
|
|
712
712
|
|
|
713
|
-
#selectedAccessibility: AiAssistanceModel.
|
|
713
|
+
#selectedAccessibility: AiAssistanceModel.AccessibilityContext.AccessibilityContext|null = null;
|
|
714
714
|
#selectedStorage: AiAssistanceModel.StorageAgent.StorageContext|null = null;
|
|
715
715
|
|
|
716
716
|
// Messages displayed in the `ChatView` component.
|
|
@@ -1781,7 +1781,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
1781
1781
|
} else if (data instanceof AiAssistanceModel.PerformanceAgent.PerformanceTraceContext) {
|
|
1782
1782
|
this.#selectedPerformanceTrace = data;
|
|
1783
1783
|
|
|
1784
|
-
} else if (data instanceof AiAssistanceModel.
|
|
1784
|
+
} else if (data instanceof AiAssistanceModel.AccessibilityContext.AccessibilityContext) {
|
|
1785
1785
|
this.#selectedAccessibility = data;
|
|
1786
1786
|
} else if (data instanceof AiAssistanceModel.StorageAgent.StorageContext) {
|
|
1787
1787
|
this.#selectedStorage = data;
|
|
@@ -355,7 +355,7 @@ export const DEFAULT_VIEW = (input: ViewInput, _output: ViewOutput, target: HTML
|
|
|
355
355
|
PanelUtils.PanelUtils.getIconForNetworkRequest(input.context.getItem()) :
|
|
356
356
|
input.context instanceof AiAssistanceModel.FileContext.FileContext ?
|
|
357
357
|
PanelUtils.PanelUtils.getIconForSourceFile(input.context.getItem()) :
|
|
358
|
-
input.context instanceof AiAssistanceModel.
|
|
358
|
+
input.context instanceof AiAssistanceModel.AccessibilityContext.AccessibilityContext ?
|
|
359
359
|
html`<devtools-icon class="icon" name="performance" title="Lighthouse"></devtools-icon>` :
|
|
360
360
|
input.context instanceof AiAssistanceModel.PerformanceAgent.PerformanceTraceContext ?
|
|
361
361
|
html`<devtools-icon class="icon" name="performance" title="Performance"></devtools-icon>` :
|
|
@@ -403,6 +403,7 @@ export class ConsolePinPresenter extends UI.Widget.Widget {
|
|
|
403
403
|
CodeMirror.EditorView.domEventHandlers({
|
|
404
404
|
blur: (_e, view) => this.#onBlur(view),
|
|
405
405
|
paste: () => this.#onPaste(),
|
|
406
|
+
drop: event => event.preventDefault(),
|
|
406
407
|
}),
|
|
407
408
|
TextEditor.Config.baseConfiguration(doc),
|
|
408
409
|
TextEditor.Config.closeBrackets.instance(),
|
|
@@ -738,65 +738,86 @@ function renderLinkifiedValue(value: string, node: SDK.DOMModel.DOMNode): Lit.Te
|
|
|
738
738
|
});
|
|
739
739
|
}
|
|
740
740
|
|
|
741
|
+
const relationPromisesCache = new WeakMap<SDK.DOMModel.DOMNode, Map<string, Promise<string|Lit.LitTemplate>>>();
|
|
742
|
+
const relatedElementsCache = new WeakMap<SDK.DOMModel.DOMNode, Map<string, SDK.DOMModel.DOMNode|null>>();
|
|
743
|
+
|
|
741
744
|
function renderAttribute(
|
|
742
745
|
attr: {name: string, value?: string}, updateRecord: Elements.ElementUpdateRecord.ElementUpdateRecord|null,
|
|
743
746
|
isDiff: boolean, node: SDK.DOMModel.DOMNode): Lit.LitTemplate {
|
|
744
747
|
const name = attr.name;
|
|
745
748
|
const value = attr.value || '';
|
|
746
749
|
const forceValue = isDiff;
|
|
750
|
+
const isRelation = name === 'popovertarget' || name === 'interesttarget' || name === 'commandfor';
|
|
747
751
|
const hasText = (forceValue || value.length > 0);
|
|
748
|
-
const
|
|
749
|
-
|
|
750
|
-
dblclick: true,
|
|
751
|
-
});
|
|
752
|
-
|
|
753
|
-
const relationRef =
|
|
754
|
-
(relation: Protocol.DOM.GetElementByRelationRequestRelation, tooltip: string): ReturnType<typeof ref> =>
|
|
755
|
-
ref((el): void => {
|
|
756
|
-
if (!el) {
|
|
757
|
-
return;
|
|
758
|
-
}
|
|
759
|
-
void (async(): Promise<void> => {
|
|
760
|
-
const relatedElementId = await node.domModel().getElementByRelation(node.id, relation);
|
|
761
|
-
const relatedElement = node.domModel().nodeForId(relatedElementId);
|
|
762
|
-
if (!relatedElement) {
|
|
763
|
-
return;
|
|
764
|
-
}
|
|
765
|
-
const link = PanelsCommon.DOMLinkifier.Linkifier.instance().linkify(relatedElement, {
|
|
766
|
-
preventKeyboardFocus: true,
|
|
767
|
-
tooltip,
|
|
768
|
-
textContent: el.textContent || undefined,
|
|
769
|
-
isDynamicLink: true,
|
|
770
|
-
});
|
|
771
|
-
render(link, el as HTMLElement);
|
|
772
|
-
})();
|
|
773
|
-
});
|
|
752
|
+
const linkifyName = isRelation && value.length === 0;
|
|
753
|
+
const linkifyValue = isRelation && value.length > 0;
|
|
774
754
|
|
|
775
|
-
let
|
|
776
|
-
|
|
755
|
+
let relation: Protocol.DOM.GetElementByRelationRequestRelation|undefined = undefined;
|
|
756
|
+
let tooltip = '';
|
|
757
|
+
if (isRelation) {
|
|
777
758
|
if (name === 'popovertarget') {
|
|
778
|
-
|
|
779
|
-
|
|
759
|
+
relation = Protocol.DOM.GetElementByRelationRequestRelation.PopoverTarget;
|
|
760
|
+
tooltip = i18nString(UIStrings.showPopoverTarget);
|
|
780
761
|
} else if (name === 'interesttarget') {
|
|
781
|
-
|
|
782
|
-
|
|
762
|
+
relation = Protocol.DOM.GetElementByRelationRequestRelation.InterestTarget;
|
|
763
|
+
tooltip = i18nString(UIStrings.showInterestTarget);
|
|
783
764
|
} else if (name === 'commandfor') {
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
}
|
|
787
|
-
}
|
|
765
|
+
relation = Protocol.DOM.GetElementByRelationRequestRelation.CommandFor;
|
|
766
|
+
tooltip = i18nString(UIStrings.showCommandForTarget);
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
let relationPromise: Promise<string|Lit.LitTemplate>|undefined = undefined;
|
|
771
|
+
if (isRelation && relation) {
|
|
772
|
+
let nodeCache = relationPromisesCache.get(node);
|
|
773
|
+
if (!nodeCache) {
|
|
774
|
+
nodeCache = new Map();
|
|
775
|
+
relationPromisesCache.set(node, nodeCache);
|
|
776
|
+
}
|
|
777
|
+
const cacheKey = `${relation}:${value}`;
|
|
778
|
+
relationPromise = nodeCache.get(cacheKey);
|
|
779
|
+
const relationType = relation;
|
|
780
|
+
if (!relationPromise) {
|
|
781
|
+
relationPromise = (async () => {
|
|
782
|
+
try {
|
|
783
|
+
const relatedElementId = await node.domModel().getElementByRelation(node.id, relationType);
|
|
784
|
+
const relatedElement = node.domModel().nodeForId(relatedElementId);
|
|
785
|
+
|
|
786
|
+
let elemCache = relatedElementsCache.get(node);
|
|
787
|
+
if (!elemCache) {
|
|
788
|
+
elemCache = new Map();
|
|
789
|
+
relatedElementsCache.set(node, elemCache);
|
|
790
|
+
}
|
|
791
|
+
elemCache.set(`${name}:${value}`, relatedElement || null);
|
|
788
792
|
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
793
|
+
const isNameLinking = value.length === 0;
|
|
794
|
+
const fallback = isNameLinking ? name : value;
|
|
795
|
+
|
|
796
|
+
if (!relatedElement) {
|
|
797
|
+
return fallback;
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
const linkOptions: PanelsCommon.DOMLinkifier.Options = {
|
|
801
|
+
preventKeyboardFocus: true,
|
|
802
|
+
tooltip,
|
|
803
|
+
isDynamicLink: true,
|
|
804
|
+
};
|
|
805
|
+
|
|
806
|
+
if (isNameLinking) {
|
|
807
|
+
linkOptions.textContent = name;
|
|
808
|
+
} else {
|
|
809
|
+
const targetId = relatedElement.getAttribute('id');
|
|
810
|
+
if (targetId) {
|
|
811
|
+
linkOptions.textContent = targetId;
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
return PanelsCommon.DOMLinkifier.Linkifier.instance().linkify(relatedElement, linkOptions);
|
|
816
|
+
} catch {
|
|
817
|
+
return value.length === 0 ? name : value;
|
|
818
|
+
}
|
|
819
|
+
})();
|
|
820
|
+
nodeCache.set(cacheKey, relationPromise);
|
|
800
821
|
}
|
|
801
822
|
}
|
|
802
823
|
|
|
@@ -815,23 +836,31 @@ function renderAttribute(
|
|
|
815
836
|
valueType = ValueType.SRCSET;
|
|
816
837
|
}
|
|
817
838
|
|
|
818
|
-
const withEntitiesRef = valueType === ValueType.UNKNOWN ? ref(el => {
|
|
839
|
+
const withEntitiesRef = (valueType === ValueType.UNKNOWN && !isRelation) ? ref(el => {
|
|
819
840
|
if (el) {
|
|
820
841
|
setValueWithEntities(el, value);
|
|
821
842
|
}
|
|
822
843
|
}) :
|
|
823
|
-
|
|
844
|
+
nothing;
|
|
845
|
+
|
|
846
|
+
const jslog = VisualLogging.value(name === 'style' ? 'style-attribute' : 'attribute').track({
|
|
847
|
+
change: true,
|
|
848
|
+
dblclick: true,
|
|
849
|
+
});
|
|
824
850
|
|
|
825
|
-
// clang-format off
|
|
826
851
|
return html`<span class="webkit-html-attribute" jslog=${jslog}><span class="webkit-html-attribute-name"
|
|
827
|
-
${animateOn(Boolean(updateRecord?.isAttributeModified(name) && !hasText), DOM_UPDATE_ANIMATION_CLASS_NAME)}
|
|
828
|
-
|
|
829
|
-
|
|
852
|
+
${animateOn(Boolean(updateRecord?.isAttributeModified(name) && !hasText), DOM_UPDATE_ANIMATION_CLASS_NAME)}>${
|
|
853
|
+
linkifyName && relationPromise ? Lit.Directives.until(relationPromise, name) : name}</span>${
|
|
854
|
+
hasText ?
|
|
855
|
+
html`=\u200B"<span class="webkit-html-attribute-value" ${
|
|
856
|
+
animateOn(Boolean(updateRecord?.isAttributeModified(name) && hasText),
|
|
857
|
+
DOM_UPDATE_ANIMATION_CLASS_NAME)} ${withEntitiesRef}>
|
|
830
858
|
${valueType === ValueType.SRC ? renderLinkifiedValue(value, node) : nothing}
|
|
831
|
-
${
|
|
859
|
+
${
|
|
860
|
+
valueType === ValueType.SRCSET ? renderLinkifiedSrcset(Common.Srcset.parseSrcset(value), node) : nothing}
|
|
861
|
+
${linkifyValue && relationPromise ? Lit.Directives.until(relationPromise, value) : nothing}
|
|
832
862
|
</span>"` :
|
|
833
|
-
|
|
834
|
-
// clang-format on
|
|
863
|
+
nothing}</span>`;
|
|
835
864
|
}
|
|
836
865
|
|
|
837
866
|
function renderTag(
|
|
@@ -2440,9 +2469,20 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
|
|
|
2440
2469
|
}
|
|
2441
2470
|
}
|
|
2442
2471
|
|
|
2443
|
-
|
|
2472
|
+
let attributeValue = attributeName && attributeValueElement ?
|
|
2444
2473
|
this.nodeInternal.getAttribute(attributeName)?.replaceAll('"', '"') :
|
|
2445
2474
|
undefined;
|
|
2475
|
+
|
|
2476
|
+
const isRelation =
|
|
2477
|
+
attributeName === 'popovertarget' || attributeName === 'interesttarget' || attributeName === 'commandfor';
|
|
2478
|
+
if (isRelation && attributeName && attributeValueElement) {
|
|
2479
|
+
const rawValue = this.nodeInternal.getAttribute(attributeName) || '';
|
|
2480
|
+
const relatedElement = relatedElementsCache.get(this.nodeInternal)?.get(`${attributeName}:${rawValue}`);
|
|
2481
|
+
if (relatedElement) {
|
|
2482
|
+
attributeValue = relatedElement.getAttribute('id') || '';
|
|
2483
|
+
}
|
|
2484
|
+
}
|
|
2485
|
+
|
|
2446
2486
|
if (attributeValue !== undefined) {
|
|
2447
2487
|
attributeValueElement.setTextContentTruncatedIfNeeded(
|
|
2448
2488
|
attributeValue, i18nString(UIStrings.valueIsTooLargeToEdit));
|
|
@@ -136,6 +136,11 @@ const UIStrings = {
|
|
|
136
136
|
* detached DOM nodes and other objects kept alive by detached DOM nodes
|
|
137
137
|
*/
|
|
138
138
|
objectsRetainedByDetachedDomNodes: 'Objects retained by detached DOM nodes',
|
|
139
|
+
/**
|
|
140
|
+
* @description An option which will filter the heap snapshot to show only
|
|
141
|
+
* objects kept alive by contexts
|
|
142
|
+
*/
|
|
143
|
+
objectsRetainedByContexts: 'Objects retained by contexts',
|
|
139
144
|
/**
|
|
140
145
|
* @description An option which will filter the heap snapshot to show only
|
|
141
146
|
* objects kept alive by the DevTools console
|
|
@@ -773,6 +778,7 @@ export class HeapSnapshotView extends UI.View.SimpleView implements DataDisplayD
|
|
|
773
778
|
static readonly ALWAYS_AVAILABLE_FILTERS: ReadonlyArray<{uiName: string, filterName: string}> = [
|
|
774
779
|
{uiName: i18nString(UIStrings.duplicatedStrings), filterName: 'duplicatedStrings'},
|
|
775
780
|
{uiName: i18nString(UIStrings.objectsRetainedByDetachedDomNodes), filterName: 'objectsRetainedByDetachedDomNodes'},
|
|
781
|
+
{uiName: i18nString(UIStrings.objectsRetainedByContexts), filterName: 'objectsRetainedByContexts'},
|
|
776
782
|
{uiName: i18nString(UIStrings.objectsRetainedByConsole), filterName: 'objectsRetainedByConsole'},
|
|
777
783
|
{uiName: i18nString(UIStrings.objectsRetainedByEventHandlers), filterName: 'objectsRetainedByEventHandlers'},
|
|
778
784
|
];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Name: Dependencies sourced from the upstream `chromium` repository
|
|
2
2
|
URL: Internal
|
|
3
3
|
Version: N/A
|
|
4
|
-
Revision:
|
|
4
|
+
Revision: 497ce88cb71102650c4ed3ec5fa40ddd45c28c26
|
|
5
5
|
Update Mechanism: Manual (https://crbug.com/428069060)
|
|
6
6
|
License: BSD-3-Clause
|
|
7
7
|
License File: LICENSE
|
|
@@ -257,6 +257,7 @@ export class SourceFrameImpl extends Common.ObjectWrapper.eventMixin<EventTypes,
|
|
|
257
257
|
focus: () => this.onFocus(),
|
|
258
258
|
blur: () => this.onBlur(),
|
|
259
259
|
paste: () => this.onPaste(),
|
|
260
|
+
drop: event => event.preventDefault(),
|
|
260
261
|
scroll: () => this.dispatchEventToListeners(Events.EDITOR_SCROLL),
|
|
261
262
|
contextmenu: event => this.onContextMenu(event),
|
|
262
263
|
}),
|
|
@@ -264,16 +265,15 @@ export class SourceFrameImpl extends Common.ObjectWrapper.eventMixin<EventTypes,
|
|
|
264
265
|
domEventHandlers:
|
|
265
266
|
{contextmenu: (_view, block, event) => this.onLineGutterContextMenu(block.from, event as MouseEvent)},
|
|
266
267
|
}),
|
|
267
|
-
CodeMirror.EditorView.updateListener.of(
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
}),
|
|
268
|
+
CodeMirror.EditorView.updateListener.of((update):
|
|
269
|
+
void => {
|
|
270
|
+
if (update.selectionSet || update.docChanged) {
|
|
271
|
+
this.updateSourcePosition();
|
|
272
|
+
}
|
|
273
|
+
if (update.docChanged) {
|
|
274
|
+
this.onTextChanged();
|
|
275
|
+
}
|
|
276
|
+
}),
|
|
277
277
|
activeSearchState,
|
|
278
278
|
CodeMirror.Prec.lowest(searchHighlighter),
|
|
279
279
|
config.language.of([]),
|