chrome-devtools-frontend 1.0.1697998 → 1.0.1699061
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/devtools-verification/SKILL.md +19 -0
- package/.agents/skills/{repro-flaky-tests → fix-tests}/SKILL.md +2 -2
- 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 +6 -56
- package/front_end/core/sdk/DebuggerModel.ts +9 -8
- package/front_end/core/sdk/NetworkManager.ts +2 -2
- package/front_end/core/sdk/NetworkRequest.ts +1 -1
- package/front_end/core/sdk/OverlayModel.ts +11 -12
- 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 +109 -15
- 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 +54 -1
- 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/CookieIssue.ts +0 -13
- 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/source_map_scopes/NamesResolver.ts +11 -3
- package/front_end/models/source_map_scopes/ScopeChainModel.ts +10 -6
- package/front_end/models/workspace/UISourceCode.ts +20 -0
- package/front_end/panels/accessibility/AccessibilityAnnouncementRecordingView.ts +281 -3
- package/front_end/panels/accessibility/accessibilityAnnouncementRecordingView.css +85 -0
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +5 -8
- package/front_end/panels/ai_assistance/components/AIv2MarkdownRenderer.ts +4 -10
- package/front_end/panels/animation/AnimationTimeline.ts +1 -1
- package/front_end/panels/application/CrashReportContextView.ts +1 -1
- package/front_end/panels/application/IndexedDBViews.ts +1 -1
- package/front_end/panels/application/KeyValueStorageItemsView.ts +1 -0
- package/front_end/panels/application/components/AdsView.ts +63 -1
- package/front_end/panels/application/components/adsView.css +11 -1
- package/front_end/{ui/comments → panels/common}/CommentThreadWidget.ts +5 -20
- 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}/commentThreadWidget.css +0 -12
- 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/CSSRuleValidator.ts +1 -1
- package/front_end/panels/elements/ElementsPanel.ts +9 -5
- package/front_end/panels/elements/ElementsTreeElement.ts +11 -3
- package/front_end/panels/elements/ElementsTreeOutline.ts +69 -74
- 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 +11 -5
- package/front_end/panels/emulation/DeviceModeToolbar.ts +2 -3
- package/front_end/panels/event_listeners/EventListenersView.ts +33 -44
- package/front_end/panels/lighthouse/LighthouseController.ts +1 -1
- 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/mobile_throttling/NetworkPanelIndicator.ts +1 -1
- package/front_end/panels/mobile_throttling/ThrottlingManager.ts +1 -1
- package/front_end/panels/mobile_throttling/ThrottlingSettingsTab.ts +1 -1
- package/front_end/panels/recorder/StepView.ts +19 -4
- package/front_end/panels/recorder/TimelineSection.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/settings/BackendLinkingSettingsTab.ts +2 -1
- package/front_end/panels/settings/EditFileSystemView.ts +1 -1
- package/front_end/panels/sources/CallStackSidebarPane.ts +1 -1
- package/front_end/panels/sources/DebuggerPlugin.ts +2 -2
- package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +11 -16
- package/front_end/panels/sources/sources-meta.ts +1 -1
- package/front_end/panels/timeline/components/DetailsView.ts +3 -3
- package/front_end/panels/timeline/components/OriginMap.ts +1 -1
- package/front_end/panels/timeline/components/insights/BaseInsightComponent.ts +2 -3
- 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/components/buttons/Button.ts +19 -1
- package/front_end/ui/legacy/ContextMenu.ts +16 -1
- package/front_end/ui/legacy/PlusButton.ts +5 -6
- package/front_end/ui/legacy/Treeoutline.ts +6 -0
- package/front_end/ui/legacy/Widget.ts +33 -0
- package/front_end/ui/legacy/components/cookie_table/CookiesTable.ts +3 -0
- package/front_end/ui/legacy/components/data_grid/DataGridElement.ts +14 -4
- package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +36 -32
- package/front_end/ui/visual_logging/KnownContextValues.ts +4 -0
- package/package.json +1 -1
- package/.agents/skills/devtools-ci/SKILL.md +0 -65
- package/.agents/skills/evaluate-ai-css-completion/SKILL.md +0 -143
- package/.agents/skills/evaluate-ai-css-completion/scripts/evaluate.js +0 -104
- package/.agents/skills/fixing-skipped-tests/SKILL.md +0 -32
- package/.agents/skills/gerrit-cli/SKILL.md +0 -74
- package/.agents/skills/gerrit-cli/references/commands.md +0 -169
- package/.agents/skills/gerrit-cli/references/workflows.md +0 -63
- package/.agents/skills/gerrit-cli/scripts/import_upstream.py +0 -85
- package/front_end/models/issues_manager/descriptions/cookieExcludeBlockedWithinRelatedWebsiteSet.md +0 -4
|
@@ -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
|
};
|
|
@@ -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 Root from '../../core/root/root.js';
|
|
5
6
|
import * as SDK from '../../core/sdk/sdk.js';
|
|
6
7
|
import * as TextUtils from '../../core/text_utils/text_utils.js';
|
|
7
8
|
import * as Protocol from '../../generated/protocol.js';
|
|
@@ -380,9 +381,16 @@ export const resolveScopeChain =
|
|
|
380
381
|
return scopeChain;
|
|
381
382
|
}
|
|
382
383
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
384
|
+
if (Root.Runtime.hostConfig.devToolsSourceMapScopesInSourcesPanel?.enabled) {
|
|
385
|
+
let sourceMap = callFrame.script.sourceMap();
|
|
386
|
+
if (!sourceMap && callFrame.debuggerModel?.sourceMapManager) {
|
|
387
|
+
sourceMap = await callFrame.debuggerModel.sourceMapManager().sourceMapForClientPromise(callFrame.script);
|
|
388
|
+
}
|
|
389
|
+
const mappedScopeChain = sourceMap?.resolveScopeChain(callFrame);
|
|
390
|
+
if (mappedScopeChain) {
|
|
391
|
+
return mappedScopeChain;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
386
394
|
|
|
387
395
|
if (callFrame.script.isWasm()) {
|
|
388
396
|
return callFrame.scopeChain().filter(scope => !scope.empty());
|
|
@@ -35,8 +35,10 @@ export class ScopeChainModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
|
35
35
|
this.#debuggerWorkspaceBinding = debuggerWorkspaceBinding;
|
|
36
36
|
this.#callFrame.debuggerModel.addEventListener(
|
|
37
37
|
SDK.DebuggerModel.Events.DebugInfoAttached, this.#debugInfoAttached, this);
|
|
38
|
-
this.#callFrame.debuggerModel.sourceMapManager().addEventListener(
|
|
39
|
-
|
|
38
|
+
this.#callFrame.debuggerModel.sourceMapManager().addEventListener(SDK.SourceMapManager.Events.SourceMapAttached,
|
|
39
|
+
this.#sourceMapChanged, this);
|
|
40
|
+
this.#callFrame.debuggerModel.sourceMapManager().addEventListener(SDK.SourceMapManager.Events.SourceMapDetached,
|
|
41
|
+
this.#sourceMapChanged, this);
|
|
40
42
|
|
|
41
43
|
void this.#throttler.schedule(this.#boundUpdate);
|
|
42
44
|
}
|
|
@@ -44,8 +46,10 @@ export class ScopeChainModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
|
44
46
|
dispose(): void {
|
|
45
47
|
this.#callFrame.debuggerModel.removeEventListener(
|
|
46
48
|
SDK.DebuggerModel.Events.DebugInfoAttached, this.#debugInfoAttached, this);
|
|
47
|
-
this.#callFrame.debuggerModel.sourceMapManager().removeEventListener(
|
|
48
|
-
|
|
49
|
+
this.#callFrame.debuggerModel.sourceMapManager().removeEventListener(SDK.SourceMapManager.Events.SourceMapAttached,
|
|
50
|
+
this.#sourceMapChanged, this);
|
|
51
|
+
this.#callFrame.debuggerModel.sourceMapManager().removeEventListener(SDK.SourceMapManager.Events.SourceMapDetached,
|
|
52
|
+
this.#sourceMapChanged, this);
|
|
49
53
|
this.listeners?.clear();
|
|
50
54
|
}
|
|
51
55
|
|
|
@@ -60,8 +64,8 @@ export class ScopeChainModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
|
60
64
|
}
|
|
61
65
|
}
|
|
62
66
|
|
|
63
|
-
#
|
|
64
|
-
|
|
67
|
+
#sourceMapChanged(event: Common.EventTarget
|
|
68
|
+
.EventTargetEvent<{client: SDK.Script.Script, sourceMap: SDK.SourceMap.SourceMap}>): void {
|
|
65
69
|
if (event.data.client === this.#callFrame.script) {
|
|
66
70
|
void this.#throttler.schedule(this.#boundUpdate);
|
|
67
71
|
}
|
|
@@ -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) {
|
|
@@ -6,25 +6,192 @@ import type * as Common from '../../core/common/common.js';
|
|
|
6
6
|
import * as i18n from '../../core/i18n/i18n.js';
|
|
7
7
|
import * as SDK from '../../core/sdk/sdk.js';
|
|
8
8
|
import type * as Protocol from '../../generated/protocol.js';
|
|
9
|
+
import * as Buttons from '../../ui/components/buttons/buttons.js';
|
|
10
|
+
import * as UI from '../../ui/legacy/legacy.js';
|
|
11
|
+
import * as Lit from '../../ui/lit/lit.js';
|
|
12
|
+
import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
|
|
9
13
|
|
|
14
|
+
import {AccessibilityAnnouncementRecordingListView} from './AccessibilityAnnouncementRecordingListView.js';
|
|
15
|
+
import accessibilityAnnouncementRecordingViewStyles from './accessibilityAnnouncementRecordingView.css.js';
|
|
10
16
|
import {AccessibilitySubPane} from './AccessibilitySubPane.js';
|
|
11
17
|
|
|
18
|
+
const {html, render} = Lit;
|
|
19
|
+
const {widget} = UI.Widget;
|
|
20
|
+
|
|
12
21
|
const UIStrings = {
|
|
13
22
|
/**
|
|
14
23
|
* @description Title for the ARIA-Live and JS announcements recording tool
|
|
15
24
|
*/
|
|
16
25
|
ariaLiveRecording: 'Announcements recording',
|
|
26
|
+
/**
|
|
27
|
+
* @description Tooltip for the start recording button in the announcements tool.
|
|
28
|
+
*/
|
|
29
|
+
startRecording: 'Start recording',
|
|
30
|
+
/**
|
|
31
|
+
* @description Tooltip for the stop recording button in the announcements tool.
|
|
32
|
+
*/
|
|
33
|
+
stopRecording: 'Stop recording',
|
|
34
|
+
/**
|
|
35
|
+
* @description Tooltip for the clear announcements button in the announcements tool.
|
|
36
|
+
*/
|
|
37
|
+
clearAnnouncements: 'Clear announcements',
|
|
38
|
+
/**
|
|
39
|
+
* @description Label/title for the dropdown filter to select which announcement types to record.
|
|
40
|
+
*/
|
|
41
|
+
filterByType: 'Filter by type',
|
|
42
|
+
/**
|
|
43
|
+
* @description Option label to record and display both ARIA-live and JavaScript announcements.
|
|
44
|
+
*/
|
|
45
|
+
recordBoth: 'Record both',
|
|
46
|
+
/**
|
|
47
|
+
* @description Option label to record and display only ARIA-live announcements.
|
|
48
|
+
*/
|
|
49
|
+
ariaLiveOnly: 'ARIA-live only',
|
|
50
|
+
/**
|
|
51
|
+
* @description Option label to record and display only JavaScript-triggered announcements.
|
|
52
|
+
*/
|
|
53
|
+
announcementsOnly: 'Announcements only',
|
|
54
|
+
/**
|
|
55
|
+
* @description Placeholder text for the filter input in the announcements tool.
|
|
56
|
+
*/
|
|
57
|
+
filter: 'Filter',
|
|
58
|
+
/**
|
|
59
|
+
* @description Screen reader announcement when no events match the filter in the announcements tool.
|
|
60
|
+
*/
|
|
61
|
+
noEventsMatch: 'No events match',
|
|
62
|
+
/**
|
|
63
|
+
* @description Screen reader announcement when exactly one event matches the filter in the announcements tool.
|
|
64
|
+
*/
|
|
65
|
+
oneEventMatches: '1 event matches',
|
|
66
|
+
/**
|
|
67
|
+
* @description Screen reader announcement when multiple events match the filter in the announcements tool.
|
|
68
|
+
* @example {15} PH1
|
|
69
|
+
*/
|
|
70
|
+
nEventsMatch: '{PH1} events match',
|
|
71
|
+
/**
|
|
72
|
+
* @description Warning banner title shown when recording could not be enabled in some frames.
|
|
73
|
+
*/
|
|
74
|
+
recordingBlockedWarning: 'Recording was blocked for some frames:',
|
|
75
|
+
/**
|
|
76
|
+
* @description Warning item describing a specific frame and the reason recording was blocked.
|
|
77
|
+
* @example {iframe#main} PH1
|
|
78
|
+
* @example {Script evaluation failed} PH2
|
|
79
|
+
*/
|
|
80
|
+
frameBlockedReason: '{PH1}: {PH2}',
|
|
81
|
+
/**
|
|
82
|
+
* @description Fallback reason shown when an unknown error occurs while blocking recording.
|
|
83
|
+
*/
|
|
84
|
+
unknownError: 'Unknown error',
|
|
17
85
|
} as const;
|
|
18
86
|
const str_ = i18n.i18n.registerUIStrings('panels/accessibility/AccessibilityAnnouncementRecordingView.ts', UIStrings);
|
|
19
87
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
20
88
|
|
|
21
89
|
export const BINDING_NAME = '__announcementsRecorderBinding';
|
|
22
90
|
|
|
23
|
-
export
|
|
91
|
+
export enum AnnouncementApi {
|
|
24
92
|
ARIA_LIVE = 'aria-live',
|
|
25
93
|
JS_TRIGGERED = 'js-triggered',
|
|
26
94
|
}
|
|
27
95
|
|
|
96
|
+
export const enum RecordTypeFilter {
|
|
97
|
+
BOTH = 'both',
|
|
98
|
+
ARIA_LIVE = 'aria-live',
|
|
99
|
+
JS_TRIGGERED = 'js-triggered',
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export interface BlockedTargetInfo {
|
|
103
|
+
targetName: string;
|
|
104
|
+
reason: string;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export interface ViewInput {
|
|
108
|
+
isRecording: boolean;
|
|
109
|
+
onToggleRecording: () => void;
|
|
110
|
+
onClear: () => void;
|
|
111
|
+
recordTypeFilter: RecordTypeFilter;
|
|
112
|
+
onRecordTypeFilterChange: (type: RecordTypeFilter) => void;
|
|
113
|
+
textFilter: string;
|
|
114
|
+
onTextFilterChange: (text: string) => void;
|
|
115
|
+
blockedTargets: BlockedTargetInfo[];
|
|
116
|
+
announcements: readonly A11yAnnouncement[];
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export type View = (input: ViewInput, output: undefined, target: HTMLElement) => void;
|
|
120
|
+
|
|
121
|
+
export const DEFAULT_VIEW: View = (input, _output, target) => {
|
|
122
|
+
// clang-format off
|
|
123
|
+
render(html`
|
|
124
|
+
<style>${accessibilityAnnouncementRecordingViewStyles}</style>
|
|
125
|
+
<div class="accessibility-announcement-recording-view">
|
|
126
|
+
<div class="announcements-toolbar-container">
|
|
127
|
+
<devtools-toolbar class="announcements-toolbar" jslog=${VisualLogging.toolbar()}>
|
|
128
|
+
<devtools-button
|
|
129
|
+
title=${input.isRecording ? i18nString(UIStrings.stopRecording) : i18nString(UIStrings.startRecording)}
|
|
130
|
+
aria-label=${input.isRecording ? i18nString(UIStrings.stopRecording) : i18nString(UIStrings.startRecording)}
|
|
131
|
+
.iconName=${'record-start'}
|
|
132
|
+
.toggledIconName=${'record-stop'}
|
|
133
|
+
.toggleType=${Buttons.Button.ToggleType.PRIMARY}
|
|
134
|
+
.toggled=${input.isRecording}
|
|
135
|
+
@click=${input.onToggleRecording}
|
|
136
|
+
.variant=${Buttons.Button.Variant.TOOLBAR}
|
|
137
|
+
.jslogContext=${'accessibility.toggle-recording'}>
|
|
138
|
+
</devtools-button>
|
|
139
|
+
<devtools-button
|
|
140
|
+
title=${i18nString(UIStrings.clearAnnouncements)}
|
|
141
|
+
aria-label=${i18nString(UIStrings.clearAnnouncements)}
|
|
142
|
+
.iconName=${'clear'}
|
|
143
|
+
@click=${input.onClear}
|
|
144
|
+
.variant=${Buttons.Button.Variant.TOOLBAR}
|
|
145
|
+
.jslogContext=${'accessibility.clear-announcements'}>
|
|
146
|
+
</devtools-button>
|
|
147
|
+
<div class="toolbar-divider" role="separator"></div>
|
|
148
|
+
<select
|
|
149
|
+
title=${i18nString(UIStrings.filterByType)}
|
|
150
|
+
aria-label=${i18nString(UIStrings.filterByType)}
|
|
151
|
+
@change=${(event: Event) => input.onRecordTypeFilterChange((event.target as HTMLSelectElement).value as RecordTypeFilter)}
|
|
152
|
+
.value=${input.recordTypeFilter}
|
|
153
|
+
jslog=${VisualLogging.dropDown('accessibility-announcements.filter-by-type').track({change: true})}>
|
|
154
|
+
<option value=${RecordTypeFilter.BOTH} .selected=${input.recordTypeFilter === RecordTypeFilter.BOTH}>
|
|
155
|
+
${i18nString(UIStrings.recordBoth)}
|
|
156
|
+
</option>
|
|
157
|
+
<option value=${RecordTypeFilter.ARIA_LIVE} .selected=${input.recordTypeFilter === RecordTypeFilter.ARIA_LIVE}>
|
|
158
|
+
${i18nString(UIStrings.ariaLiveOnly)}
|
|
159
|
+
</option>
|
|
160
|
+
<option value=${RecordTypeFilter.JS_TRIGGERED} .selected=${input.recordTypeFilter === RecordTypeFilter.JS_TRIGGERED}>
|
|
161
|
+
${i18nString(UIStrings.announcementsOnly)}
|
|
162
|
+
</option>
|
|
163
|
+
</select>
|
|
164
|
+
<div class="toolbar-divider" role="separator"></div>
|
|
165
|
+
<devtools-toolbar-input
|
|
166
|
+
type="filter"
|
|
167
|
+
placeholder=${i18nString(UIStrings.filter)}
|
|
168
|
+
.value=${input.textFilter}
|
|
169
|
+
@change=${(event: CustomEvent<string>) => input.onTextFilterChange(event.detail)}
|
|
170
|
+
style="flex-grow: 1">
|
|
171
|
+
</devtools-toolbar-input>
|
|
172
|
+
</devtools-toolbar>
|
|
173
|
+
</div>
|
|
174
|
+
${input.blockedTargets.length > 0 ? html`
|
|
175
|
+
<div class="announcements-blocked-banner" role="alert">
|
|
176
|
+
<div class="blocked-banner-header">
|
|
177
|
+
<devtools-icon name="warning-filled"></devtools-icon>
|
|
178
|
+
<span>${i18nString(UIStrings.recordingBlockedWarning)}</span>
|
|
179
|
+
</div>
|
|
180
|
+
<ul class="blocked-targets-list">
|
|
181
|
+
${input.blockedTargets.map(targetInfo => html`
|
|
182
|
+
<li>${i18nString(UIStrings.frameBlockedReason, {PH1: targetInfo.targetName, PH2: targetInfo.reason || i18nString(UIStrings.unknownError)})}</li>
|
|
183
|
+
`)}
|
|
184
|
+
</ul>
|
|
185
|
+
</div>
|
|
186
|
+
` : Lit.nothing}
|
|
187
|
+
<div class="announcements-main-pane">
|
|
188
|
+
${widget(AccessibilityAnnouncementRecordingListView, {items: input.announcements})}
|
|
189
|
+
</div>
|
|
190
|
+
</div>`,
|
|
191
|
+
target);
|
|
192
|
+
// clang-format on
|
|
193
|
+
};
|
|
194
|
+
|
|
28
195
|
declare global {
|
|
29
196
|
interface Window {
|
|
30
197
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
@@ -564,17 +731,23 @@ export function validateAndSanitizeAnnouncement(payload: unknown): A11yAnnouncem
|
|
|
564
731
|
|
|
565
732
|
export class AccessibilityAnnouncementRecordingView extends AccessibilitySubPane implements SDK.TargetManager.Observer {
|
|
566
733
|
#announcements: A11yAnnouncement[] = [];
|
|
734
|
+
#filteredAnnouncements: readonly A11yAnnouncement[]|null = null;
|
|
567
735
|
#isRecording = false;
|
|
568
736
|
#blockedTargets = new Map<SDK.Target.Target, string>();
|
|
569
737
|
#scriptIdentifiers = new Map<SDK.Target.Target, Protocol.Page.ScriptIdentifier>();
|
|
570
738
|
#targets = new Set<SDK.Target.Target>();
|
|
571
739
|
#enabledTargets = new Set<SDK.Target.Target>();
|
|
740
|
+
#recordTypeFilter: RecordTypeFilter = RecordTypeFilter.BOTH;
|
|
741
|
+
#textFilter = '';
|
|
742
|
+
#regexFilter: RegExp|null = null;
|
|
743
|
+
readonly #view: View;
|
|
572
744
|
|
|
573
|
-
constructor() {
|
|
745
|
+
constructor(view: View = DEFAULT_VIEW) {
|
|
574
746
|
super({
|
|
575
747
|
title: i18nString(UIStrings.ariaLiveRecording),
|
|
576
748
|
viewId: 'aria-live-recording',
|
|
577
749
|
});
|
|
750
|
+
this.#view = view;
|
|
578
751
|
SDK.TargetManager.TargetManager.instance().observeTargets(this, {scoped: true});
|
|
579
752
|
}
|
|
580
753
|
|
|
@@ -595,8 +768,11 @@ export class AccessibilityAnnouncementRecordingView extends AccessibilitySubPane
|
|
|
595
768
|
|
|
596
769
|
async targetRemoved(target: SDK.Target.Target): Promise<void> {
|
|
597
770
|
this.#targets.delete(target);
|
|
598
|
-
this.#blockedTargets.delete(target);
|
|
771
|
+
const wasBlocked = this.#blockedTargets.delete(target);
|
|
599
772
|
await this.#disableTarget(target);
|
|
773
|
+
if (wasBlocked) {
|
|
774
|
+
this.requestUpdate();
|
|
775
|
+
}
|
|
600
776
|
}
|
|
601
777
|
|
|
602
778
|
async #enableTarget(target: SDK.Target.Target): Promise<void> {
|
|
@@ -708,6 +884,11 @@ export class AccessibilityAnnouncementRecordingView extends AccessibilitySubPane
|
|
|
708
884
|
return;
|
|
709
885
|
}
|
|
710
886
|
this.#announcements.push(announcement);
|
|
887
|
+
if (this.#filteredAnnouncements !== null) {
|
|
888
|
+
if (this.#matchesFilter(announcement)) {
|
|
889
|
+
this.#filteredAnnouncements = [...this.#filteredAnnouncements, announcement];
|
|
890
|
+
}
|
|
891
|
+
}
|
|
711
892
|
this.requestUpdate();
|
|
712
893
|
}
|
|
713
894
|
|
|
@@ -736,9 +917,106 @@ export class AccessibilityAnnouncementRecordingView extends AccessibilitySubPane
|
|
|
736
917
|
|
|
737
918
|
clearAnnouncements(): void {
|
|
738
919
|
this.#announcements = [];
|
|
920
|
+
this.#filteredAnnouncements = [];
|
|
921
|
+
this.requestUpdate();
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
#matchesFilter(announcement: A11yAnnouncement): boolean {
|
|
925
|
+
if (this.#recordTypeFilter === RecordTypeFilter.ARIA_LIVE && announcement.api !== AnnouncementApi.ARIA_LIVE) {
|
|
926
|
+
return false;
|
|
927
|
+
}
|
|
928
|
+
if (this.#recordTypeFilter === RecordTypeFilter.JS_TRIGGERED && announcement.api !== AnnouncementApi.JS_TRIGGERED) {
|
|
929
|
+
return false;
|
|
930
|
+
}
|
|
931
|
+
if (this.#regexFilter && !this.#regexFilter.test(announcement.message)) {
|
|
932
|
+
return false;
|
|
933
|
+
}
|
|
934
|
+
return true;
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
get filteredAnnouncements(): readonly A11yAnnouncement[] {
|
|
938
|
+
if (this.#filteredAnnouncements !== null) {
|
|
939
|
+
return this.#filteredAnnouncements;
|
|
940
|
+
}
|
|
941
|
+
this.#filteredAnnouncements = this.#announcements.filter(announcement => this.#matchesFilter(announcement));
|
|
942
|
+
return this.#filteredAnnouncements;
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
#announceFilterMatches(): void {
|
|
946
|
+
const count = this.filteredAnnouncements.length;
|
|
947
|
+
let message: string;
|
|
948
|
+
if (count === 0) {
|
|
949
|
+
message = i18nString(UIStrings.noEventsMatch);
|
|
950
|
+
} else if (count === 1) {
|
|
951
|
+
message = i18nString(UIStrings.oneEventMatches);
|
|
952
|
+
} else {
|
|
953
|
+
message = i18nString(UIStrings.nEventsMatch, {PH1: count});
|
|
954
|
+
}
|
|
955
|
+
UI.ARIAUtils.LiveAnnouncer.alert(message);
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
setRecordTypeFilter(type: RecordTypeFilter): void {
|
|
959
|
+
if (this.#recordTypeFilter === type) {
|
|
960
|
+
return;
|
|
961
|
+
}
|
|
962
|
+
this.#recordTypeFilter = type;
|
|
963
|
+
this.#filteredAnnouncements = null;
|
|
964
|
+
this.#announceFilterMatches();
|
|
739
965
|
this.requestUpdate();
|
|
740
966
|
}
|
|
741
967
|
|
|
968
|
+
setTextFilter(text: string): void {
|
|
969
|
+
if (this.#textFilter === text) {
|
|
970
|
+
return;
|
|
971
|
+
}
|
|
972
|
+
this.#textFilter = text;
|
|
973
|
+
if (!text) {
|
|
974
|
+
this.#regexFilter = null;
|
|
975
|
+
} else {
|
|
976
|
+
try {
|
|
977
|
+
this.#regexFilter = new RegExp(text, 'i');
|
|
978
|
+
} catch {
|
|
979
|
+
this.#regexFilter = new RegExp('(?!)', 'i');
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
this.#filteredAnnouncements = null;
|
|
983
|
+
this.#announceFilterMatches();
|
|
984
|
+
this.requestUpdate();
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
override performUpdate(): void {
|
|
988
|
+
const blockedTargets: BlockedTargetInfo[] = [];
|
|
989
|
+
for (const [target, reason] of this.#blockedTargets) {
|
|
990
|
+
const targetName = target.name() || target.inspectedURL() || target.id();
|
|
991
|
+
blockedTargets.push({targetName, reason});
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
const input: ViewInput = {
|
|
995
|
+
isRecording: this.#isRecording,
|
|
996
|
+
onToggleRecording: () => {
|
|
997
|
+
if (this.#isRecording) {
|
|
998
|
+
void this.stopRecording();
|
|
999
|
+
} else {
|
|
1000
|
+
void this.startRecording();
|
|
1001
|
+
}
|
|
1002
|
+
},
|
|
1003
|
+
onClear: () => {
|
|
1004
|
+
this.clearAnnouncements();
|
|
1005
|
+
},
|
|
1006
|
+
recordTypeFilter: this.#recordTypeFilter,
|
|
1007
|
+
onRecordTypeFilterChange: (type: RecordTypeFilter) => {
|
|
1008
|
+
this.setRecordTypeFilter(type);
|
|
1009
|
+
},
|
|
1010
|
+
textFilter: this.#textFilter,
|
|
1011
|
+
onTextFilterChange: (text: string) => {
|
|
1012
|
+
this.setTextFilter(text);
|
|
1013
|
+
},
|
|
1014
|
+
blockedTargets,
|
|
1015
|
+
announcements: this.filteredAnnouncements,
|
|
1016
|
+
};
|
|
1017
|
+
this.#view(input, undefined, this.contentElement);
|
|
1018
|
+
}
|
|
1019
|
+
|
|
742
1020
|
announcementsForTest(): A11yAnnouncement[] {
|
|
743
1021
|
return [...this.#announcements];
|
|
744
1022
|
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 The Chromium Authors
|
|
3
|
+
* Use of this source code is governed by a BSD-style license that can be
|
|
4
|
+
* found in the LICENSE file.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
@scope to (devtools-widget > *) {
|
|
8
|
+
:scope {
|
|
9
|
+
font-family: inherit;
|
|
10
|
+
display: flex;
|
|
11
|
+
flex-direction: column;
|
|
12
|
+
flex: auto;
|
|
13
|
+
height: 100%;
|
|
14
|
+
overflow: hidden;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.accessibility-announcement-recording-view {
|
|
18
|
+
display: flex;
|
|
19
|
+
flex-direction: column;
|
|
20
|
+
flex: auto;
|
|
21
|
+
height: 100%;
|
|
22
|
+
overflow: hidden;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.announcements-toolbar-container {
|
|
26
|
+
display: flex;
|
|
27
|
+
flex: none;
|
|
28
|
+
background-color: var(--sys-color-cdt-base-container);
|
|
29
|
+
border-bottom: var(--sys-size-1) solid var(--sys-color-divider);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.announcements-toolbar {
|
|
33
|
+
flex: auto;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.announcements-toolbar select {
|
|
37
|
+
background-color: transparent;
|
|
38
|
+
border: none;
|
|
39
|
+
color: var(--sys-color-on-surface);
|
|
40
|
+
font-size: var(--sys-typescale-body4-size);
|
|
41
|
+
padding: var(--sys-size-2) var(--sys-size-4);
|
|
42
|
+
height: 100%;
|
|
43
|
+
cursor: pointer;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.toolbar-divider {
|
|
47
|
+
background-color: var(--sys-color-divider);
|
|
48
|
+
width: var(--sys-size-1);
|
|
49
|
+
margin: 5px var(--sys-size-3);
|
|
50
|
+
height: var(--sys-size-8);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.announcements-blocked-banner {
|
|
54
|
+
display: flex;
|
|
55
|
+
flex-direction: column;
|
|
56
|
+
flex: none;
|
|
57
|
+
gap: var(--sys-size-3);
|
|
58
|
+
padding: var(--sys-size-5) var(--sys-size-8);
|
|
59
|
+
background-color: var(--sys-color-surface-yellow);
|
|
60
|
+
color: var(--sys-color-on-surface-yellow);
|
|
61
|
+
border-bottom: var(--sys-size-1) solid var(--sys-color-divider);
|
|
62
|
+
font-size: var(--sys-typescale-body4-size);
|
|
63
|
+
line-height: var(--sys-typescale-body4-line-height);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.blocked-banner-header {
|
|
67
|
+
display: flex;
|
|
68
|
+
align-items: center;
|
|
69
|
+
gap: var(--sys-size-4);
|
|
70
|
+
font-weight: var(--ref-typeface-weight-medium);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.blocked-targets-list {
|
|
74
|
+
margin: 0;
|
|
75
|
+
padding-left: var(--sys-size-8);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.announcements-main-pane {
|
|
79
|
+
display: flex;
|
|
80
|
+
flex-direction: column;
|
|
81
|
+
flex: auto;
|
|
82
|
+
min-height: 0;
|
|
83
|
+
overflow: hidden;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -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);
|
|
@@ -393,9 +391,8 @@ function toolbarView(input: ToolbarViewInput): Lit.LitTemplate {
|
|
|
393
391
|
@click=${input.onNewChatClick}></devtools-button>
|
|
394
392
|
<div class="toolbar-divider"></div>
|
|
395
393
|
<devtools-menu-button
|
|
396
|
-
title=${i18nString(UIStrings.history)}
|
|
397
|
-
aria-label=${i18nString(UIStrings.history)}
|
|
398
394
|
.iconName=${'history'}
|
|
395
|
+
.accessibleLabel=${i18nString(UIStrings.history)}
|
|
399
396
|
.jslogContext=${'freestyler.history'}
|
|
400
397
|
.populateMenuCall=${input.populateHistoryMenu}
|
|
401
398
|
></devtools-menu-button>`
|