chrome-devtools-frontend 1.0.1698733 → 1.0.1700561
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/front_end/core/sdk/CSSPropertyParserMatchers.ts +2 -2
- package/front_end/core/sdk/DOMModel.ts +3 -5
- package/front_end/core/sdk/NetworkManager.ts +2 -2
- package/front_end/core/sdk/OverlayModel.ts +11 -12
- package/front_end/core/sdk/ServiceWorkerCacheModel.ts +3 -0
- package/front_end/core/sdk/SourceMapScopeChainEntry.ts +84 -32
- package/front_end/core/sdk/StorageBucketsModel.ts +2 -0
- package/front_end/entrypoints/main/GlobalAiButton.ts +2 -6
- package/front_end/entrypoints/main/MainImpl.ts +8 -1
- package/front_end/generated/InspectorBackendCommands.ts +12 -2
- package/front_end/generated/SupportedCSSProperties.ts +14 -0
- package/front_end/generated/protocol-mapping.d.ts +48 -1
- package/front_end/generated/protocol-proxy-api.d.ts +37 -1
- package/front_end/generated/protocol.ts +131 -0
- package/front_end/models/bindings/NetworkProject.ts +30 -0
- package/front_end/models/bindings/ResourceScriptMapping.ts +62 -0
- package/front_end/models/change_tracker/ChangeTracker.ts +1 -1
- package/front_end/models/comment_manager/CD4ABridge.ts +2 -2
- package/front_end/models/comment_manager/CommentManager.ts +18 -0
- package/front_end/models/emulation/DeviceModeModel.ts +1 -1
- package/front_end/models/extensions/ExtensionAPI.ts +4 -2
- package/front_end/models/issues_manager/CookieIssue.ts +0 -15
- package/front_end/models/persistence/NetworkPersistenceManager.ts +29 -4
- package/front_end/models/source_map_scopes/NamesResolver.ts +34 -4
- package/front_end/models/source_map_scopes/ScopeChainModel.ts +31 -7
- 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 +1 -2
- package/front_end/panels/ai_assistance/ai_assistance-meta.ts +5 -8
- package/front_end/panels/animation/AnimationTimeline.ts +1 -1
- package/front_end/panels/application/AppManifestView.ts +128 -134
- package/front_end/panels/application/CrashReportContextView.ts +6 -6
- package/front_end/panels/application/DeviceBoundSessionsTreeElement.ts +17 -17
- package/front_end/panels/application/DeviceBoundSessionsView.ts +136 -137
- package/front_end/panels/application/IndexedDBModel.ts +3 -0
- package/front_end/panels/application/IndexedDBViews.ts +1 -1
- package/front_end/panels/application/KeyValueStorageItemsView.ts +1 -0
- package/front_end/panels/application/OriginTrialTreeView.ts +18 -23
- package/front_end/panels/application/ReportingApiTreeElement.ts +3 -3
- package/front_end/panels/application/ReportingApiView.ts +6 -14
- package/front_end/panels/application/application-meta.ts +7 -7
- package/front_end/panels/application/components/AdsView.ts +63 -1
- package/front_end/panels/application/components/adsView.css +11 -1
- package/front_end/panels/common/CommentThreadWidget.ts +20 -22
- package/front_end/panels/common/CommentsOverlayWidget.ts +115 -9
- package/front_end/panels/common/CommentsStatusBarPill.ts +13 -1
- package/front_end/panels/common/ExtensionServer.ts +43 -34
- package/front_end/panels/common/GeminiRebrandPromoDialog.ts +1 -1
- package/front_end/panels/common/commentThreadWidget.css +6 -0
- package/front_end/panels/common/common-meta.ts +4 -1
- package/front_end/panels/elements/CSSRuleValidator.ts +1 -1
- package/front_end/panels/elements/ElementsPanel.ts +4 -4
- package/front_end/panels/elements/ElementsTreeElement.ts +9 -2
- package/front_end/panels/elements/ElementsTreeOutline.ts +25 -33
- package/front_end/panels/elements/elementsTreeOutline.css +8 -4
- package/front_end/panels/event_listeners/EventListenersView.ts +9 -4
- package/front_end/panels/issues/IssuesPane.ts +34 -22
- package/front_end/panels/lighthouse/LighthouseController.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/network/RequestPayloadView.ts +17 -15
- package/front_end/panels/recorder/RecordingView.ts +32 -53
- package/front_end/panels/recorder/StepView.ts +19 -4
- package/front_end/panels/recorder/TimelineSection.ts +1 -1
- package/front_end/panels/recorder/controlButton.css +6 -0
- package/front_end/panels/recorder/recordingView.css +11 -2
- 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 +137 -56
- package/front_end/panels/sources/ScopeChainSidebarPane.ts +17 -15
- package/front_end/panels/timeline/components/DetailsView.ts +3 -3
- package/front_end/panels/timeline/components/IgnoreListSetting.ts +0 -2
- package/front_end/panels/timeline/components/LiveMetricsView.ts +59 -64
- 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/components/liveMetricsView.css +1 -0
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/third_party/lighthouse/README.chromium +2 -2
- package/front_end/third_party/lighthouse/lighthouse-dt-bundle.js +1580 -1524
- package/front_end/third_party/lighthouse/locales/ar-XB.json +111 -72
- package/front_end/third_party/lighthouse/locales/ar.json +113 -74
- package/front_end/third_party/lighthouse/locales/bg.json +112 -73
- package/front_end/third_party/lighthouse/locales/ca.json +112 -73
- package/front_end/third_party/lighthouse/locales/cs.json +112 -73
- package/front_end/third_party/lighthouse/locales/da.json +112 -73
- package/front_end/third_party/lighthouse/locales/de.json +112 -73
- package/front_end/third_party/lighthouse/locales/el.json +112 -73
- package/front_end/third_party/lighthouse/locales/en-GB.json +111 -72
- package/front_end/third_party/lighthouse/locales/en-US.json +102 -66
- package/front_end/third_party/lighthouse/locales/en-XA.json +111 -72
- package/front_end/third_party/lighthouse/locales/en-XL.json +102 -66
- package/front_end/third_party/lighthouse/locales/es-419.json +112 -73
- package/front_end/third_party/lighthouse/locales/es.json +112 -73
- package/front_end/third_party/lighthouse/locales/fi.json +112 -73
- package/front_end/third_party/lighthouse/locales/fil.json +112 -73
- package/front_end/third_party/lighthouse/locales/fr.json +112 -73
- package/front_end/third_party/lighthouse/locales/he.json +112 -73
- package/front_end/third_party/lighthouse/locales/hi.json +112 -73
- package/front_end/third_party/lighthouse/locales/hr.json +112 -73
- package/front_end/third_party/lighthouse/locales/hu.json +112 -73
- package/front_end/third_party/lighthouse/locales/id.json +112 -73
- package/front_end/third_party/lighthouse/locales/it.json +113 -74
- package/front_end/third_party/lighthouse/locales/ja.json +112 -73
- package/front_end/third_party/lighthouse/locales/ko.json +112 -73
- package/front_end/third_party/lighthouse/locales/lt.json +112 -73
- package/front_end/third_party/lighthouse/locales/lv.json +112 -73
- package/front_end/third_party/lighthouse/locales/nl.json +112 -73
- package/front_end/third_party/lighthouse/locales/no.json +112 -73
- package/front_end/third_party/lighthouse/locales/pl.json +112 -73
- package/front_end/third_party/lighthouse/locales/pt-PT.json +112 -73
- package/front_end/third_party/lighthouse/locales/pt.json +112 -73
- package/front_end/third_party/lighthouse/locales/ro.json +112 -73
- package/front_end/third_party/lighthouse/locales/ru.json +112 -73
- package/front_end/third_party/lighthouse/locales/sk.json +112 -73
- package/front_end/third_party/lighthouse/locales/sl.json +112 -73
- package/front_end/third_party/lighthouse/locales/sr-Latn.json +112 -73
- package/front_end/third_party/lighthouse/locales/sr.json +112 -73
- package/front_end/third_party/lighthouse/locales/sv.json +124 -85
- package/front_end/third_party/lighthouse/locales/ta.json +112 -73
- package/front_end/third_party/lighthouse/locales/te.json +112 -73
- package/front_end/third_party/lighthouse/locales/th.json +112 -73
- package/front_end/third_party/lighthouse/locales/tr.json +113 -74
- package/front_end/third_party/lighthouse/locales/uk.json +112 -73
- package/front_end/third_party/lighthouse/locales/vi.json +112 -73
- package/front_end/third_party/lighthouse/locales/zh-HK.json +112 -73
- package/front_end/third_party/lighthouse/locales/zh-TW.json +113 -74
- package/front_end/third_party/lighthouse/locales/zh.json +113 -74
- package/front_end/third_party/lighthouse/report/bundle.d.ts +4 -4
- package/front_end/third_party/lighthouse/report/bundle.js +10 -3
- package/front_end/third_party/lighthouse/report-assets/report-generator.mjs +2 -2
- package/front_end/third_party/lit/lit.ts +3 -0
- package/front_end/third_party/lit/package.json +3 -0
- package/front_end/third_party/lit/rebuild.sh +3 -2
- package/front_end/ui/comments/CommentAnchorResolver.ts +8 -2
- package/front_end/ui/comments/CommentOverlayManager.ts +2 -1
- package/front_end/ui/components/buttons/Button.ts +19 -1
- package/front_end/ui/legacy/ContextMenu.ts +16 -1
- package/front_end/ui/legacy/InspectorView.ts +4 -3
- package/front_end/ui/legacy/PlusButton.ts +5 -6
- package/front_end/ui/legacy/TabbedPane.ts +121 -80
- package/front_end/ui/legacy/Treeoutline.ts +37 -6
- package/front_end/ui/legacy/UIUtils.ts +7 -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 +157 -171
- package/front_end/ui/lit/lit.ts +1 -1
- package/front_end/ui/visual_logging/KnownContextValues.ts +7 -0
- package/inspector_overlay/highlight_anchor.ts +197 -0
- package/inspector_overlay/tool_highlight.ts +8 -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
|
@@ -21,6 +21,9 @@ import {resolveScopeChain} from './NamesResolver.js';
|
|
|
21
21
|
* This class tracks all that and sends events with the latest scope chain for a specific call frame.
|
|
22
22
|
*/
|
|
23
23
|
export class ScopeChainModel extends Common.ObjectWrapper.ObjectWrapper<EventTypes> {
|
|
24
|
+
static readonly #cachedScopeChainByCallFrame =
|
|
25
|
+
new WeakMap<SDK.DebuggerModel.CallFrame, Promise<SDK.DebuggerModel.ScopeChainEntry[]>>();
|
|
26
|
+
|
|
24
27
|
readonly #callFrame: SDK.DebuggerModel.CallFrame;
|
|
25
28
|
readonly #debuggerWorkspaceBinding: Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding;
|
|
26
29
|
|
|
@@ -35,8 +38,10 @@ export class ScopeChainModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
|
35
38
|
this.#debuggerWorkspaceBinding = debuggerWorkspaceBinding;
|
|
36
39
|
this.#callFrame.debuggerModel.addEventListener(
|
|
37
40
|
SDK.DebuggerModel.Events.DebugInfoAttached, this.#debugInfoAttached, this);
|
|
38
|
-
this.#callFrame.debuggerModel.sourceMapManager().addEventListener(
|
|
39
|
-
|
|
41
|
+
this.#callFrame.debuggerModel.sourceMapManager().addEventListener(SDK.SourceMapManager.Events.SourceMapAttached,
|
|
42
|
+
this.#sourceMapChanged, this);
|
|
43
|
+
this.#callFrame.debuggerModel.sourceMapManager().addEventListener(SDK.SourceMapManager.Events.SourceMapDetached,
|
|
44
|
+
this.#sourceMapChanged, this);
|
|
40
45
|
|
|
41
46
|
void this.#throttler.schedule(this.#boundUpdate);
|
|
42
47
|
}
|
|
@@ -44,25 +49,44 @@ export class ScopeChainModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
|
44
49
|
dispose(): void {
|
|
45
50
|
this.#callFrame.debuggerModel.removeEventListener(
|
|
46
51
|
SDK.DebuggerModel.Events.DebugInfoAttached, this.#debugInfoAttached, this);
|
|
47
|
-
this.#callFrame.debuggerModel.sourceMapManager().removeEventListener(
|
|
48
|
-
|
|
52
|
+
this.#callFrame.debuggerModel.sourceMapManager().removeEventListener(SDK.SourceMapManager.Events.SourceMapAttached,
|
|
53
|
+
this.#sourceMapChanged, this);
|
|
54
|
+
this.#callFrame.debuggerModel.sourceMapManager().removeEventListener(SDK.SourceMapManager.Events.SourceMapDetached,
|
|
55
|
+
this.#sourceMapChanged, this);
|
|
49
56
|
this.listeners?.clear();
|
|
50
57
|
}
|
|
51
58
|
|
|
59
|
+
static resolveScopeChain(callFrame: SDK.DebuggerModel.CallFrame,
|
|
60
|
+
debuggerWorkspaceBinding: Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding):
|
|
61
|
+
Promise<SDK.DebuggerModel.ScopeChainEntry[]> {
|
|
62
|
+
let cachedPromise = ScopeChainModel.#cachedScopeChainByCallFrame.get(callFrame);
|
|
63
|
+
if (!cachedPromise) {
|
|
64
|
+
cachedPromise = resolveScopeChain(callFrame, debuggerWorkspaceBinding);
|
|
65
|
+
ScopeChainModel.#cachedScopeChainByCallFrame.set(callFrame, cachedPromise);
|
|
66
|
+
}
|
|
67
|
+
return cachedPromise;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
resolveScopeChain(): Promise<SDK.DebuggerModel.ScopeChainEntry[]> {
|
|
71
|
+
return ScopeChainModel.resolveScopeChain(this.#callFrame, this.#debuggerWorkspaceBinding);
|
|
72
|
+
}
|
|
73
|
+
|
|
52
74
|
async #update(): Promise<void> {
|
|
53
|
-
const scopeChain = await resolveScopeChain(
|
|
75
|
+
const scopeChain = await this.resolveScopeChain();
|
|
54
76
|
this.dispatchEventToListeners(Events.SCOPE_CHAIN_UPDATED, new ScopeChain(scopeChain));
|
|
55
77
|
}
|
|
56
78
|
|
|
57
79
|
#debugInfoAttached(event: Common.EventTarget.EventTargetEvent<SDK.Script.Script>): void {
|
|
58
80
|
if (event.data === this.#callFrame.script) {
|
|
81
|
+
ScopeChainModel.#cachedScopeChainByCallFrame.delete(this.#callFrame);
|
|
59
82
|
void this.#throttler.schedule(this.#boundUpdate);
|
|
60
83
|
}
|
|
61
84
|
}
|
|
62
85
|
|
|
63
|
-
#
|
|
64
|
-
|
|
86
|
+
#sourceMapChanged(event: Common.EventTarget
|
|
87
|
+
.EventTargetEvent<{client: SDK.Script.Script, sourceMap: SDK.SourceMap.SourceMap}>): void {
|
|
65
88
|
if (event.data.client === this.#callFrame.script) {
|
|
89
|
+
ScopeChainModel.#cachedScopeChainByCallFrame.delete(this.#callFrame);
|
|
66
90
|
void this.#throttler.schedule(this.#boundUpdate);
|
|
67
91
|
}
|
|
68
92
|
}
|
|
@@ -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
|
+
}
|
|
@@ -391,9 +391,8 @@ function toolbarView(input: ToolbarViewInput): Lit.LitTemplate {
|
|
|
391
391
|
@click=${input.onNewChatClick}></devtools-button>
|
|
392
392
|
<div class="toolbar-divider"></div>
|
|
393
393
|
<devtools-menu-button
|
|
394
|
-
title=${i18nString(UIStrings.history)}
|
|
395
|
-
aria-label=${i18nString(UIStrings.history)}
|
|
396
394
|
.iconName=${'history'}
|
|
395
|
+
.accessibleLabel=${i18nString(UIStrings.history)}
|
|
397
396
|
.jslogContext=${'freestyler.history'}
|
|
398
397
|
.populateMenuCall=${input.populateHistoryMenu}
|
|
399
398
|
></devtools-menu-button>`
|
|
@@ -35,22 +35,18 @@ const UIStrings = {
|
|
|
35
35
|
* the current context.
|
|
36
36
|
*/
|
|
37
37
|
debugWithAi: 'Debug with AI',
|
|
38
|
-
/**
|
|
39
|
-
* @description The title of the Gemini panel.
|
|
40
|
-
*/
|
|
41
|
-
gemini: 'Gemini',
|
|
42
38
|
/**
|
|
43
39
|
* @description The title of the command menu action for showing the Gemini panel.
|
|
44
40
|
*/
|
|
45
|
-
showGemini: 'Show Gemini',
|
|
41
|
+
showGemini: 'Show `Gemini`',
|
|
46
42
|
/**
|
|
47
43
|
* @description The setting title to enable the Gemini via the settings tab.
|
|
48
44
|
*/
|
|
49
|
-
enableGemini: 'Enable Gemini',
|
|
45
|
+
enableGemini: 'Enable `Gemini`',
|
|
50
46
|
/**
|
|
51
47
|
* @description Text of a context menu item to redirect to the Gemini panel with the current context.
|
|
52
48
|
*/
|
|
53
|
-
debugWithGemini: 'Debug with Gemini',
|
|
49
|
+
debugWithGemini: 'Debug with `Gemini`',
|
|
54
50
|
} as const;
|
|
55
51
|
|
|
56
52
|
const str_ = i18n.i18n.registerUIStrings('panels/ai_assistance/ai_assistance-meta.ts', UIStrings);
|
|
@@ -108,7 +104,8 @@ UI.ViewManager.registerViewExtension({
|
|
|
108
104
|
location: UI.ViewManager.ViewLocationValues.DRAWER_VIEW,
|
|
109
105
|
id: 'freestyler',
|
|
110
106
|
commandPrompt: i18nAiBrandedString(UIStrings.showGemini, UIStrings.showAiAssistance),
|
|
111
|
-
title:
|
|
107
|
+
title: () => Root.Runtime.hostConfig.devToolsGeminiRebranding?.enabled ? i18n.i18n.lockedString('Gemini') :
|
|
108
|
+
i18nString(UIStrings.aiAssistance),
|
|
112
109
|
order: 10,
|
|
113
110
|
persistence: UI.ViewManager.ViewPersistence.CLOSEABLE,
|
|
114
111
|
hasToolbar: false,
|
|
@@ -72,7 +72,7 @@ const UIStrings = {
|
|
|
72
72
|
/**
|
|
73
73
|
* @description Empty buffer hint text content in the animation timeline of the Animations panel that explains the panel.
|
|
74
74
|
*/
|
|
75
|
-
animationDescription: 'On this page you can inspect and modify animations
|
|
75
|
+
animationDescription: 'On this page you can inspect and modify animations',
|
|
76
76
|
/**
|
|
77
77
|
* @description Tooltip text that appears when hovering over largeicon replay animation button in the animation timeline of the Animations panel.
|
|
78
78
|
*/
|