chrome-devtools-frontend 1.0.1534717 → 1.0.1536371
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/docs/contributing/images/issues-nearestslo.png +0 -0
- package/docs/contributing/issues.md +32 -58
- package/eslint.config.mjs +1 -0
- package/front_end/core/common/Console.ts +1 -8
- package/front_end/core/common/ParsedURL.ts +10 -20
- package/front_end/core/common/SegmentedRange.ts +1 -2
- package/front_end/core/common/StringOutputStream.ts +1 -4
- package/front_end/core/host/InspectorFrontendHost.ts +6 -0
- package/front_end/core/host/UserMetrics.ts +5 -1
- package/front_end/core/i18n/i18nImpl.ts +0 -24
- package/front_end/core/protocol_client/CDPConnection.ts +53 -5
- package/front_end/core/protocol_client/protocol_client.ts +2 -0
- package/front_end/core/sdk/AnimationModel.ts +1 -2
- package/front_end/core/sdk/CSSMatchedStyles.ts +2 -2
- package/front_end/core/sdk/CSSModel.ts +1 -1
- package/front_end/core/sdk/CSSProperty.ts +3 -6
- package/front_end/core/sdk/CSSStyleDeclaration.ts +4 -4
- package/front_end/core/sdk/DebuggerModel.ts +1 -2
- package/front_end/core/sdk/EnhancedTracesParser.ts +4 -0
- package/front_end/core/sdk/SourceMap.ts +2 -3
- package/front_end/devtools_compatibility.js +32 -24
- package/front_end/entrypoints/node_app/NodeConnectionsPanel.ts +2 -1
- package/front_end/generated/InspectorBackendCommands.js +1 -2
- package/front_end/generated/SupportedCSSProperties.js +57 -0
- package/front_end/generated/protocol.ts +0 -27
- package/front_end/panels/accessibility/AccessibilityNodeView.ts +18 -17
- package/front_end/panels/accessibility/AccessibilitySidebarView.ts +9 -12
- package/front_end/panels/ai_assistance/PatchWidget.ts +39 -40
- package/front_end/panels/ai_assistance/components/ChatView.ts +5 -4
- package/front_end/panels/ai_assistance/components/ExploreWidget.ts +0 -2
- package/front_end/panels/application/AppManifestView.ts +7 -6
- package/front_end/panels/application/ApplicationPanelSidebar.ts +4 -4
- package/front_end/panels/application/OpenedWindowDetailsView.ts +6 -6
- package/front_end/panels/application/StorageView.ts +9 -8
- package/front_end/panels/application/components/BackForwardCacheView.ts +333 -314
- package/front_end/panels/application/components/ProtocolHandlersView.ts +3 -2
- package/front_end/panels/application/preloading/components/PreloadingDisabledInfobar.ts +2 -1
- package/front_end/panels/autofill/AutofillView.ts +2 -3
- package/front_end/panels/browser_debugger/ObjectEventListenersSidebarPane.ts +8 -8
- package/front_end/panels/changes/CombinedDiffView.ts +13 -14
- package/front_end/panels/common/BadgeNotification.ts +2 -1
- package/front_end/panels/common/GdpSignUpDialog.ts +2 -1
- package/front_end/panels/console/ConsoleInsightTeaser.ts +13 -2
- package/front_end/panels/console/ConsolePinPane.ts +12 -7
- package/front_end/panels/console/ConsoleView.ts +1 -0
- package/front_end/panels/console/consoleView.css +0 -1
- package/front_end/panels/developer_resources/DeveloperResourcesView.ts +9 -9
- package/front_end/panels/elements/ComputedStyleWidget.ts +7 -7
- package/front_end/panels/elements/ElementsTreeOutline.ts +1 -1
- package/front_end/panels/elements/EventListenersWidget.ts +9 -9
- package/front_end/panels/elements/NodeStackTraceWidget.ts +6 -6
- package/front_end/panels/elements/PlatformFontsWidget.ts +5 -5
- package/front_end/panels/elements/PropertiesWidget.ts +8 -8
- package/front_end/panels/layer_viewer/Layers3DView.ts +2 -1
- package/front_end/panels/layer_viewer/PaintProfilerView.ts +3 -3
- package/front_end/panels/network/RequestCookiesView.ts +2 -1
- package/front_end/panels/network/RequestTimingView.ts +2 -1
- package/front_end/panels/network/components/DirectSocketConnectionView.ts +4 -6
- package/front_end/panels/recorder/RecorderController.ts +34 -23
- package/front_end/panels/recorder/components/CreateRecordingView.ts +249 -240
- package/front_end/panels/security/CookieControlsView.ts +74 -67
- package/front_end/panels/security/CookieReportView.ts +18 -16
- package/front_end/panels/security/IPProtectionView.ts +1 -2
- package/front_end/panels/security/SecurityPanel.ts +19 -19
- package/front_end/panels/settings/AISettingsTab.ts +2 -1
- package/front_end/panels/settings/KeybindsSettingsTab.ts +6 -0
- package/front_end/panels/settings/components/SyncSection.ts +2 -1
- package/front_end/panels/sources/DebuggerPausedMessage.ts +4 -3
- package/front_end/panels/sources/ResourceOriginPlugin.ts +3 -2
- package/front_end/panels/sources/SourcesNavigator.ts +2 -1
- package/front_end/panels/sources/TabbedEditorContainer.ts +3 -2
- package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +9 -9
- package/front_end/panels/timeline/TimelineSelectorStatsView.ts +36 -36
- package/front_end/panels/timeline/TimelineUIUtils.ts +3 -2
- package/front_end/panels/timeline/components/DetailsView.ts +5 -4
- package/front_end/panels/timeline/components/FieldSettingsDialog.ts +2 -1
- package/front_end/panels/timeline/components/LiveMetricsView.ts +5 -4
- package/front_end/panels/timeline/components/MetricCompareStrings.ts +25 -24
- package/front_end/panels/timeline/components/SidebarAnnotationsTab.ts +1 -2
- package/front_end/panels/timeline/components/insights/LCPDiscovery.ts +2 -1
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/ui/components/docs/tooltip/basic.ts +1 -1
- package/front_end/ui/components/tooltips/Tooltip.ts +32 -17
- package/front_end/ui/i18n/i18n.ts +31 -0
- package/front_end/ui/legacy/SoftDropDown.ts +1 -12
- package/front_end/ui/legacy/ViewManager.ts +2 -4
- package/front_end/ui/legacy/Widget.ts +33 -17
- package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +2 -1
- package/front_end/ui/legacy/legacy.ts +0 -2
- package/front_end/ui/visual_logging/KnownContextValues.ts +5 -0
- package/mcp/mcp.ts +1 -0
- package/package.json +1 -1
- package/front_end/ui/components/docs/recorder_create_recording_view/basic.html +0 -20
- package/front_end/ui/components/docs/recorder_create_recording_view/basic.ts +0 -27
- package/front_end/ui/legacy/ThrottledWidget.ts +0 -48
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// Copyright 2024 The Chromium Authors
|
|
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
|
-
/* eslint-disable @devtools/no-lit-render-outside-of-view */
|
|
5
4
|
|
|
6
5
|
import '../../ui/components/switch/switch.js';
|
|
7
6
|
import '../../ui/components/cards/cards.js';
|
|
@@ -14,15 +13,15 @@ import type * as Platform from '../../core/platform/platform.js';
|
|
|
14
13
|
import * as Root from '../../core/root/root.js';
|
|
15
14
|
import * as SDK from '../../core/sdk/sdk.js';
|
|
16
15
|
import * as Buttons from '../../ui/components/buttons/buttons.js';
|
|
17
|
-
import * as ChromeLink from '../../ui/components/chrome_link/chrome_link.js';
|
|
18
16
|
import * as Input from '../../ui/components/input/input.js';
|
|
17
|
+
import * as uiI18n from '../../ui/i18n/i18n.js';
|
|
19
18
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
20
|
-
import
|
|
19
|
+
import {Directives, html, nothing, render, type TemplateResult} from '../../ui/lit/lit.js';
|
|
21
20
|
import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
|
|
22
21
|
|
|
23
22
|
import cookieControlsViewStyles from './cookieControlsView.css.js';
|
|
24
23
|
|
|
25
|
-
const {
|
|
24
|
+
const {ref} = Directives;
|
|
26
25
|
|
|
27
26
|
const UIStrings = {
|
|
28
27
|
/**
|
|
@@ -115,55 +114,53 @@ const UIStrings = {
|
|
|
115
114
|
|
|
116
115
|
const str_ = i18n.i18n.registerUIStrings('panels/security/CookieControlsView.ts', UIStrings);
|
|
117
116
|
export const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
118
|
-
export const i18nFormatString =
|
|
117
|
+
export const i18nFormatString = uiI18n.getFormatLocalizedString.bind(undefined, str_);
|
|
119
118
|
|
|
120
119
|
export interface ViewInput {
|
|
120
|
+
thirdPartyControlsDict: Root.Runtime.HostConfig['thirdPartyCookieControls'];
|
|
121
|
+
isGracePeriodActive: boolean;
|
|
121
122
|
inputChanged: (newValue: boolean, setting: Common.Settings.Setting<boolean>) => void;
|
|
122
123
|
openChromeCookieSettings: () => void;
|
|
123
124
|
}
|
|
124
125
|
|
|
125
126
|
export type View = (input: ViewInput, output: object, target: HTMLElement) => void;
|
|
126
127
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
128
|
+
function getChromeFlagsLink(flag: string): TemplateResult {
|
|
129
|
+
return html`
|
|
130
|
+
<devtools-chrome-link href="chrome://flags/#${flag}" tabindex="0">
|
|
131
|
+
${flag}
|
|
132
|
+
</devtools-chrome-link>`;
|
|
130
133
|
}
|
|
134
|
+
const DEFAULT_VIEW: View = (input: ViewInput, _output: object, target: HTMLElement): void => {
|
|
135
|
+
// createSetting() allows us to initialize the settings with the UI binding values the first
|
|
136
|
+
// time that the browser starts, and use the existing setting value for all subsequent uses.
|
|
137
|
+
const enterpriseEnabledSetting = Common.Settings.Settings.instance().createSetting(
|
|
138
|
+
'enterprise-enabled',
|
|
139
|
+
input.thirdPartyControlsDict && input.thirdPartyControlsDict.managedBlockThirdPartyCookies &&
|
|
140
|
+
typeof input.thirdPartyControlsDict.managedBlockThirdPartyCookies === 'boolean' ?
|
|
141
|
+
input.thirdPartyControlsDict.managedBlockThirdPartyCookies :
|
|
142
|
+
false,
|
|
143
|
+
Common.Settings.SettingStorageType.GLOBAL);
|
|
144
|
+
const toggleEnabledSetting = Common.Settings.Settings.instance().createSetting(
|
|
145
|
+
'cookie-control-override-enabled',
|
|
146
|
+
input.thirdPartyControlsDict?.thirdPartyCookieRestrictionEnabled ?
|
|
147
|
+
input.thirdPartyControlsDict.thirdPartyCookieRestrictionEnabled :
|
|
148
|
+
false,
|
|
149
|
+
Common.Settings.SettingStorageType.GLOBAL);
|
|
150
|
+
const gracePeriodDisabledSetting = Common.Settings.Settings.instance().createSetting(
|
|
151
|
+
'grace-period-mitigation-disabled',
|
|
152
|
+
input.thirdPartyControlsDict?.thirdPartyCookieMetadataEnabled ?
|
|
153
|
+
input.thirdPartyControlsDict.thirdPartyCookieMetadataEnabled :
|
|
154
|
+
true,
|
|
155
|
+
Common.Settings.SettingStorageType.GLOBAL);
|
|
156
|
+
const heuristicsDisabledSetting = Common.Settings.Settings.instance().createSetting(
|
|
157
|
+
'heuristic-mitigation-disabled',
|
|
158
|
+
input.thirdPartyControlsDict?.thirdPartyCookieHeuristicsEnabled ?
|
|
159
|
+
input.thirdPartyControlsDict.thirdPartyCookieHeuristicsEnabled :
|
|
160
|
+
true,
|
|
161
|
+
Common.Settings.SettingStorageType.GLOBAL);
|
|
131
162
|
|
|
132
|
-
|
|
133
|
-
#view: View;
|
|
134
|
-
#isGracePeriodActive: boolean;
|
|
135
|
-
#thirdPartyControlsDict: Root.Runtime.HostConfig['thirdPartyCookieControls'];
|
|
136
|
-
|
|
137
|
-
constructor(element?: HTMLElement, view: View = (input, _, target) => {
|
|
138
|
-
// createSetting() allows us to initialize the settings with the UI binding values the first
|
|
139
|
-
// time that the browser starts, and use the existing setting value for all subsequent uses.
|
|
140
|
-
const enterpriseEnabledSetting = Common.Settings.Settings.instance().createSetting(
|
|
141
|
-
'enterprise-enabled',
|
|
142
|
-
this.#thirdPartyControlsDict && this.#thirdPartyControlsDict.managedBlockThirdPartyCookies &&
|
|
143
|
-
typeof this.#thirdPartyControlsDict.managedBlockThirdPartyCookies === 'boolean' ?
|
|
144
|
-
this.#thirdPartyControlsDict.managedBlockThirdPartyCookies :
|
|
145
|
-
false,
|
|
146
|
-
Common.Settings.SettingStorageType.GLOBAL);
|
|
147
|
-
const toggleEnabledSetting = Common.Settings.Settings.instance().createSetting(
|
|
148
|
-
'cookie-control-override-enabled',
|
|
149
|
-
this.#thirdPartyControlsDict && this.#thirdPartyControlsDict.thirdPartyCookieRestrictionEnabled ?
|
|
150
|
-
this.#thirdPartyControlsDict.thirdPartyCookieRestrictionEnabled :
|
|
151
|
-
false,
|
|
152
|
-
Common.Settings.SettingStorageType.GLOBAL);
|
|
153
|
-
const gracePeriodDisabledSetting = Common.Settings.Settings.instance().createSetting(
|
|
154
|
-
'grace-period-mitigation-disabled',
|
|
155
|
-
this.#thirdPartyControlsDict && this.#thirdPartyControlsDict.thirdPartyCookieMetadataEnabled ?
|
|
156
|
-
this.#thirdPartyControlsDict.thirdPartyCookieMetadataEnabled :
|
|
157
|
-
true,
|
|
158
|
-
Common.Settings.SettingStorageType.GLOBAL);
|
|
159
|
-
const heuristicsDisabledSetting = Common.Settings.Settings.instance().createSetting(
|
|
160
|
-
'heuristic-mitigation-disabled',
|
|
161
|
-
this.#thirdPartyControlsDict && this.#thirdPartyControlsDict.thirdPartyCookieHeuristicsEnabled ?
|
|
162
|
-
this.#thirdPartyControlsDict.thirdPartyCookieHeuristicsEnabled :
|
|
163
|
-
true,
|
|
164
|
-
Common.Settings.SettingStorageType.GLOBAL);
|
|
165
|
-
|
|
166
|
-
// clang-format off
|
|
163
|
+
// clang-format off
|
|
167
164
|
const cardHeader = html `
|
|
168
165
|
<div class="card-header">
|
|
169
166
|
<div class="lhs">
|
|
@@ -175,11 +172,11 @@ export class CookieControlsView extends UI.Widget.VBox {
|
|
|
175
172
|
<devtools-icon
|
|
176
173
|
tabindex="0"
|
|
177
174
|
name="domain"
|
|
178
|
-
${
|
|
175
|
+
${ref((el: Element|undefined) => {
|
|
179
176
|
UI.Tooltip.Tooltip.install(el as HTMLElement, i18nString(UIStrings.enterpriseTooltip));
|
|
180
177
|
(el as HTMLElement).role = 'img';
|
|
181
178
|
})}>
|
|
182
|
-
</devtools-icon>` :
|
|
179
|
+
</devtools-icon>` : nothing
|
|
183
180
|
}
|
|
184
181
|
</div>
|
|
185
182
|
<div>
|
|
@@ -197,8 +194,8 @@ export class CookieControlsView extends UI.Widget.VBox {
|
|
|
197
194
|
`;
|
|
198
195
|
|
|
199
196
|
const gracePeriodControlDisabled =
|
|
200
|
-
(
|
|
201
|
-
enterpriseEnabledSetting.get() || !toggleEnabledSetting.get() || !
|
|
197
|
+
(input.thirdPartyControlsDict ? (!input.thirdPartyControlsDict.thirdPartyCookieMetadataEnabled) : false) ||
|
|
198
|
+
enterpriseEnabledSetting.get() || !toggleEnabledSetting.get() || !input.isGracePeriodActive;
|
|
202
199
|
const gracePeriodControl = html`
|
|
203
200
|
<div class="card-row">
|
|
204
201
|
<label class='checkbox-label'>
|
|
@@ -215,11 +212,11 @@ export class CookieControlsView extends UI.Widget.VBox {
|
|
|
215
212
|
i18nFormatString(UIStrings.gracePeriodExplanation, {
|
|
216
213
|
PH1: i18nString(UIStrings.gracePeriod),
|
|
217
214
|
}) :
|
|
218
|
-
(
|
|
215
|
+
(input.thirdPartyControlsDict ? !input.thirdPartyControlsDict?.thirdPartyCookieMetadataEnabled: false) ?
|
|
219
216
|
i18nFormatString(UIStrings.enableFlag, {
|
|
220
|
-
PH1:
|
|
217
|
+
PH1: getChromeFlagsLink(UIStrings.tpcdMetadataGrants),
|
|
221
218
|
}) :
|
|
222
|
-
i18nFormatString(
|
|
219
|
+
i18nFormatString(input.isGracePeriodActive ? UIStrings.gracePeriodExplanation : UIStrings.enrollGracePeriod, {
|
|
223
220
|
PH1: UI.Fragment.html`<x-link class="devtools-link" href="https://developers.google.com/privacy-sandbox/cookies/temporary-exceptions/grace-period" jslog=${VisualLogging.link('grace-period-link').track({click: true})}>${i18nString(UIStrings.gracePeriod)}</x-link>`,
|
|
224
221
|
})
|
|
225
222
|
}
|
|
@@ -230,7 +227,7 @@ export class CookieControlsView extends UI.Widget.VBox {
|
|
|
230
227
|
`;
|
|
231
228
|
|
|
232
229
|
const heuristicsControlDisabled =
|
|
233
|
-
(
|
|
230
|
+
(input.thirdPartyControlsDict ? (!input.thirdPartyControlsDict.thirdPartyCookieHeuristicsEnabled) : false) ||
|
|
234
231
|
enterpriseEnabledSetting.get() || !toggleEnabledSetting.get();
|
|
235
232
|
const heuristicControl = html`
|
|
236
233
|
<div class="card-row">
|
|
@@ -248,9 +245,9 @@ export class CookieControlsView extends UI.Widget.VBox {
|
|
|
248
245
|
i18nFormatString(UIStrings.heuristicExplanation, {
|
|
249
246
|
PH1: i18nString(UIStrings.scenarios),
|
|
250
247
|
}) :
|
|
251
|
-
(
|
|
248
|
+
(input.thirdPartyControlsDict ? !input.thirdPartyControlsDict.thirdPartyCookieHeuristicsEnabled: false) ?
|
|
252
249
|
i18nFormatString(UIStrings.enableFlag, {
|
|
253
|
-
PH1:
|
|
250
|
+
PH1: getChromeFlagsLink(UIStrings.tpcdHeuristicsGrants),
|
|
254
251
|
}) :
|
|
255
252
|
i18nFormatString(UIStrings.heuristicExplanation, {
|
|
256
253
|
PH1: UI.Fragment.html`<x-link class="devtools-link" href="https://developers.google.com/privacy-sandbox/cookies/temporary-exceptions/heuristics-based-exceptions" jslog=${VisualLogging.link('heuristic-link').track({click: true})}>${i18nString(UIStrings.scenarios)}</x-link>`,
|
|
@@ -300,12 +297,24 @@ export class CookieControlsView extends UI.Widget.VBox {
|
|
|
300
297
|
</div>
|
|
301
298
|
</div>
|
|
302
299
|
</devtools-card>
|
|
303
|
-
${Boolean(enterpriseEnabledSetting.get()) ? enterpriseDisclaimer :
|
|
300
|
+
${Boolean(enterpriseEnabledSetting.get()) ? enterpriseDisclaimer : nothing}
|
|
304
301
|
</div>
|
|
305
302
|
</div>
|
|
306
|
-
`, target
|
|
307
|
-
|
|
308
|
-
|
|
303
|
+
`, target);
|
|
304
|
+
// clang-format on
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
export function showInfobar(): void {
|
|
308
|
+
UI.InspectorView.InspectorView.instance().displayDebuggedTabReloadRequiredWarning(
|
|
309
|
+
i18nString(UIStrings.siteReloadMessage));
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
export class CookieControlsView extends UI.Widget.VBox {
|
|
313
|
+
#view: View;
|
|
314
|
+
#isGracePeriodActive: boolean;
|
|
315
|
+
#thirdPartyControlsDict: Root.Runtime.HostConfig['thirdPartyCookieControls'];
|
|
316
|
+
|
|
317
|
+
constructor(element?: HTMLElement, view: View = DEFAULT_VIEW) {
|
|
309
318
|
super(element, {useShadowDom: true});
|
|
310
319
|
this.#view = view;
|
|
311
320
|
this.#isGracePeriodActive = false;
|
|
@@ -327,7 +336,14 @@ export class CookieControlsView extends UI.Widget.VBox {
|
|
|
327
336
|
}
|
|
328
337
|
|
|
329
338
|
override performUpdate(): void {
|
|
330
|
-
this.#view(
|
|
339
|
+
this.#view(
|
|
340
|
+
{
|
|
341
|
+
thirdPartyControlsDict: this.#thirdPartyControlsDict,
|
|
342
|
+
isGracePeriodActive: this.#isGracePeriodActive,
|
|
343
|
+
inputChanged: this.inputChanged.bind(this),
|
|
344
|
+
openChromeCookieSettings: this.openChromeCookieSettings.bind(this),
|
|
345
|
+
},
|
|
346
|
+
this, this.contentElement);
|
|
331
347
|
}
|
|
332
348
|
|
|
333
349
|
inputChanged(newValue: boolean, setting: Common.Settings.Setting<boolean>): void {
|
|
@@ -390,13 +406,4 @@ export class CookieControlsView extends UI.Widget.VBox {
|
|
|
390
406
|
this.requestUpdate();
|
|
391
407
|
}
|
|
392
408
|
}
|
|
393
|
-
|
|
394
|
-
getChromeFlagsLink(flag: string): Element {
|
|
395
|
-
const link = new ChromeLink.ChromeLink.ChromeLink();
|
|
396
|
-
link.textContent = flag;
|
|
397
|
-
link.href = ('chrome://flags/' + flag) as Platform.DevToolsPath.UrlString;
|
|
398
|
-
link.setAttribute('tabindex', '0');
|
|
399
|
-
|
|
400
|
-
return link;
|
|
401
|
-
}
|
|
402
409
|
}
|
|
@@ -12,6 +12,7 @@ import * as SDK from '../../core/sdk/sdk.js';
|
|
|
12
12
|
import * as Protocol from '../../generated/protocol.js';
|
|
13
13
|
import * as IssuesManager from '../../models/issues_manager/issues_manager.js';
|
|
14
14
|
import type * as TextUtils from '../../models/text_utils/text_utils.js';
|
|
15
|
+
import * as uiI18n from '../../ui/i18n/i18n.js';
|
|
15
16
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
16
17
|
import * as Lit from '../../ui/lit/lit.js';
|
|
17
18
|
import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
|
|
@@ -196,17 +197,8 @@ export interface CookieReportNodeData {
|
|
|
196
197
|
}
|
|
197
198
|
|
|
198
199
|
export type View = (input: ViewInput, output: ViewOutput, target: HTMLElement) => void;
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
#issuesManager?: IssuesManager.IssuesManager.IssuesManager;
|
|
202
|
-
namedBitSetFilterUI?: UI.FilterBar.NamedBitSetFilterUI;
|
|
203
|
-
#cookieRows = new Map<string, IssuesManager.CookieIssue.CookieReportInfo>();
|
|
204
|
-
#view: View;
|
|
205
|
-
filterItems: UI.FilterBar.Item[] = [];
|
|
206
|
-
searchText: string;
|
|
207
|
-
|
|
208
|
-
constructor(element?: HTMLElement, view: View = (input, output, target) => {
|
|
209
|
-
// clang-format off
|
|
200
|
+
const DEFAULT_VIEW: View = (input, output, target) => {
|
|
201
|
+
// clang-format off
|
|
210
202
|
render(html `
|
|
211
203
|
<div class="report overflow-auto">
|
|
212
204
|
<div class="header">
|
|
@@ -283,9 +275,19 @@ export class CookieReportView extends UI.Widget.VBox {
|
|
|
283
275
|
}
|
|
284
276
|
|
|
285
277
|
</div>
|
|
286
|
-
`, target
|
|
287
|
-
|
|
288
|
-
|
|
278
|
+
`, target);
|
|
279
|
+
// clang-format on
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
export class CookieReportView extends UI.Widget.VBox {
|
|
283
|
+
#issuesManager?: IssuesManager.IssuesManager.IssuesManager;
|
|
284
|
+
namedBitSetFilterUI?: UI.FilterBar.NamedBitSetFilterUI;
|
|
285
|
+
#cookieRows = new Map<string, IssuesManager.CookieIssue.CookieReportInfo>();
|
|
286
|
+
#view: View;
|
|
287
|
+
filterItems: UI.FilterBar.Item[] = [];
|
|
288
|
+
searchText: string;
|
|
289
|
+
|
|
290
|
+
constructor(element?: HTMLElement, view: View = DEFAULT_VIEW) {
|
|
289
291
|
super(element, {useShadowDom: true});
|
|
290
292
|
this.#view = view;
|
|
291
293
|
this.registerRequiredCSS(cookieReportViewStyles);
|
|
@@ -447,7 +449,7 @@ export class CookieReportView extends UI.Widget.VBox {
|
|
|
447
449
|
'https://github.com/privacysandbox/privacy-sandbox-dev-support/blob/main/3pc-migration-readiness.md',
|
|
448
450
|
i18nString(UIStrings.guidance), undefined, undefined, 'readiness-list-link');
|
|
449
451
|
|
|
450
|
-
return html`${
|
|
452
|
+
return html`${uiI18n.getFormatLocalizedString(str_, UIStrings.gitHubResource, {
|
|
451
453
|
PH1: githubLink,
|
|
452
454
|
})}`;
|
|
453
455
|
}
|
|
@@ -460,7 +462,7 @@ export class CookieReportView extends UI.Widget.VBox {
|
|
|
460
462
|
(domain.charAt(0) === '.' ? domain.substring(1) : domain),
|
|
461
463
|
i18nString(UIStrings.reportedIssues), undefined, undefined, 'compatibility-lookup-link');
|
|
462
464
|
|
|
463
|
-
return html`${
|
|
465
|
+
return html`${uiI18n.getFormatLocalizedString(str_, UIStrings.gracePeriod, {
|
|
464
466
|
PH1: gracePeriodLink,
|
|
465
467
|
})}`;
|
|
466
468
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// Copyright 2025 The Chromium Authors
|
|
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
|
-
/* eslint-disable @devtools/no-lit-render-outside-of-view */
|
|
5
4
|
|
|
6
5
|
import '../../ui/components/switch/switch.js';
|
|
7
6
|
import '../../ui/components/cards/cards.js';
|
|
@@ -136,7 +135,7 @@ export interface ViewInput {
|
|
|
136
135
|
}
|
|
137
136
|
export type View = (input: ViewInput, output: object, target: HTMLElement) => void;
|
|
138
137
|
|
|
139
|
-
export const DEFAULT_VIEW: View = (input,
|
|
138
|
+
export const DEFAULT_VIEW: View = (input, _output, target) => {
|
|
140
139
|
const {status} = input;
|
|
141
140
|
const statusText = status ? i18nString(UIStrings[status]) : i18nString(UIStrings.statusUnknown);
|
|
142
141
|
|
|
@@ -2,7 +2,6 @@
|
|
|
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
|
/* eslint-disable @devtools/no-imperative-dom-api */
|
|
5
|
-
/* eslint-disable @devtools/no-lit-render-outside-of-view */
|
|
6
5
|
|
|
7
6
|
import * as Common from '../../core/common/common.js';
|
|
8
7
|
import * as Host from '../../core/host/host.js';
|
|
@@ -549,6 +548,24 @@ export interface ViewOutput {
|
|
|
549
548
|
|
|
550
549
|
export type View = (input: ViewInput, output: ViewOutput, target: HTMLElement) => void;
|
|
551
550
|
|
|
551
|
+
const DEFAULT_VIEW: View = (input: ViewInput, output: ViewOutput, target: HTMLElement): void => {
|
|
552
|
+
// clang-format off
|
|
553
|
+
render(html`
|
|
554
|
+
<devtools-split-view direction="column" name="security"
|
|
555
|
+
${UI.Widget.widgetRef(UI.SplitWidget.SplitWidget, e => {output.splitWidget = e;})}>
|
|
556
|
+
<devtools-widget
|
|
557
|
+
slot="sidebar"
|
|
558
|
+
.widgetConfig=${widgetConfig(SecurityPanelSidebar)}
|
|
559
|
+
@showIPProtection=${() => output.setVisibleView(new IPProtectionView())}
|
|
560
|
+
@showCookieReport=${()=>output.setVisibleView(new CookieReportView())}
|
|
561
|
+
@showFlagControls=${() => output.setVisibleView(new CookieControlsView())}
|
|
562
|
+
${UI.Widget.widgetRef(SecurityPanelSidebar, e => {output.sidebar = e;})}>
|
|
563
|
+
</devtools-widget>
|
|
564
|
+
</devtools-split-view>`,
|
|
565
|
+
target);
|
|
566
|
+
// clang-format on
|
|
567
|
+
};
|
|
568
|
+
|
|
552
569
|
export class SecurityPanel extends UI.Panel.Panel implements SDK.TargetManager.SDKModelObserver<SecurityModel> {
|
|
553
570
|
readonly mainView: SecurityMainView;
|
|
554
571
|
readonly sidebar!: SecurityPanelSidebar;
|
|
@@ -560,24 +577,7 @@ export class SecurityPanel extends UI.Panel.Panel implements SDK.TargetManager.S
|
|
|
560
577
|
private securityModel: SecurityModel|null;
|
|
561
578
|
readonly splitWidget!: UI.SplitWidget.SplitWidget;
|
|
562
579
|
|
|
563
|
-
constructor(private view: View =
|
|
564
|
-
// clang-format off
|
|
565
|
-
render(
|
|
566
|
-
html`
|
|
567
|
-
<devtools-split-view direction="column" name="security"
|
|
568
|
-
${UI.Widget.widgetRef(UI.SplitWidget.SplitWidget, e => {output.splitWidget = e;})}>
|
|
569
|
-
<devtools-widget
|
|
570
|
-
slot="sidebar"
|
|
571
|
-
.widgetConfig=${widgetConfig(SecurityPanelSidebar)}
|
|
572
|
-
@showIPProtection=${() => output.setVisibleView(new IPProtectionView())}
|
|
573
|
-
@showCookieReport=${()=>output.setVisibleView(new CookieReportView())}
|
|
574
|
-
@showFlagControls=${() => output.setVisibleView(new CookieControlsView())}
|
|
575
|
-
${UI.Widget.widgetRef(SecurityPanelSidebar, e => {output.sidebar = e;})}>
|
|
576
|
-
</devtools-widget>
|
|
577
|
-
</devtools-split-view>`,
|
|
578
|
-
target, {host: this});
|
|
579
|
-
// clang-format on
|
|
580
|
-
}) {
|
|
580
|
+
constructor(private view: View = DEFAULT_VIEW) {
|
|
581
581
|
super('security');
|
|
582
582
|
|
|
583
583
|
this.update();
|
|
@@ -13,6 +13,7 @@ import * as Buttons from '../../ui/components/buttons/buttons.js';
|
|
|
13
13
|
import * as Input from '../../ui/components/input/input.js';
|
|
14
14
|
import * as LegacyWrapper from '../../ui/components/legacy_wrapper/legacy_wrapper.js';
|
|
15
15
|
import * as Switch from '../../ui/components/switch/switch.js';
|
|
16
|
+
import * as uiI18n from '../../ui/i18n/i18n.js';
|
|
16
17
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
17
18
|
import * as Lit from '../../ui/lit/lit.js';
|
|
18
19
|
import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
|
|
@@ -515,7 +516,7 @@ export class AISettingsTab extends LegacyWrapper.LegacyWrapper.WrappableComponen
|
|
|
515
516
|
},
|
|
516
517
|
{
|
|
517
518
|
icon: 'policy',
|
|
518
|
-
text: html`${
|
|
519
|
+
text: html`${uiI18n.getFormatLocalizedString(str_, UIStrings.termsOfServicePrivacyNotice, {
|
|
519
520
|
PH1: tosLink,
|
|
520
521
|
PH2: privacyNoticeLink,
|
|
521
522
|
})}`,
|
|
@@ -42,6 +42,11 @@ const UIStrings = {
|
|
|
42
42
|
* @description Link text in the settings pane to add another shortcut for an action
|
|
43
43
|
*/
|
|
44
44
|
addAShortcut: 'Add a shortcut',
|
|
45
|
+
/**
|
|
46
|
+
* @description Placeholder text in the settings pane when adding a new shortcut.
|
|
47
|
+
* Explaining that key strokes are going to be recoded.
|
|
48
|
+
*/
|
|
49
|
+
recordingKeys: 'Recoding keys',
|
|
45
50
|
/**
|
|
46
51
|
* @description Label for a button in the settings pane that confirms changes to a keyboard shortcut
|
|
47
52
|
*/
|
|
@@ -446,6 +451,7 @@ export class ShortcutListItem {
|
|
|
446
451
|
if (this.isEditing) {
|
|
447
452
|
const shortcutInput = shortcutElement.createChild('input', 'harmony-input');
|
|
448
453
|
shortcutInput.setAttribute('jslog', `${VisualLogging.textField().track({change: true})}`);
|
|
454
|
+
shortcutInput.setAttribute('placeholder', i18nString(UIStrings.recordingKeys));
|
|
449
455
|
shortcutInput.spellcheck = false;
|
|
450
456
|
shortcutInput.maxLength = 0;
|
|
451
457
|
this.shortcutInputs.set(shortcut, shortcutInput);
|
|
@@ -16,6 +16,7 @@ import * as Badges from '../../../models/badges/badges.js';
|
|
|
16
16
|
import * as Buttons from '../../../ui/components/buttons/buttons.js';
|
|
17
17
|
import * as ComponentHelpers from '../../../ui/components/helpers/helpers.js';
|
|
18
18
|
import type * as SettingsComponents from '../../../ui/components/settings/settings.js';
|
|
19
|
+
import * as uiI18n from '../../../ui/i18n/i18n.js';
|
|
19
20
|
import * as Lit from '../../../ui/lit/lit.js';
|
|
20
21
|
import * as VisualLogging from '../../../ui/visual_logging/visual_logging.js';
|
|
21
22
|
import * as PanelCommon from '../../common/common.js';
|
|
@@ -112,7 +113,7 @@ function renderDataDisclaimer(): HTMLElement {
|
|
|
112
113
|
|
|
113
114
|
const container = document.createElement('span');
|
|
114
115
|
Lit.render(relevantDataTooltipTemplate, container);
|
|
115
|
-
cachedTooltipElement =
|
|
116
|
+
cachedTooltipElement = uiI18n.getFormatLocalizedString(str_, UIStrings.dataDisclaimer, {
|
|
116
117
|
PH1: container,
|
|
117
118
|
});
|
|
118
119
|
return cachedTooltipElement;
|
|
@@ -11,6 +11,7 @@ import * as Protocol from '../../generated/protocol.js';
|
|
|
11
11
|
import type * as Bindings from '../../models/bindings/bindings.js';
|
|
12
12
|
import type * as BreakpointManager from '../../models/breakpoints/breakpoints.js';
|
|
13
13
|
import * as IconButton from '../../ui/components/icon_button/icon_button.js';
|
|
14
|
+
import * as uiI18n from '../../ui/i18n/i18n.js';
|
|
14
15
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
15
16
|
import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
|
|
16
17
|
|
|
@@ -175,12 +176,12 @@ export class DebuggerPausedMessage {
|
|
|
175
176
|
let messageElement;
|
|
176
177
|
if (data.insertion) {
|
|
177
178
|
if (data.targetNode === data.node) {
|
|
178
|
-
messageElement =
|
|
179
|
+
messageElement = uiI18n.getFormatLocalizedString(str_, UIStrings.childSAdded, {PH1: targetNodeLink});
|
|
179
180
|
} else {
|
|
180
|
-
messageElement =
|
|
181
|
+
messageElement = uiI18n.getFormatLocalizedString(str_, UIStrings.descendantSAdded, {PH1: targetNodeLink});
|
|
181
182
|
}
|
|
182
183
|
} else {
|
|
183
|
-
messageElement =
|
|
184
|
+
messageElement = uiI18n.getFormatLocalizedString(str_, UIStrings.descendantSRemoved, {PH1: targetNodeLink});
|
|
184
185
|
}
|
|
185
186
|
subElement.appendChild(document.createElement('br'));
|
|
186
187
|
subElement.appendChild(messageElement);
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
import * as i18n from '../../core/i18n/i18n.js';
|
|
7
7
|
import * as Bindings from '../../models/bindings/bindings.js';
|
|
8
8
|
import type * as Workspace from '../../models/workspace/workspace.js';
|
|
9
|
+
import * as uiI18n from '../../ui/i18n/i18n.js';
|
|
9
10
|
import * as Components from '../../ui/legacy/components/utils/utils.js';
|
|
10
11
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
11
12
|
|
|
@@ -62,14 +63,14 @@ export class ResourceOriginPlugin extends Plugin {
|
|
|
62
63
|
}
|
|
63
64
|
element.append(link);
|
|
64
65
|
});
|
|
65
|
-
return [new UI.Toolbar.ToolbarItem(
|
|
66
|
+
return [new UI.Toolbar.ToolbarItem(uiI18n.getFormatLocalizedString(str_, UIStrings.fromS, {PH1: element}))];
|
|
66
67
|
}
|
|
67
68
|
|
|
68
69
|
// Handle anonymous scripts with an originStackTrace.
|
|
69
70
|
for (const script of debuggerWorkspaceBinding.scriptsForUISourceCode(this.uiSourceCode)) {
|
|
70
71
|
if (script.originStackTrace?.callFrames.length) {
|
|
71
72
|
const link = linkifier.linkifyStackTraceTopFrame(script.debuggerModel.target(), script.originStackTrace);
|
|
72
|
-
return [new UI.Toolbar.ToolbarItem(
|
|
73
|
+
return [new UI.Toolbar.ToolbarItem(uiI18n.getFormatLocalizedString(str_, UIStrings.fromS, {PH1: link}))];
|
|
73
74
|
}
|
|
74
75
|
}
|
|
75
76
|
|
|
@@ -15,6 +15,7 @@ import * as Bindings from '../../models/bindings/bindings.js';
|
|
|
15
15
|
import * as Persistence from '../../models/persistence/persistence.js';
|
|
16
16
|
import * as TextUtils from '../../models/text_utils/text_utils.js';
|
|
17
17
|
import * as Workspace from '../../models/workspace/workspace.js';
|
|
18
|
+
import * as uiI18n from '../../ui/i18n/i18n.js';
|
|
18
19
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
19
20
|
import * as Snippets from '../snippets/snippets.js';
|
|
20
21
|
|
|
@@ -190,7 +191,7 @@ export class FilesNavigatorView extends NavigatorView {
|
|
|
190
191
|
const link =
|
|
191
192
|
UI.XLink.XLink.create('https://goo.gle/devtools-automatic-workspace-folders', 'com.chrome.devtools.json');
|
|
192
193
|
this.#automaticFileSystemNudge =
|
|
193
|
-
|
|
194
|
+
uiI18n.getFormatLocalizedString(str_, UIStrings.automaticWorkspaceNudge, {PH1: link});
|
|
194
195
|
this.#automaticFileSystemNudge.classList.add('automatic-file-system-nudge');
|
|
195
196
|
this.contentElement.insertBefore(this.#automaticFileSystemNudge, this.contentElement.firstChild);
|
|
196
197
|
|
|
@@ -12,6 +12,7 @@ import * as Workspace from '../../models/workspace/workspace.js';
|
|
|
12
12
|
import type * as CodeMirror from '../../third_party/codemirror.next/codemirror.next.js';
|
|
13
13
|
import * as IconButton from '../../ui/components/icon_button/icon_button.js';
|
|
14
14
|
import * as Tooltips from '../../ui/components/tooltips/tooltips.js';
|
|
15
|
+
import * as uiI18n from '../../ui/i18n/i18n.js';
|
|
15
16
|
import * as SourceFrame from '../../ui/legacy/components/source_frame/source_frame.js';
|
|
16
17
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
17
18
|
import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
|
|
@@ -633,11 +634,11 @@ export class TabbedEditorContainer extends Common.ObjectWrapper.ObjectWrapper<Ev
|
|
|
633
634
|
await UI.ViewManager.ViewManager.instance().showView('navigator-files');
|
|
634
635
|
await automaticFileSystemManager.connectAutomaticFileSystem(/* addIfMissing= */ true);
|
|
635
636
|
});
|
|
636
|
-
tooltip.append(
|
|
637
|
+
tooltip.append(uiI18n.getFormatLocalizedString(
|
|
637
638
|
str_, UIStrings.changesWereNotSavedToFileSystemToSaveAddFolderToWorkspace, {PH1: link}));
|
|
638
639
|
} else {
|
|
639
640
|
const link = UI.XLink.XLink.create('https://developer.chrome.com/docs/devtools/workspaces/', 'Workspace');
|
|
640
|
-
tooltip.append(
|
|
641
|
+
tooltip.append(uiI18n.getFormatLocalizedString(
|
|
641
642
|
str_, UIStrings.changesWereNotSavedToFileSystemToSaveSetUpYourWorkspace, {PH1: link}));
|
|
642
643
|
}
|
|
643
644
|
suffixElement.append(icon, tooltip);
|
|
@@ -94,7 +94,7 @@ const str_ = i18n.i18n.registerUIStrings('panels/sources/WatchExpressionsSidebar
|
|
|
94
94
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
95
95
|
let watchExpressionsSidebarPaneInstance: WatchExpressionsSidebarPane;
|
|
96
96
|
|
|
97
|
-
export class WatchExpressionsSidebarPane extends UI.
|
|
97
|
+
export class WatchExpressionsSidebarPane extends UI.Widget.VBox implements
|
|
98
98
|
UI.ActionRegistration.ActionDelegate, UI.Toolbar.ItemsProvider,
|
|
99
99
|
UI.ContextMenu.Provider<ObjectUI.ObjectPropertiesSection.ObjectPropertyTreeElement|UISourceCodeFrame> {
|
|
100
100
|
private watchExpressions: WatchExpression[];
|
|
@@ -106,7 +106,7 @@ export class WatchExpressionsSidebarPane extends UI.ThrottledWidget.ThrottledWid
|
|
|
106
106
|
private readonly expandController: ObjectUI.ObjectPropertiesSection.ObjectPropertiesSectionsTreeExpandController;
|
|
107
107
|
private readonly linkifier: Components.Linkifier.Linkifier;
|
|
108
108
|
private constructor() {
|
|
109
|
-
super(true);
|
|
109
|
+
super({useShadowDom: true});
|
|
110
110
|
this.registerRequiredCSS(watchExpressionsSidebarPaneStyles, objectValueStyles);
|
|
111
111
|
|
|
112
112
|
// TODO(szuend): Replace with a Set once the web test
|
|
@@ -125,7 +125,7 @@ export class WatchExpressionsSidebarPane extends UI.ThrottledWidget.ThrottledWid
|
|
|
125
125
|
this.refreshButton = new UI.Toolbar.ToolbarButton(
|
|
126
126
|
i18nString(UIStrings.refreshWatchExpressions), 'refresh', undefined, 'refresh-watch-expressions');
|
|
127
127
|
this.refreshButton.setSize(Buttons.Button.Size.SMALL);
|
|
128
|
-
this.refreshButton.addEventListener(UI.Toolbar.ToolbarButton.Events.CLICK, this.
|
|
128
|
+
this.refreshButton.addEventListener(UI.Toolbar.ToolbarButton.Events.CLICK, this.requestUpdate, this);
|
|
129
129
|
|
|
130
130
|
this.contentElement.classList.add('watch-expressions');
|
|
131
131
|
this.contentElement.setAttribute('jslog', `${VisualLogging.section('sources.watch')}`);
|
|
@@ -138,10 +138,10 @@ export class WatchExpressionsSidebarPane extends UI.ThrottledWidget.ThrottledWid
|
|
|
138
138
|
this.expandController =
|
|
139
139
|
new ObjectUI.ObjectPropertiesSection.ObjectPropertiesSectionsTreeExpandController(this.treeOutline);
|
|
140
140
|
|
|
141
|
-
UI.Context.Context.instance().addFlavorChangeListener(SDK.RuntimeModel.ExecutionContext, this.
|
|
142
|
-
UI.Context.Context.instance().addFlavorChangeListener(SDK.DebuggerModel.CallFrame, this.
|
|
141
|
+
UI.Context.Context.instance().addFlavorChangeListener(SDK.RuntimeModel.ExecutionContext, this.requestUpdate, this);
|
|
142
|
+
UI.Context.Context.instance().addFlavorChangeListener(SDK.DebuggerModel.CallFrame, this.requestUpdate, this);
|
|
143
143
|
this.linkifier = new Components.Linkifier.Linkifier();
|
|
144
|
-
this.
|
|
144
|
+
this.requestUpdate();
|
|
145
145
|
}
|
|
146
146
|
|
|
147
147
|
static instance(): WatchExpressionsSidebarPane {
|
|
@@ -182,7 +182,7 @@ export class WatchExpressionsSidebarPane extends UI.ThrottledWidget.ThrottledWid
|
|
|
182
182
|
this.createWatchExpression(null).startEditing();
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
-
override async
|
|
185
|
+
override async performUpdate(): Promise<void> {
|
|
186
186
|
this.linkifier.reset();
|
|
187
187
|
this.contentElement.removeChildren();
|
|
188
188
|
this.treeOutline.removeChildren();
|
|
@@ -265,14 +265,14 @@ export class WatchExpressionsSidebarPane extends UI.ThrottledWidget.ThrottledWid
|
|
|
265
265
|
private deleteAllButtonClicked(): void {
|
|
266
266
|
this.watchExpressions = [];
|
|
267
267
|
this.saveExpressions();
|
|
268
|
-
this.
|
|
268
|
+
this.requestUpdate();
|
|
269
269
|
}
|
|
270
270
|
|
|
271
271
|
private async focusAndAddExpressionToWatch(expression: string): Promise<void> {
|
|
272
272
|
await UI.ViewManager.ViewManager.instance().showView('sources.watch');
|
|
273
273
|
this.createWatchExpression(expression);
|
|
274
274
|
this.saveExpressions();
|
|
275
|
-
this.
|
|
275
|
+
this.requestUpdate();
|
|
276
276
|
}
|
|
277
277
|
|
|
278
278
|
handleAction(_context: UI.Context.Context, _actionId: string): boolean {
|