chrome-devtools-frontend 1.0.1682249 → 1.0.1684555
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/AUTHORS +1 -0
- package/front_end/core/sdk/ServiceWorkerCacheModel.ts +0 -7
- package/front_end/core/sdk/StorageBucketsModel.ts +0 -6
- package/front_end/entrypoints/inspector_main/InspectorMain.ts +2 -1
- package/front_end/entrypoints/inspector_main/inspector_main-meta.ts +1 -5
- package/front_end/entrypoints/main/MainImpl.ts +6 -4
- package/front_end/entrypoints/main/main-meta.ts +9 -51
- package/front_end/foundation/Universe.ts +7 -0
- package/front_end/generated/InspectorBackendCommands.ts +12 -22
- package/front_end/generated/protocol-mapping.d.ts +9 -59
- package/front_end/generated/protocol-proxy-api.d.ts +7 -47
- package/front_end/generated/protocol.ts +105 -330
- package/front_end/models/ai_assistance/AiAgent2.ts +12 -4
- package/front_end/models/ai_assistance/AiConversation.ts +25 -7
- package/front_end/models/ai_assistance/agents/AiAgent.ts +11 -19
- package/front_end/models/ai_assistance/agents/StorageAgent.ts +6 -6
- package/front_end/models/ai_assistance/ai_assistance.ts +4 -0
- package/front_end/models/ai_assistance/tools/GetLighthouseAudits.ts +12 -6
- package/front_end/models/ai_assistance/tools/GetStorageValues.ts +1 -1
- package/front_end/models/ai_assistance/tools/ListStorageKeys.ts +1 -1
- package/front_end/models/ai_assistance/tools/RunLighthouse.ts +5 -8
- package/front_end/models/ai_assistance/tools/Tool.ts +19 -6
- package/front_end/models/issues_manager/DOMIssuesManager.ts +144 -0
- package/front_end/models/issues_manager/ElementAccessibilityIssue.ts +13 -1
- package/front_end/models/issues_manager/GenericIssue.ts +14 -2
- package/front_end/models/issues_manager/IssuesManager.ts +0 -1
- package/front_end/models/issues_manager/issues_manager.ts +2 -0
- package/front_end/models/javascript_metadata/NativeFunctions.js +8 -0
- package/front_end/models/trace/Processor.ts +1 -0
- package/front_end/panels/ai_assistance/ExternalHandler.ts +89 -0
- package/front_end/panels/ai_assistance/ai_assistance.ts +1 -0
- package/front_end/panels/application/BackgroundServiceModel.ts +4 -3
- package/front_end/panels/application/IndexedDBModel.ts +0 -7
- package/front_end/panels/console/ConsoleView.ts +17 -16
- package/front_end/panels/console/ConsoleViewMessage.ts +4 -1
- package/front_end/panels/console/console-meta.ts +4 -19
- package/front_end/panels/elements/ElementIssueUtils.ts +10 -2
- package/front_end/panels/elements/ElementsPanel.ts +8 -3
- package/front_end/panels/elements/ElementsTreeElement.ts +82 -161
- package/front_end/panels/elements/ElementsTreeOutline.ts +26 -105
- package/front_end/panels/elements/StandaloneStylesContainer.ts +5 -11
- package/front_end/panels/elements/StylePropertyTreeElement.ts +2 -0
- package/front_end/panels/elements/StylesContainer.ts +1 -0
- package/front_end/panels/elements/StylesSidebarPane.ts +174 -151
- package/front_end/panels/network/RequestPayloadView.ts +5 -2
- package/front_end/panels/security/SecurityPanelSidebar.ts +0 -32
- package/front_end/panels/settings/KeybindsSettingsTab.ts +5 -2
- package/front_end/panels/sources/SourcesPanel.ts +6 -3
- package/front_end/panels/timeline/components/BreadcrumbsUI.ts +2 -6
- package/front_end/panels/timeline/components/CWVMetrics.ts +9 -10
- package/front_end/panels/timeline/components/DetailsView.ts +12 -16
- package/front_end/panels/timeline/components/ExportTraceOptions.ts +13 -13
- package/front_end/panels/timeline/components/FieldSettingsDialog.ts +19 -19
- package/front_end/panels/timeline/components/IgnoreListSetting.ts +7 -9
- package/front_end/panels/timeline/components/InteractionBreakdown.ts +3 -3
- package/front_end/panels/timeline/components/LayoutShiftDetails.ts +13 -13
- package/front_end/panels/timeline/components/LiveMetricsView.ts +64 -64
- package/front_end/panels/timeline/components/MetricCard.ts +25 -25
- package/front_end/panels/timeline/components/NetworkRequestDetails.ts +22 -22
- package/front_end/panels/timeline/components/NetworkRequestTooltip.ts +9 -9
- package/front_end/panels/timeline/components/OriginMap.ts +7 -7
- package/front_end/panels/timeline/components/RelatedInsightChips.ts +2 -2
- package/front_end/panels/timeline/components/SidebarAnnotationsTab.ts +19 -20
- package/front_end/panels/timeline/components/SidebarSingleInsightSet.ts +1 -1
- package/front_end/panels/timeline/components/TimelineSummary.ts +2 -2
- package/front_end/panels/timeline/components/Utils.ts +2 -6
- package/front_end/panels/timeline/components/insights/BaseInsightComponent.ts +6 -9
- package/front_end/panels/timeline/components/insights/Checklist.ts +2 -2
- package/front_end/panels/timeline/components/insights/Table.ts +1 -1
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/ui/comments/CommentAnchorResolver.ts +94 -0
- package/front_end/ui/comments/CommentOverlayManager.ts +16 -32
- package/front_end/ui/components/text_editor/config.ts +2 -1
- package/front_end/ui/legacy/DockController.ts +4 -1
- package/front_end/ui/legacy/InspectorView.ts +3 -1
- package/front_end/ui/legacy/KeyboardShortcut.ts +4 -7
- package/front_end/ui/legacy/SearchableView.ts +2 -1
- package/front_end/ui/legacy/ShortcutRegistry.ts +6 -3
- package/front_end/ui/legacy/UIUtils.ts +10 -6
- package/front_end/ui/legacy/components/cookie_table/CookiesTable.ts +23 -24
- package/front_end/ui/legacy/components/perf_ui/BrickBreaker.ts +2 -2
- package/front_end/ui/legacy/components/perf_ui/FilmStripView.ts +6 -6
- package/front_end/ui/legacy/components/perf_ui/FlameChart.ts +14 -15
- package/front_end/ui/legacy/components/perf_ui/GCActionDelegate.ts +1 -1
- package/front_end/ui/legacy/components/perf_ui/NetworkPriorities.ts +5 -5
- package/front_end/ui/legacy/components/perf_ui/OverviewGrid.ts +5 -5
- package/front_end/ui/legacy/components/perf_ui/PieChart.ts +1 -1
- package/front_end/ui/legacy/components/perf_ui/perf_ui-meta.ts +4 -6
- package/front_end/ui/legacy/components/source_frame/FontView.ts +2 -2
- package/front_end/ui/legacy/components/source_frame/ImageView.ts +13 -13
- package/front_end/ui/legacy/components/source_frame/JSONView.ts +1 -1
- package/front_end/ui/legacy/components/source_frame/PreviewFactory.ts +2 -2
- package/front_end/ui/legacy/components/source_frame/ResourceSourceFrame.ts +1 -1
- package/front_end/ui/legacy/components/source_frame/SourceFrame.ts +15 -18
- package/front_end/ui/legacy/components/source_frame/XMLView.ts +1 -1
- package/front_end/ui/legacy/components/source_frame/source_frame-meta.ts +10 -10
- package/front_end/ui/legacy/theme_support/ThemeSupport.ts +5 -2
- package/front_end/ui/settings/ConsoleSettings.ts +32 -0
- package/front_end/ui/settings/InspectorMainSettings.ts +7 -0
- package/front_end/ui/settings/MainSettings.ts +80 -0
- package/front_end/ui/settings/settings.ts +4 -0
- package/front_end/ui/visual_logging/KnownContextValues.ts +8 -0
- package/package.json +1 -1
|
@@ -202,7 +202,7 @@ export class StorageAgent extends AiAgent<StorageItem> {
|
|
|
202
202
|
},
|
|
203
203
|
|
|
204
204
|
handler: async args => {
|
|
205
|
-
this.
|
|
205
|
+
this.disableServerSideLogging();
|
|
206
206
|
if (!isSamePrimaryPageOrigin(this.targetManager, this.context)) {
|
|
207
207
|
return {error: 'No origin available or not allowed.'};
|
|
208
208
|
}
|
|
@@ -288,7 +288,7 @@ export class StorageAgent extends AiAgent<StorageItem> {
|
|
|
288
288
|
},
|
|
289
289
|
|
|
290
290
|
handler: async (args, options) => {
|
|
291
|
-
this.
|
|
291
|
+
this.disableServerSideLogging();
|
|
292
292
|
if (!isSamePrimaryPageOrigin(this.targetManager, this.context)) {
|
|
293
293
|
return {error: 'No origin available or not allowed.'};
|
|
294
294
|
}
|
|
@@ -388,7 +388,7 @@ export class StorageAgent extends AiAgent<StorageItem> {
|
|
|
388
388
|
};
|
|
389
389
|
},
|
|
390
390
|
handler: async args => {
|
|
391
|
-
this.
|
|
391
|
+
this.disableServerSideLogging();
|
|
392
392
|
if (!isSamePrimaryPageOrigin(this.targetManager, this.context)) {
|
|
393
393
|
return {error: 'No origin available or not allowed.'};
|
|
394
394
|
}
|
|
@@ -448,7 +448,7 @@ export class StorageAgent extends AiAgent<StorageItem> {
|
|
|
448
448
|
};
|
|
449
449
|
},
|
|
450
450
|
handler: async (args, options) => {
|
|
451
|
-
this.
|
|
451
|
+
this.disableServerSideLogging();
|
|
452
452
|
if (!isSamePrimaryPageOrigin(this.targetManager, this.context)) {
|
|
453
453
|
return {error: 'No origin available or not allowed.'};
|
|
454
454
|
}
|
|
@@ -618,9 +618,9 @@ export class StorageAgent extends AiAgent<StorageItem> {
|
|
|
618
618
|
protected override async preRun(): Promise<void> {
|
|
619
619
|
const item = this.context?.getItem();
|
|
620
620
|
if (item instanceof CookieItem && Boolean(item.name)) {
|
|
621
|
-
this.
|
|
621
|
+
this.disableServerSideLogging();
|
|
622
622
|
} else if (item instanceof DOMStorageItem && Boolean(item.key)) {
|
|
623
|
-
this.
|
|
623
|
+
this.disableServerSideLogging();
|
|
624
624
|
}
|
|
625
625
|
}
|
|
626
626
|
|
|
@@ -38,6 +38,8 @@ import * as AICallTree from './performance/AICallTree.js';
|
|
|
38
38
|
import * as AIContext from './performance/AIContext.js';
|
|
39
39
|
import * as AIQueries from './performance/AIQueries.js';
|
|
40
40
|
import * as PerformanceAnnotations from './PerformanceAnnotations.js';
|
|
41
|
+
import * as Skill from './skills/Skill.js';
|
|
42
|
+
import * as SkillRegistry from './skills/SkillRegistry.js';
|
|
41
43
|
import * as StorageItem from './StorageItem.js';
|
|
42
44
|
import * as DOMStorageUtils from './tools/DOMStorageUtils.js';
|
|
43
45
|
import * as ExecuteJavaScript from './tools/ExecuteJavaScript.js';
|
|
@@ -122,6 +124,8 @@ export {
|
|
|
122
124
|
ResolveDevtoolsNodePath,
|
|
123
125
|
RunLighthouse,
|
|
124
126
|
SelectTraceEventByKey,
|
|
127
|
+
Skill,
|
|
128
|
+
SkillRegistry,
|
|
125
129
|
StorageAgent,
|
|
126
130
|
StorageContext,
|
|
127
131
|
StorageItem,
|
|
@@ -4,17 +4,23 @@
|
|
|
4
4
|
|
|
5
5
|
import * as Host from '../../../core/host/host.js';
|
|
6
6
|
import type * as LHModel from '../../lighthouse/lighthouse.js';
|
|
7
|
-
import {AccessibilityContext} from '../contexts/AccessibilityContext.js';
|
|
8
7
|
import {LighthouseFormatter} from '../data_formatters/LighthouseFormatter.js';
|
|
9
8
|
|
|
10
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
type BaseToolCapability,
|
|
11
|
+
type DataHandlerResult,
|
|
12
|
+
type DataTool,
|
|
13
|
+
type LighthouseReportCapability,
|
|
14
|
+
type ToolArgs,
|
|
15
|
+
ToolName,
|
|
16
|
+
} from './Tool.js';
|
|
11
17
|
|
|
12
18
|
export interface GetLighthouseAuditsArgs extends ToolArgs {
|
|
13
19
|
categoryId: LHModel.RunTypes.CategoryId;
|
|
14
20
|
}
|
|
15
21
|
|
|
16
22
|
export class GetLighthouseAuditsTool implements
|
|
17
|
-
DataTool<GetLighthouseAuditsArgs, {audits: string}, BaseToolCapability> {
|
|
23
|
+
DataTool<GetLighthouseAuditsArgs, {audits: string}, BaseToolCapability&LighthouseReportCapability> {
|
|
18
24
|
readonly name = ToolName.GET_LIGHTHOUSE_AUDITS;
|
|
19
25
|
readonly description = 'Returns the audits for a specific Lighthouse category.';
|
|
20
26
|
|
|
@@ -40,11 +46,11 @@ export class GetLighthouseAuditsTool implements
|
|
|
40
46
|
}
|
|
41
47
|
|
|
42
48
|
async handler(params: GetLighthouseAuditsArgs,
|
|
43
|
-
context: BaseToolCapability): Promise<DataHandlerResult<{audits: string}>> {
|
|
44
|
-
|
|
49
|
+
context: BaseToolCapability&LighthouseReportCapability): Promise<DataHandlerResult<{audits: string}>> {
|
|
50
|
+
const report = context.getLighthouseReport();
|
|
51
|
+
if (!report) {
|
|
45
52
|
return {error: 'Error: Active context is not a Lighthouse report.'};
|
|
46
53
|
}
|
|
47
|
-
const report = context.conversationContext.getItem();
|
|
48
54
|
const audits = new LighthouseFormatter().audits(report, params.categoryId);
|
|
49
55
|
return {
|
|
50
56
|
result: {audits},
|
|
@@ -97,7 +97,7 @@ export class GetStorageValuesTool implements DataTool<GetStorageValuesArgs, GetS
|
|
|
97
97
|
context: BaseToolCapability&OriginLockCapability&ServerLoggingCapability,
|
|
98
98
|
options?: FunctionHandlerOptions,
|
|
99
99
|
): Promise<DataHandlerResult<GetStorageValuesResult>> {
|
|
100
|
-
context.
|
|
100
|
+
context.disableLogging();
|
|
101
101
|
|
|
102
102
|
// eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
|
|
103
103
|
const targetManager = SDK.TargetManager.TargetManager.instance();
|
|
@@ -84,7 +84,7 @@ export class ListStorageKeysTool implements DataTool<ListStorageKeysArgs, ListSt
|
|
|
84
84
|
args: ListStorageKeysArgs,
|
|
85
85
|
context: BaseToolCapability&OriginLockCapability&ServerLoggingCapability,
|
|
86
86
|
): Promise<DataHandlerResult<ListStorageKeysResult>> {
|
|
87
|
-
context.
|
|
87
|
+
context.disableLogging();
|
|
88
88
|
|
|
89
89
|
// eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
|
|
90
90
|
const targetManager = SDK.TargetManager.TargetManager.instance();
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
type BaseToolCapability,
|
|
11
11
|
type DataHandlerResult,
|
|
12
12
|
type DataTool,
|
|
13
|
-
type
|
|
13
|
+
type LighthouseRecordingCapability,
|
|
14
14
|
type ToolArgs,
|
|
15
15
|
ToolName,
|
|
16
16
|
} from './Tool.js';
|
|
@@ -22,7 +22,7 @@ export interface RunLighthouseArgs extends ToolArgs {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
export class RunLighthouseTool implements
|
|
25
|
-
DataTool<RunLighthouseArgs, {audits: string}, BaseToolCapability&
|
|
25
|
+
DataTool<RunLighthouseArgs, {audits: string}, BaseToolCapability&LighthouseRecordingCapability> {
|
|
26
26
|
readonly name = ToolName.RUN_LIGHTHOUSE;
|
|
27
27
|
readonly description =
|
|
28
28
|
'Runs Lighthouse audits on the active page. Supports "navigation" (for full initial page load audits), "snapshot" (for inspecting live in-page modifications without reload), and "timespan" (for interactions).';
|
|
@@ -60,14 +60,11 @@ export class RunLighthouseTool implements
|
|
|
60
60
|
};
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
async handler(params: RunLighthouseArgs,
|
|
64
|
-
|
|
65
|
-
if (!context.lighthouseRecording) {
|
|
66
|
-
return {error: 'Error: Lighthouse recording capability is not available.'};
|
|
67
|
-
}
|
|
63
|
+
async handler(params: RunLighthouseArgs, context: BaseToolCapability&LighthouseRecordingCapability):
|
|
64
|
+
Promise<DataHandlerResult<{audits: string}>> {
|
|
68
65
|
const mode = params.mode ?? 'snapshot';
|
|
69
66
|
try {
|
|
70
|
-
const report = await context.
|
|
67
|
+
const report = await context.runLighthouse({
|
|
71
68
|
mode,
|
|
72
69
|
categoryIds: [params.category],
|
|
73
70
|
isAIControlled: true,
|
|
@@ -122,10 +122,17 @@ export interface OriginLockCapability {
|
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
/**
|
|
125
|
-
* Capability for tools that need to
|
|
125
|
+
* Capability for tools that need to inspect an active Lighthouse report from context.
|
|
126
126
|
*/
|
|
127
|
-
export interface
|
|
128
|
-
|
|
127
|
+
export interface LighthouseReportCapability {
|
|
128
|
+
getLighthouseReport(): LHModel.ReporterTypes.ReportJSON|null;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Capability for tools that trigger new Lighthouse audit runs.
|
|
133
|
+
*/
|
|
134
|
+
export interface LighthouseRecordingCapability {
|
|
135
|
+
runLighthouse(overrides?: LHModel.RunTypes.RunOverrides): Promise<LHModel.ReporterTypes.ReportJSON|null>;
|
|
129
136
|
}
|
|
130
137
|
|
|
131
138
|
/**
|
|
@@ -139,8 +146,9 @@ export interface PerformanceRecordingCapability {
|
|
|
139
146
|
* Unified context interface providing all capabilities available in the project.
|
|
140
147
|
* Used by the agent to pass a complete context to any tool type-safely.
|
|
141
148
|
*/
|
|
142
|
-
export type AllToolsCapabilities =
|
|
143
|
-
|
|
149
|
+
export type AllToolsCapabilities =
|
|
150
|
+
BaseToolCapability&PageExecutionCapability&StyleMutationCapability&TargetCapability&OriginLockCapability&
|
|
151
|
+
LighthouseReportCapability&LighthouseRecordingCapability&PerformanceRecordingCapability&ServerLoggingCapability;
|
|
144
152
|
|
|
145
153
|
/**
|
|
146
154
|
* Base argument type for AI Tools.
|
|
@@ -263,8 +271,13 @@ export type Tool<
|
|
|
263
271
|
CapabilitiesType extends BaseToolCapability = BaseToolCapability,
|
|
264
272
|
> = DataTool<ArgsType, ReturnType, CapabilitiesType>|ContextTool<ArgsType, ReturnType, CapabilitiesType>;
|
|
265
273
|
|
|
274
|
+
/**
|
|
275
|
+
* Capability provided to tools that handle sensitive user data (e.g. cookies or storage values).
|
|
276
|
+
* Calling `disableLogging()` irreversibly disables server-side logging for the remainder of
|
|
277
|
+
* the conversation session to prevent sensitive data from being logged on future turns.
|
|
278
|
+
*/
|
|
266
279
|
export interface ServerLoggingCapability {
|
|
267
|
-
|
|
280
|
+
disableLogging(): void;
|
|
268
281
|
}
|
|
269
282
|
|
|
270
283
|
export const enum ToolAnnotation {
|
|
@@ -0,0 +1,144 @@
|
|
|
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 * as Common from '../../core/common/common.js';
|
|
6
|
+
import * as Platform from '../../core/platform/platform.js';
|
|
7
|
+
import * as SDK from '../../core/sdk/sdk.js';
|
|
8
|
+
import type * as Protocol from '../../generated/protocol.js';
|
|
9
|
+
|
|
10
|
+
import type {Issue} from './Issue.js';
|
|
11
|
+
import type {IssueAddedEvent, IssueHiddenStatusUpdatedEvent, IssuesManager} from './IssuesManager.js';
|
|
12
|
+
import {Events as IssuesManagerEvents} from './IssuesManagerEvents.js';
|
|
13
|
+
|
|
14
|
+
export const enum Events {
|
|
15
|
+
DOM_ISSUE_ADDED = 'DOMIssueAdded',
|
|
16
|
+
DOM_ISSUE_REMOVED = 'DOMIssueRemoved',
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface EventTypes {
|
|
20
|
+
[Events.DOM_ISSUE_ADDED]: {node: SDK.DOMModel.DOMNode, issue: Issue};
|
|
21
|
+
[Events.DOM_ISSUE_REMOVED]: {node: SDK.DOMModel.DOMNode, issue: Issue};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export class DOMIssuesManager extends Common.ObjectWrapper.ObjectWrapper<EventTypes> {
|
|
25
|
+
readonly #issuesManager: IssuesManager;
|
|
26
|
+
readonly #targetManager: SDK.TargetManager.TargetManager;
|
|
27
|
+
#currentIssues = new Set<Issue>();
|
|
28
|
+
#nodeToIssues = new Platform.MapUtilities.Multimap<SDK.DOMModel.DOMNode, Issue>();
|
|
29
|
+
readonly #nodeIdSubscribers = new Platform.MapUtilities.Multimap<Protocol.DOM.NodeId, () => void>();
|
|
30
|
+
|
|
31
|
+
constructor(issuesManager: IssuesManager, targetManager: SDK.TargetManager.TargetManager) {
|
|
32
|
+
super();
|
|
33
|
+
this.#issuesManager = issuesManager;
|
|
34
|
+
this.#targetManager = targetManager;
|
|
35
|
+
this.#issuesManager.addEventListener(IssuesManagerEvents.ISSUE_ADDED, this.#onIssueAdded, this);
|
|
36
|
+
this.#issuesManager.addEventListener(IssuesManagerEvents.ISSUE_HIDDEN_STATUS_UPDATED,
|
|
37
|
+
this.#onIssueHiddenStatusUpdated, this);
|
|
38
|
+
this.#issuesManager.addEventListener(IssuesManagerEvents.FULL_UPDATE_REQUIRED, this.#onFullUpdateRequired, this);
|
|
39
|
+
this.#targetManager.addModelListener(SDK.DOMModel.DOMModel, SDK.DOMModel.Events.DocumentUpdated,
|
|
40
|
+
this.#onDocumentUpdated, this, {scoped: true});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
subscribeByNodeId(nodeId: Protocol.DOM.NodeId, callback: () => void): void {
|
|
44
|
+
this.#nodeIdSubscribers.set(nodeId, callback);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
unsubscribeByNodeId(nodeId: Protocol.DOM.NodeId, callback: () => void): void {
|
|
48
|
+
this.#nodeIdSubscribers.delete(nodeId, callback);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
issuesForNode(node: SDK.DOMModel.DOMNode): Issue[] {
|
|
52
|
+
return Array.from(this.#nodeToIssues.get(node));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
#onIssueAdded(event: Common.EventTarget.EventTargetEvent<IssueAddedEvent>): void {
|
|
56
|
+
void this.#addIssue(event.data.issue);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
#onIssueHiddenStatusUpdated(event: Common.EventTarget.EventTargetEvent<IssueHiddenStatusUpdatedEvent>): void {
|
|
60
|
+
const {issue} = event.data;
|
|
61
|
+
if (issue.isHidden()) {
|
|
62
|
+
void this.#removeIssue(issue);
|
|
63
|
+
} else {
|
|
64
|
+
void this.#addIssue(issue);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
#onFullUpdateRequired(): void {
|
|
69
|
+
const newIssues = new Set(this.#issuesManager.issues());
|
|
70
|
+
for (const issue of this.#currentIssues) {
|
|
71
|
+
if (!newIssues.has(issue) || issue.isHidden()) {
|
|
72
|
+
void this.#removeIssue(issue);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
for (const issue of newIssues) {
|
|
76
|
+
if (!issue.isHidden()) {
|
|
77
|
+
void this.#addIssue(issue);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
#onDocumentUpdated(_event: Common.EventTarget.EventTargetEvent<SDK.DOMModel.DOMModel>): void {
|
|
83
|
+
this.#nodeToIssues.clear();
|
|
84
|
+
for (const issue of this.#issuesManager.issues()) {
|
|
85
|
+
if (!issue.isHidden()) {
|
|
86
|
+
void this.#addIssue(issue);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async #resolveNodesForIssue(issue: Issue): Promise<SDK.DOMModel.DOMNode[]> {
|
|
92
|
+
const primaryTarget = this.#targetManager.primaryPageTarget() ?? this.#targetManager.targets()[0];
|
|
93
|
+
const nodes: SDK.DOMModel.DOMNode[] = [];
|
|
94
|
+
for (const element of issue.elements()) {
|
|
95
|
+
const elementTarget = (element.target && typeof (element.target as SDK.Target.Target).model === 'function') ?
|
|
96
|
+
(element.target as SDK.Target.Target) :
|
|
97
|
+
primaryTarget;
|
|
98
|
+
if (!elementTarget) {
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
const domModel = elementTarget.model(SDK.DOMModel.DOMModel);
|
|
102
|
+
if (!domModel) {
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
const deferredDOMNode = new SDK.DOMModel.DeferredDOMNode(elementTarget, element.backendNodeId);
|
|
106
|
+
const node = await deferredDOMNode.resolvePromise();
|
|
107
|
+
if (node) {
|
|
108
|
+
nodes.push(node);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return nodes;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async #addIssue(issue: Issue): Promise<void> {
|
|
115
|
+
if (issue.isHidden()) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
this.#currentIssues.add(issue);
|
|
119
|
+
const nodes = await this.#resolveNodesForIssue(issue);
|
|
120
|
+
for (const node of nodes) {
|
|
121
|
+
if (!this.#nodeToIssues.hasValue(node, issue)) {
|
|
122
|
+
this.#nodeToIssues.set(node, issue);
|
|
123
|
+
this.dispatchEventToListeners(Events.DOM_ISSUE_ADDED, {node, issue});
|
|
124
|
+
for (const callback of this.#nodeIdSubscribers.get(node.id)) {
|
|
125
|
+
callback();
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
async #removeIssue(issue: Issue): Promise<void> {
|
|
132
|
+
this.#currentIssues.delete(issue);
|
|
133
|
+
const nodes = await this.#resolveNodesForIssue(issue);
|
|
134
|
+
for (const node of nodes) {
|
|
135
|
+
if (this.#nodeToIssues.hasValue(node, issue)) {
|
|
136
|
+
this.#nodeToIssues.delete(node, issue);
|
|
137
|
+
this.dispatchEventToListeners(Events.DOM_ISSUE_REMOVED, {node, issue});
|
|
138
|
+
for (const callback of this.#nodeIdSubscribers.get(node.id)) {
|
|
139
|
+
callback();
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import type * as SDK from '../../core/sdk/sdk.js';
|
|
6
6
|
import * as Protocol from '../../generated/protocol.js';
|
|
7
7
|
|
|
8
|
-
import {Issue, IssueCategory, IssueKind} from './Issue.js';
|
|
8
|
+
import {type AffectedElement, Issue, IssueCategory, IssueKind} from './Issue.js';
|
|
9
9
|
import {
|
|
10
10
|
type LazyMarkdownIssueDescription,
|
|
11
11
|
type MarkdownIssueDescription,
|
|
@@ -23,6 +23,18 @@ export class ElementAccessibilityIssue extends Issue<Protocol.Audits.ElementAcce
|
|
|
23
23
|
super(issueCode, issueDetails, issuesModel, issueId);
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
override elements(): Iterable<AffectedElement> {
|
|
27
|
+
const details = this.details();
|
|
28
|
+
if (details.nodeId) {
|
|
29
|
+
return [{
|
|
30
|
+
backendNodeId: details.nodeId,
|
|
31
|
+
nodeName: '',
|
|
32
|
+
target: this.model()?.target() ?? null,
|
|
33
|
+
}];
|
|
34
|
+
}
|
|
35
|
+
return [];
|
|
36
|
+
}
|
|
37
|
+
|
|
26
38
|
primaryKey(): string {
|
|
27
39
|
return JSON.stringify(this.details());
|
|
28
40
|
}
|
|
@@ -6,11 +6,11 @@ import * as i18n from '../../core/i18n/i18n.js';
|
|
|
6
6
|
import type * as SDK from '../../core/sdk/sdk.js';
|
|
7
7
|
import * as Protocol from '../../generated/protocol.js';
|
|
8
8
|
|
|
9
|
-
import {Issue, IssueCategory, IssueKind} from './Issue.js';
|
|
9
|
+
import {type AffectedElement, Issue, IssueCategory, IssueKind} from './Issue.js';
|
|
10
10
|
import {
|
|
11
|
-
resolveLazyDescription,
|
|
12
11
|
type LazyMarkdownIssueDescription,
|
|
13
12
|
type MarkdownIssueDescription,
|
|
13
|
+
resolveLazyDescription,
|
|
14
14
|
} from './MarkdownIssueDescription.js';
|
|
15
15
|
|
|
16
16
|
const UIStrings = {
|
|
@@ -72,6 +72,18 @@ export class GenericIssue extends Issue<Protocol.Audits.GenericIssueDetails> {
|
|
|
72
72
|
return [];
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
+
override elements(): Iterable<AffectedElement> {
|
|
76
|
+
const details = this.details();
|
|
77
|
+
if (details.violatingNodeId) {
|
|
78
|
+
return [{
|
|
79
|
+
backendNodeId: details.violatingNodeId,
|
|
80
|
+
nodeName: '',
|
|
81
|
+
target: this.model()?.target() ?? null,
|
|
82
|
+
}];
|
|
83
|
+
}
|
|
84
|
+
return [];
|
|
85
|
+
}
|
|
86
|
+
|
|
75
87
|
getCategory(): IssueCategory {
|
|
76
88
|
return IssueCategory.GENERIC;
|
|
77
89
|
}
|
|
@@ -233,7 +233,6 @@ export class IssuesManager extends Common.ObjectWrapper.ObjectWrapper<EventTypes
|
|
|
233
233
|
#issuesByOutermostTarget: WeakMap<SDK.Target.Target, Set<Issue>> = new Map();
|
|
234
234
|
#frameManager: SDK.FrameManager.FrameManager;
|
|
235
235
|
#targetManager: SDK.TargetManager.TargetManager;
|
|
236
|
-
|
|
237
236
|
constructor(
|
|
238
237
|
private readonly showThirdPartyIssuesSetting?: Common.Settings.Setting<boolean>,
|
|
239
238
|
private readonly hideIssueSetting?: Common.Settings.Setting<HideIssueMenuSetting>,
|
|
@@ -10,6 +10,7 @@ import * as CookieIssue from './CookieIssue.js';
|
|
|
10
10
|
import * as CorsIssue from './CorsIssue.js';
|
|
11
11
|
import * as CrossOriginEmbedderPolicyIssue from './CrossOriginEmbedderPolicyIssue.js';
|
|
12
12
|
import * as DeprecationIssue from './DeprecationIssue.js';
|
|
13
|
+
import * as DOMIssuesManager from './DOMIssuesManager.js';
|
|
13
14
|
import * as ElementAccessibilityIssue from './ElementAccessibilityIssue.js';
|
|
14
15
|
import * as EmailVerificationRequestIssue from './EmailVerificationRequestIssue.js';
|
|
15
16
|
import * as FederatedAuthRequestIssue from './FederatedAuthRequestIssue.js';
|
|
@@ -45,6 +46,7 @@ export {
|
|
|
45
46
|
CorsIssue,
|
|
46
47
|
CrossOriginEmbedderPolicyIssue,
|
|
47
48
|
DeprecationIssue,
|
|
49
|
+
DOMIssuesManager,
|
|
48
50
|
ElementAccessibilityIssue,
|
|
49
51
|
EmailVerificationRequestIssue,
|
|
50
52
|
FederatedAuthRequestIssue,
|
|
@@ -6718,6 +6718,10 @@ export const NativeFunctions = [
|
|
|
6718
6718
|
name: "copyElementImageToTexture",
|
|
6719
6719
|
signatures: [["source","destination"]]
|
|
6720
6720
|
},
|
|
6721
|
+
{
|
|
6722
|
+
name: "drawElementImageToTexture",
|
|
6723
|
+
signatures: [["source","destination"]]
|
|
6724
|
+
},
|
|
6721
6725
|
{
|
|
6722
6726
|
name: "multiDrawIndirect",
|
|
6723
6727
|
signatures: [["indirectBuffer","indirectOffset","maxDrawCount","?drawCountBuffer","?drawCountBufferOffset"]]
|
|
@@ -7898,6 +7902,10 @@ export const NativeFunctions = [
|
|
|
7898
7902
|
name: "receiveFeatureReport",
|
|
7899
7903
|
signatures: [["reportId"]]
|
|
7900
7904
|
},
|
|
7905
|
+
{
|
|
7906
|
+
name: "playHaptics",
|
|
7907
|
+
signatures: [["effect","?intensity"]]
|
|
7908
|
+
},
|
|
7901
7909
|
{
|
|
7902
7910
|
name: "addStroke",
|
|
7903
7911
|
signatures: [["stroke"]]
|
|
@@ -0,0 +1,89 @@
|
|
|
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 * as Host from '../../core/host/host.js';
|
|
6
|
+
import * as SDK from '../../core/sdk/sdk.js';
|
|
7
|
+
import * as AiAssistanceModel from '../../models/ai_assistance/ai_assistance.js';
|
|
8
|
+
import * as NetworkTimeCalculator from '../../models/network_time_calculator/network_time_calculator.js';
|
|
9
|
+
import * as UI from '../../ui/legacy/legacy.js';
|
|
10
|
+
|
|
11
|
+
export type ContextType = 'NETWORK_REQUEST';
|
|
12
|
+
|
|
13
|
+
export interface ExternalAIRequestOptions {
|
|
14
|
+
context?: {
|
|
15
|
+
type: ContextType,
|
|
16
|
+
contextIdentifier: string,
|
|
17
|
+
};
|
|
18
|
+
prompts: string[];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface IndividualPromptRequestResponse {
|
|
22
|
+
prompt: string;
|
|
23
|
+
response: string;
|
|
24
|
+
error?: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function resolveConversationType(contextType?: ContextType): AiAssistanceModel.AiHistoryStorage.ConversationType {
|
|
28
|
+
switch (contextType) {
|
|
29
|
+
case 'NETWORK_REQUEST':
|
|
30
|
+
return AiAssistanceModel.AiHistoryStorage.ConversationType.NETWORK;
|
|
31
|
+
default:
|
|
32
|
+
return AiAssistanceModel.AiHistoryStorage.ConversationType.NONE;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function getMatchingFlavorContext(
|
|
37
|
+
contextOptions?: ExternalAIRequestOptions['context'],
|
|
38
|
+
): AiAssistanceModel.AiAgent.ConversationContext<unknown>|null {
|
|
39
|
+
if (!contextOptions?.contextIdentifier) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
if (contextOptions.type === 'NETWORK_REQUEST') {
|
|
43
|
+
const raw = UI.Context.Context.instance().flavor(SDK.NetworkRequest.NetworkRequest);
|
|
44
|
+
if (raw) {
|
|
45
|
+
if (raw.name() !== contextOptions.contextIdentifier && raw.url() !== contextOptions.contextIdentifier) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
return new AiAssistanceModel.RequestContext.RequestContext(
|
|
49
|
+
raw, new NetworkTimeCalculator.NetworkTransferTimeCalculator());
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export async function handleExternalAIRequest(options: ExternalAIRequestOptions): Promise<unknown[]> {
|
|
56
|
+
localStorage.setItem('aiAssistanceStructuredLogEnabled', 'true');
|
|
57
|
+
localStorage.removeItem('aiAssistanceStructuredLog');
|
|
58
|
+
|
|
59
|
+
const conversationType = resolveConversationType(options.context?.type);
|
|
60
|
+
|
|
61
|
+
const aidaClient = new Host.AidaClient.AidaClient();
|
|
62
|
+
const conversation = new AiAssistanceModel.AiConversation.AiConversation({
|
|
63
|
+
type: conversationType,
|
|
64
|
+
data: [],
|
|
65
|
+
isReadOnly: false,
|
|
66
|
+
aidaClient,
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
const resolvedContext = getMatchingFlavorContext(options.context);
|
|
70
|
+
if (resolvedContext) {
|
|
71
|
+
conversation.setContext(resolvedContext);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
for (const prompt of options.prompts) {
|
|
75
|
+
await Array.fromAsync(conversation.run(prompt));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const logsRaw = localStorage.getItem('aiAssistanceStructuredLog');
|
|
79
|
+
return logsRaw ? JSON.parse(logsRaw) : [];
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
declare global {
|
|
83
|
+
interface Window {
|
|
84
|
+
handleExternalAIRequest?: typeof handleExternalAIRequest;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// @ts-expect-error
|
|
89
|
+
globalThis.handleExternalAIRequest = handleExternalAIRequest;
|
|
@@ -16,4 +16,5 @@ export * as DisabledWidget from './components/DisabledWidget.js';
|
|
|
16
16
|
export * as WalkthroughUtils from './components/WalkthroughUtils.js';
|
|
17
17
|
export * as WalkthroughView from './components/WalkthroughView.js';
|
|
18
18
|
export * as ExportConversation from './ExportConversation.js';
|
|
19
|
+
export * as ExternalHandler from './ExternalHandler.js';
|
|
19
20
|
export * as ImageResize from './components/ImageResize.js';
|
|
@@ -2,6 +2,7 @@
|
|
|
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 Platform from '../../core/platform/platform.js';
|
|
5
6
|
import * as SDK from '../../core/sdk/sdk.js';
|
|
6
7
|
import type * as ProtocolProxyApi from '../../generated/protocol-proxy-api.js';
|
|
7
8
|
import type * as Protocol from '../../generated/protocol.js';
|
|
@@ -44,9 +45,9 @@ export class BackgroundServiceModel extends SDK.SDKModel.SDKModel<EventTypes> im
|
|
|
44
45
|
|
|
45
46
|
backgroundServiceEventReceived({backgroundServiceEvent}:
|
|
46
47
|
Protocol.BackgroundService.BackgroundServiceEventReceivedEvent): void {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
const events = this.events.get(backgroundServiceEvent.service);
|
|
49
|
+
Platform.assertNotNullOrUndefined(events);
|
|
50
|
+
events.push(backgroundServiceEvent);
|
|
50
51
|
this.dispatchEventToListeners(Events.BackgroundServiceEventReceived, backgroundServiceEvent);
|
|
51
52
|
}
|
|
52
53
|
}
|
|
@@ -423,13 +423,6 @@ export class IndexedDBModel extends SDK.SDKModel.SDKModel<EventTypes> implements
|
|
|
423
423
|
cacheStorageContentUpdated(_event: Protocol.Storage.CacheStorageContentUpdatedEvent): void {
|
|
424
424
|
}
|
|
425
425
|
|
|
426
|
-
sharedStorageAccessed(_event: Protocol.Storage.SharedStorageAccessedEvent): void {
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
sharedStorageWorkletOperationExecutionFinished(
|
|
430
|
-
_event: Protocol.Storage.SharedStorageWorkletOperationExecutionFinishedEvent): void {
|
|
431
|
-
}
|
|
432
|
-
|
|
433
426
|
storageBucketCreatedOrUpdated(_event: Protocol.Storage.StorageBucketCreatedOrUpdatedEvent): void {
|
|
434
427
|
}
|
|
435
428
|
|