blob: 03f6fed4f7895c5a12c5991811d380723a82ab7b [file] [log] [blame]
Andres Olivares6490c002020-12-02 16:03:351// Copyright 2020 The Chromium Authors. All rights reserved.
Andres Olivares0e3a9e82020-12-01 14:03:202// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Tim van der Lippeaa61faf2021-04-07 15:32:075import * as Common from '../../core/common/common.js';
Douglas Chiang5f52fb62023-04-05 08:43:106import * as i18n from '../../core/i18n/i18n.js';
Benedikt Meurere0b4b922024-01-15 13:33:537import * as Platform from '../../core/platform/platform.js';
Tim van der Lippeaa61faf2021-04-07 15:32:078import * as Root from '../../core/root/root.js';
Andres Olivares0e3a9e82020-12-01 14:03:209
10import {Context} from './Context.js';
11
Douglas Chiang5f52fb62023-04-05 08:43:1012const UIStrings = {
13 /**
14 *@description Title of the keybind category 'Elements' in Settings' Shortcuts pannel.
15 */
16 elements: 'Elements',
17 /**
18 *@description Title of the keybind category 'Screenshot' in Settings' Shortcuts pannel.
19 */
20 screenshot: 'Screenshot',
21 /**
22 *@description Title of the keybind category 'Network' in Settings' Shortcuts pannel.
23 */
24 network: 'Network',
25 /**
26 *@description Title of the keybind category 'Memory' in Settings' Shortcuts pannel.
27 */
28 memory: 'Memory',
29 /**
30 *@description Title of the keybind category 'JavaScript Profiler' in Settings' Shortcuts pannel.
31 */
32 javascript_profiler: 'JavaScript Profiler',
33 /**
34 *@description Title of the keybind category 'Console' in Settings' Shortcuts pannel.
35 */
36 console: 'Console',
37 /**
38 *@description Title of the keybind category 'Performance' in Settings' Shortcuts pannel.
39 */
40 performance: 'Performance',
41 /**
42 *@description Title of the keybind category 'Mobile' in Settings' Shortcuts pannel.
43 */
44 mobile: 'Mobile',
45 /**
46 *@description Title of the keybind category 'Help' in Settings' Shortcuts pannel.
47 */
48 help: 'Help',
49 /**
50 *@description Title of the keybind category 'Layers' in Settings' Shortcuts pannel.
51 */
52 layers: 'Layers',
53 /**
54 *@description Title of the keybind category 'Navigation' in Settings' Shortcuts pannel.
55 */
56 navigation: 'Navigation',
57 /**
58 *@description Title of the keybind category 'Drawer' in Settings' Shortcuts pannel.
59 */
60 drawer: 'Drawer',
61 /**
62 *@description Title of the keybind category 'Global' in Settings' Shortcuts pannel.
63 */
64 global: 'Global',
65 /**
66 *@description Title of the keybind category 'Resources' in Settings' Shortcuts pannel.
67 */
68 resources: 'Resources',
69 /**
70 *@description Title of the keybind category 'Background Services' in Settings' Shortcuts pannel.
71 */
72 background_services: 'Background Services',
73 /**
74 *@description Title of the keybind category 'Settings' in Settings' Shortcuts pannel.
75 */
76 settings: 'Settings',
77 /**
78 *@description Title of the keybind category 'Debugger' in Settings' Shortcuts pannel.
79 */
80 debugger: 'Debugger',
81 /**
82 *@description Title of the keybind category 'Sources' in Settings' Shortcuts pannel.
83 */
84 sources: 'Sources',
85 /**
86 *@description Title of the keybind category 'Rendering' in Settings' Shortcuts pannel.
87 */
88 rendering: 'Rendering',
Nikolay Vitkov8f7bda52023-11-10 16:46:1389 /**
90 *@description Title of the keybind category 'Recorder' in Settings' Shortcuts pannel.
91 */
92 recorder: 'Recorder',
Benedikt Meurer01fabc62023-11-16 10:24:1693 /**
94 *@description Title of the keybind category 'Changes' in Settings' Shortcuts pannel.
95 */
96 changes: 'Changes',
Douglas Chiang5f52fb62023-04-05 08:43:1097};
98const str_ = i18n.i18n.registerUIStrings('ui/legacy/ActionRegistration.ts', UIStrings);
99const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
100
Andres Olivares0e3a9e82020-12-01 14:03:20101export interface ActionDelegate {
102 handleAction(_context: Context, _actionId: string): boolean;
103}
104
Kateryna Prokopenkoa72448b2021-08-31 14:16:16105export class Action extends Common.ObjectWrapper.ObjectWrapper<EventTypes> {
Jan Scheffler01eab3c2021-08-16 17:18:07106 private enabledInternal = true;
107 private toggledInternal = false;
Jack Franklin01d09b02020-12-02 15:15:20108 private actionRegistration: ActionRegistration;
Andres Olivares0e3a9e82020-12-01 14:03:20109 constructor(actionRegistration: ActionRegistration) {
110 super();
Jack Franklin01d09b02020-12-02 15:15:20111 this.actionRegistration = actionRegistration;
Andres Olivares0e3a9e82020-12-01 14:03:20112 }
113
114 id(): string {
Jack Franklin01d09b02020-12-02 15:15:20115 return this.actionRegistration.actionId;
Andres Olivares0e3a9e82020-12-01 14:03:20116 }
117
118 async execute(): Promise<boolean> {
Jack Franklin01d09b02020-12-02 15:15:20119 if (!this.actionRegistration.loadActionDelegate) {
Andres Olivares0e3a9e82020-12-01 14:03:20120 return false;
121 }
Jack Franklin01d09b02020-12-02 15:15:20122 const delegate = await this.actionRegistration.loadActionDelegate();
Andres Olivares0e3a9e82020-12-01 14:03:20123 const actionId = this.id();
124 return delegate.handleAction(Context.instance(), actionId);
125 }
126
127 icon(): string|undefined {
Jack Franklin01d09b02020-12-02 15:15:20128 return this.actionRegistration.iconClass;
Andres Olivares0e3a9e82020-12-01 14:03:20129 }
130
131 toggledIcon(): string|undefined {
Jack Franklin01d09b02020-12-02 15:15:20132 return this.actionRegistration.toggledIconClass;
Andres Olivares0e3a9e82020-12-01 14:03:20133 }
134
135 toggleWithRedColor(): boolean {
Tim van der Lippeba0e6452021-01-07 13:46:34136 return Boolean(this.actionRegistration.toggleWithRedColor);
Andres Olivares0e3a9e82020-12-01 14:03:20137 }
138
Tim van der Lipped946df02020-12-14 14:35:49139 setEnabled(enabled: boolean): void {
Jan Scheffler01eab3c2021-08-16 17:18:07140 if (this.enabledInternal === enabled) {
Andres Olivares0e3a9e82020-12-01 14:03:20141 return;
142 }
143
Jan Scheffler01eab3c2021-08-16 17:18:07144 this.enabledInternal = enabled;
Andres Olivares0e3a9e82020-12-01 14:03:20145 this.dispatchEventToListeners(Events.Enabled, enabled);
146 }
147
148 enabled(): boolean {
Jan Scheffler01eab3c2021-08-16 17:18:07149 return this.enabledInternal;
Andres Olivares0e3a9e82020-12-01 14:03:20150 }
151
Douglas Chiang5f52fb62023-04-05 08:43:10152 category(): ActionCategory {
Jack Franklin01d09b02020-12-02 15:15:20153 return this.actionRegistration.category;
Andres Olivares0e3a9e82020-12-01 14:03:20154 }
155
Andres Olivares344120f2020-12-07 17:43:28156 tags(): string|void {
157 if (this.actionRegistration.tags) {
158 // Get localized keys and separate by null character to prevent fuzzy matching from matching across them.
Andres Olivares4ce36a52021-01-18 18:35:05159 return this.actionRegistration.tags.map(tag => tag()).join('\0');
Andres Olivares344120f2020-12-07 17:43:28160 }
Andres Olivares0e3a9e82020-12-01 14:03:20161 }
162
163 toggleable(): boolean {
Tim van der Lippeba0e6452021-01-07 13:46:34164 return Boolean(this.actionRegistration.toggleable);
Andres Olivares0e3a9e82020-12-01 14:03:20165 }
166
Simon Zünd6eb94e32023-04-11 05:28:22167 title(): Common.UIString.LocalizedString {
168 let title = this.actionRegistration.title ? this.actionRegistration.title() : i18n.i18n.lockedString('');
Jack Franklin01d09b02020-12-02 15:15:20169 const options = this.actionRegistration.options;
Andres Olivares0e3a9e82020-12-01 14:03:20170 if (options) {
171 // Actions with an 'options' property don't have a title field. Instead, the displayed
172 // title is taken from the 'title' property of the option that is not active. Only one of the
173 // two options can be active at a given moment and the 'toggled' property of the action along
174 // with the 'value' of the options are used to determine which one it is.
175
176 for (const pair of options) {
Jan Scheffler01eab3c2021-08-16 17:18:07177 if (pair.value !== this.toggledInternal) {
Andres Olivares4ce36a52021-01-18 18:35:05178 title = pair.title();
Andres Olivares0e3a9e82020-12-01 14:03:20179 }
180 }
181 }
182 return title;
183 }
184
185 toggled(): boolean {
Jan Scheffler01eab3c2021-08-16 17:18:07186 return this.toggledInternal;
Andres Olivares0e3a9e82020-12-01 14:03:20187 }
188
Tim van der Lipped946df02020-12-14 14:35:49189 setToggled(toggled: boolean): void {
Andres Olivares0e3a9e82020-12-01 14:03:20190 console.assert(this.toggleable(), 'Shouldn\'t be toggling an untoggleable action', this.id());
Jan Scheffler01eab3c2021-08-16 17:18:07191 if (this.toggledInternal === toggled) {
Andres Olivares0e3a9e82020-12-01 14:03:20192 return;
193 }
194
Jan Scheffler01eab3c2021-08-16 17:18:07195 this.toggledInternal = toggled;
Andres Olivares0e3a9e82020-12-01 14:03:20196 this.dispatchEventToListeners(Events.Toggled, toggled);
197 }
198
199 options(): undefined|Array<ExtensionOption> {
Jack Franklin01d09b02020-12-02 15:15:20200 return this.actionRegistration.options;
Andres Olivares0e3a9e82020-12-01 14:03:20201 }
202
Sigurd Schneider61fc9bd2021-07-14 09:01:53203 contextTypes(): undefined|Array<Function> {
Jack Franklin01d09b02020-12-02 15:15:20204 if (this.actionRegistration.contextTypes) {
205 return this.actionRegistration.contextTypes();
Andres Olivares0e3a9e82020-12-01 14:03:20206 }
207 return undefined;
208 }
209
210 canInstantiate(): boolean {
Tim van der Lippeba0e6452021-01-07 13:46:34211 return Boolean(this.actionRegistration.loadActionDelegate);
Andres Olivares0e3a9e82020-12-01 14:03:20212 }
213
214 bindings(): Array<Binding>|undefined {
Jack Franklin01d09b02020-12-02 15:15:20215 return this.actionRegistration.bindings;
Andres Olivares0e3a9e82020-12-01 14:03:20216 }
217
218 experiment(): string|undefined {
Jack Franklin01d09b02020-12-02 15:15:20219 return this.actionRegistration.experiment;
Andres Olivares0e3a9e82020-12-01 14:03:20220 }
221
Alex Rudenko43ebf022024-01-31 18:43:40222 setting(): string|undefined {
223 return this.actionRegistration.setting;
224 }
225
Andres Olivares0e3a9e82020-12-01 14:03:20226 condition(): string|undefined {
Jack Franklin01d09b02020-12-02 15:15:20227 return this.actionRegistration.condition;
Andres Olivares0e3a9e82020-12-01 14:03:20228 }
Andres Olivares4dba1302021-01-28 23:17:32229
230 order(): number|undefined {
231 return this.actionRegistration.order;
232 }
Andres Olivares0e3a9e82020-12-01 14:03:20233}
234
Benedikt Meurerc9fb2be2024-01-15 09:06:42235const registeredActions = new Map<string, Action>();
Andres Olivares0e3a9e82020-12-01 14:03:20236
Tim van der Lipped946df02020-12-14 14:35:49237export function registerActionExtension(registration: ActionRegistration): void {
Andres Olivares0e3a9e82020-12-01 14:03:20238 const actionId = registration.actionId;
Benedikt Meurerc9fb2be2024-01-15 09:06:42239 if (registeredActions.has(actionId)) {
Benedikt Meurere0b4b922024-01-15 13:33:53240 throw new Error(`Duplicate action ID '${actionId}'`);
241 }
242 if (!Platform.StringUtilities.isExtendedKebabCase(actionId)) {
243 throw new Error(`Invalid action ID '${actionId}'`);
Andres Olivares0e3a9e82020-12-01 14:03:20244 }
Benedikt Meurerc9fb2be2024-01-15 09:06:42245 registeredActions.set(actionId, new Action(registration));
Andres Olivares0e3a9e82020-12-01 14:03:20246}
247
Andrés Olivaresb0fcd182023-02-21 10:13:28248export function reset(): void {
Benedikt Meurerc9fb2be2024-01-15 09:06:42249 registeredActions.clear();
Andrés Olivaresb0fcd182023-02-21 10:13:28250}
251
Andres Olivaresf2a2ddd2021-02-03 17:27:51252export function getRegisteredActionExtensions(): Array<Action> {
Benedikt Meurerc9fb2be2024-01-15 09:06:42253 return Array.from(registeredActions.values())
Alex Rudenko43ebf022024-01-31 18:43:40254 .filter(action => {
255 const settingName = action.setting();
256 if (settingName && !Common.Settings.moduleSetting(settingName).get()) {
257 return false;
258 }
259
260 return Root.Runtime.Runtime.isDescriptorEnabled(
261 {experiment: action.experiment(), condition: action.condition()});
262 })
Andres Olivares4dba1302021-01-28 23:17:32263 .sort((firstAction, secondAction) => {
264 const order1 = firstAction.order() || 0;
265 const order2 = secondAction.order() || 0;
266 return order1 - order2;
267 });
Andres Olivares0e3a9e82020-12-01 14:03:20268}
269
Andres Olivares975c3022021-03-29 13:45:24270export function maybeRemoveActionExtension(actionId: string): boolean {
Benedikt Meurerc9fb2be2024-01-15 09:06:42271 return registeredActions.delete(actionId);
Andres Olivares975c3022021-03-29 13:45:24272}
273
Andres Olivares4ce36a52021-01-18 18:35:05274export const enum Platforms {
Andres Olivares0e3a9e82020-12-01 14:03:20275 All = 'All platforms',
276 Mac = 'mac',
277 WindowsLinux = 'windows,linux',
278 Android = 'Android',
Andres Olivares70556d62021-02-02 19:09:01279 Windows = 'windows',
Andres Olivares0e3a9e82020-12-01 14:03:20280}
281
Kateryna Prokopenkoa72448b2021-08-31 14:16:16282export const enum Events {
283 Enabled = 'Enabled',
284 Toggled = 'Toggled',
285}
286
287export type EventTypes = {
288 [Events.Enabled]: boolean,
289 [Events.Toggled]: boolean,
Andres Olivares0e3a9e82020-12-01 14:03:20290};
291
Benedikt Meurer624312d2024-01-22 09:24:09292export const enum ActionCategory {
Douglas Chiang5f52fb62023-04-05 08:43:10293 NONE = '', // `NONE` must be a falsy value. Legacy code uses if-checks for the category.
294 ELEMENTS = 'ELEMENTS',
295 SCREENSHOT = 'SCREENSHOT',
296 NETWORK = 'NETWORK',
297 MEMORY = 'MEMORY',
298 JAVASCRIPT_PROFILER = 'JAVASCRIPT_PROFILER',
299 CONSOLE = 'CONSOLE',
300 PERFORMANCE = 'PERFORMANCE',
301 MOBILE = 'MOBILE',
302 HELP = 'HELP',
303 LAYERS = 'LAYERS',
304 NAVIGATION = 'NAVIGATION',
305 DRAWER = 'DRAWER',
306 GLOBAL = 'GLOBAL',
307 RESOURCES = 'RESOURCES',
308 BACKGROUND_SERVICES = 'BACKGROUND_SERVICES',
309 SETTINGS = 'SETTINGS',
310 DEBUGGER = 'DEBUGGER',
311 SOURCES = 'SOURCES',
312 RENDERING = 'RENDERING',
Nikolay Vitkov8f7bda52023-11-10 16:46:13313 RECORDER = 'RECORDER',
Benedikt Meurer01fabc62023-11-16 10:24:16314 CHANGES = 'CHANGES',
Douglas Chiang5f52fb62023-04-05 08:43:10315}
Andres Olivares0e3a9e82020-12-01 14:03:20316
Douglas Chiang5f52fb62023-04-05 08:43:10317export function getLocalizedActionCategory(category: ActionCategory): Platform.UIString.LocalizedString {
318 switch (category) {
319 case ActionCategory.ELEMENTS:
320 return i18nString(UIStrings.elements);
321 case ActionCategory.SCREENSHOT:
322 return i18nString(UIStrings.screenshot);
323 case ActionCategory.NETWORK:
324 return i18nString(UIStrings.network);
325 case ActionCategory.MEMORY:
326 return i18nString(UIStrings.memory);
327 case ActionCategory.JAVASCRIPT_PROFILER:
328 return i18nString(UIStrings.javascript_profiler);
329 case ActionCategory.CONSOLE:
330 return i18nString(UIStrings.console);
331 case ActionCategory.PERFORMANCE:
332 return i18nString(UIStrings.performance);
333 case ActionCategory.MOBILE:
334 return i18nString(UIStrings.mobile);
335 case ActionCategory.HELP:
336 return i18nString(UIStrings.help);
337 case ActionCategory.LAYERS:
338 return i18nString(UIStrings.layers);
339 case ActionCategory.NAVIGATION:
340 return i18nString(UIStrings.navigation);
341 case ActionCategory.DRAWER:
342 return i18nString(UIStrings.drawer);
343 case ActionCategory.GLOBAL:
344 return i18nString(UIStrings.global);
345 case ActionCategory.RESOURCES:
346 return i18nString(UIStrings.resources);
347 case ActionCategory.BACKGROUND_SERVICES:
348 return i18nString(UIStrings.background_services);
349 case ActionCategory.SETTINGS:
350 return i18nString(UIStrings.settings);
351 case ActionCategory.DEBUGGER:
352 return i18nString(UIStrings.debugger);
353 case ActionCategory.SOURCES:
354 return i18nString(UIStrings.sources);
355 case ActionCategory.RENDERING:
356 return i18nString(UIStrings.rendering);
Nikolay Vitkov8f7bda52023-11-10 16:46:13357 case ActionCategory.RECORDER:
358 return i18nString(UIStrings.recorder);
Benedikt Meurer01fabc62023-11-16 10:24:16359 case ActionCategory.CHANGES:
360 return i18nString(UIStrings.changes);
Douglas Chiang5f52fb62023-04-05 08:43:10361 case ActionCategory.NONE:
362 return i18n.i18n.lockedString('');
363 }
Simon Zündd2132fb2023-04-05 11:39:15364 // Not all categories are cleanly typed yet. Return the category as-is in this case.
365 return i18n.i18n.lockedString(category);
Douglas Chiang5f52fb62023-04-05 08:43:10366}
Andres Olivares0e3a9e82020-12-01 14:03:20367
368export const enum IconClass {
Kateryna Prokopenko910cb532023-03-28 09:36:46369 LARGEICON_NODE_SEARCH = 'select-element',
Kateryna Prokopenko75da9712023-03-31 11:56:38370 START_RECORDING = 'record-start',
371 STOP_RECORDING = 'record-stop',
Kateryna Prokopenko551f9c82023-04-04 14:34:21372 REFRESH = 'refresh',
Kateryna Prokopenko05ade9a2023-03-31 10:57:05373 CLEAR = 'clear',
374 EYE = 'eye',
Kateryna Prokopenko910cb532023-03-28 09:36:46375 LARGEICON_PHONE = 'devices',
Benedikt Meurer58fea3a2023-04-13 05:48:47376 PLAY = 'play',
Benedikt Meurerc4ad9d92023-04-11 07:25:02377 DOWNLOAD = 'download',
Benedikt Meurer4878f6a2023-03-29 12:01:44378 LARGEICON_PAUSE = 'pause',
379 LARGEICON_RESUME = 'resume',
Muhammad Mahad88237102023-12-10 10:24:03380 MOP = 'mop',
Benedikt Meurer178c0c32023-03-31 04:50:06381 BIN = 'bin',
Kateryna Prokopenko910cb532023-03-28 09:36:46382 LARGEICON_SETTINGS_GEAR = 'gear',
Benedikt Meurer4878f6a2023-03-29 12:01:44383 LARGEICON_STEP_OVER = 'step-over',
384 LARGE_ICON_STEP_INTO = 'step-into',
385 LARGE_ICON_STEP = 'step',
386 LARGE_ICON_STEP_OUT = 'step-out',
Benedikt Meurer32c2a1b2023-03-30 07:09:59387 BREAKPOINT_CROSSED_FILLED = 'breakpoint-crossed-filled',
388 BREAKPOINT_CROSSED = 'breakpoint-crossed',
Benedikt Meurer7d5cc372023-04-12 12:20:41389 PLUS = 'plus',
Benedikt Meurer01fabc62023-11-16 10:24:16390 UNDO = 'undo',
391 COPY = 'copy',
Benedikt Meurer92795632023-11-30 14:00:57392 IMPORT = 'import',
Andres Olivares0e3a9e82020-12-01 14:03:20393}
394
395export const enum KeybindSet {
396 DEVTOOLS_DEFAULT = 'devToolsDefault',
397 VS_CODE = 'vsCode',
398}
399
400export interface ExtensionOption {
401 value: boolean;
Andres Olivares4ce36a52021-01-18 18:35:05402 title: () => Platform.UIString.LocalizedString;
Andres Olivares0e3a9e82020-12-01 14:03:20403 text?: string;
404}
405
406export interface Binding {
Andres Olivares4ce36a52021-01-18 18:35:05407 platform?: Platforms;
Andres Olivares0e3a9e82020-12-01 14:03:20408 shortcut: string;
409 keybindSets?: Array<KeybindSet>;
410}
411
Andres Olivares3f49f132020-12-03 13:10:27412/**
413 * The representation of an action extension to be registered.
414 */
Andres Olivares0e3a9e82020-12-01 14:03:20415export interface ActionRegistration {
Andres Olivares3f49f132020-12-03 13:10:27416 /**
417 * The unique id of an Action extension.
418 */
Andres Olivares0e3a9e82020-12-01 14:03:20419 actionId: string;
Andres Olivares3f49f132020-12-03 13:10:27420 /**
421 * The category with which the action is displayed in the UI.
422 */
Andres Olivares0e3a9e82020-12-01 14:03:20423 category: ActionCategory;
Andres Olivares3f49f132020-12-03 13:10:27424 /**
425 * The title with which the action is displayed in the UI.
426 */
Andres Olivares4ce36a52021-01-18 18:35:05427 title?: () => Platform.UIString.LocalizedString;
Andres Olivares3f49f132020-12-03 13:10:27428 /**
429 * The type of the icon used to trigger the action.
430 */
Andres Olivares844c58d2021-01-26 13:09:07431 iconClass?: IconClass;
Andres Olivares3f49f132020-12-03 13:10:27432 /**
433 * Whether the style of the icon toggles on interaction.
434 */
Andres Olivares844c58d2021-01-26 13:09:07435 toggledIconClass?: IconClass;
Andres Olivares3f49f132020-12-03 13:10:27436 /**
437 * Whether the class 'toolbar-toggle-with-red-color' is toggled on the icon on interaction.
438 */
Andres Olivares0e3a9e82020-12-01 14:03:20439 toggleWithRedColor?: boolean;
Andres Olivares3f49f132020-12-03 13:10:27440 /**
441 * Words used to find an action in the Command Menu.
442 */
Andres Olivares4ce36a52021-01-18 18:35:05443 tags?: Array<() => Platform.UIString.LocalizedString>;
Andres Olivares3f49f132020-12-03 13:10:27444 /**
445 * Whether the action is toggleable.
446 */
Andres Olivares0e3a9e82020-12-01 14:03:20447 toggleable?: boolean;
Andres Olivares3f49f132020-12-03 13:10:27448 /**
Andres Olivaresa0cdb382021-01-21 15:44:33449 * Loads the class that handles the action when it is triggered. The common pattern for implementing
450 * this function relies on having the module that contains the action’s handler lazily loaded. For example:
451 * ```js
452 * let loadedElementsModule;
453 *
454 * async function loadElementsModule() {
455 *
456 * if (!loadedElementsModule) {
457 * loadedElementsModule = await import('./elements.js');
458 * }
459 * return loadedElementsModule;
460 * }
461 * UI.ActionRegistration.registerActionExtension({
462 * <...>
463 * async loadActionDelegate() {
464 * const Elements = await loadElementsModule();
Benedikt Meurer64d1fec2023-11-24 10:32:08465 * return new Elements.ElementsPanel.ElementsActionDelegate();
Andres Olivaresa0cdb382021-01-21 15:44:33466 * },
467 * <...>
468 * });
469 * ```
Andres Olivares3f49f132020-12-03 13:10:27470 */
Andres Olivares0e3a9e82020-12-01 14:03:20471 loadActionDelegate?: () => Promise<ActionDelegate>;
Andres Olivares3f49f132020-12-03 13:10:27472 /**
473 * Returns the classes that represent the 'context flavors' under which the action is available for triggering.
474 * The context of the application is described in 'flavors' that are usually views added and removed to the context
475 * as the user interacts with the application (e.g when the user moves across views). (See UI.Context)
476 * When the action is supposed to be available globally, that is, it does not depend on the application to have
477 * a specific context, the value of this property should be undefined.
478 *
479 * Because the method is synchronous, context types should be already loaded when the method is invoked.
480 * In the case that an action has context types it depends on, and they haven't been loaded yet, the function should
481 * return an empty array. Once the context types have been loaded, the function should return an array with all types
482 * that it depends on.
483 *
484 * The common pattern for implementing this function is relying on having the module with the corresponding context
485 * types loaded and stored when the related 'view' extension is loaded asynchronously. As an example:
486 *
487 * ```js
488 * let loadedElementsModule;
489 *
490 * async function loadElementsModule() {
491 *
492 * if (!loadedElementsModule) {
493 * loadedElementsModule = await import('./elements.js');
494 * }
495 * return loadedElementsModule;
496 * }
497 * function maybeRetrieveContextTypes(getClassCallBack: (elementsModule: typeof Elements) => unknown[]): unknown[] {
498 *
499 * if (loadedElementsModule === undefined) {
500 * return [];
501 * }
502 * return getClassCallBack(loadedElementsModule);
503 * }
504 * UI.ActionRegistration.registerActionExtension({
505 *
506 * contextTypes() {
507 * return maybeRetrieveContextTypes(Elements => [Elements.ElementsPanel.ElementsPanel]);
508 * }
509 * <...>
510 * });
511 * ```
512 */
Sigurd Schneider61fc9bd2021-07-14 09:01:53513 contextTypes?: () => Array<Function>;
Andres Olivares3f49f132020-12-03 13:10:27514 /**
Andres Olivaresa0cdb382021-01-21 15:44:33515 * The descriptions for each of the two states in which a toggleable action can be.
Andres Olivares3f49f132020-12-03 13:10:27516 */
Andres Olivares0e3a9e82020-12-01 14:03:20517 options?: Array<ExtensionOption>;
Andres Olivares3f49f132020-12-03 13:10:27518 /**
519 * The description of the variables (e.g. platform, keys and keybind sets) under which a keyboard shortcut triggers the action.
520 * If a keybind must be available on all platforms, its 'platform' property must be undefined. The same applies to keybind sets
521 * and the keybindSet property.
522 *
523 * Keybinds also depend on the context types of their corresponding action, and so they will only be available when such context types
524 * are flavors of the current appliaction context.
525 */
Andres Olivares0e3a9e82020-12-01 14:03:20526 bindings?: Array<Binding>;
Andres Olivares3f49f132020-12-03 13:10:27527 /**
Andres Olivaresa0cdb382021-01-21 15:44:33528 * The name of the experiment an action is associated with. Enabling and disabling the declared
529 * experiment will enable and disable the action respectively.
Andres Olivares3f49f132020-12-03 13:10:27530 */
Andres Olivares0e3a9e82020-12-01 14:03:20531 experiment?: Root.Runtime.ExperimentName;
Andres Olivares3f49f132020-12-03 13:10:27532 /**
Alex Rudenko43ebf022024-01-31 18:43:40533 * The name of the setting an action is associated with. Enabling and
534 * disabling the declared setting will enable and disable the action
535 * respectively. Note that changing the setting requires a reload for it to
536 * apply to action registration.
537 */
538 setting?: string;
539 /**
Andres Olivaresa0cdb382021-01-21 15:44:33540 * A condition represented as a string the action's availability depends on. Conditions come
541 * from the queryParamsObject defined in Runtime and just as the experiment field, they determine the availability
542 * of the setting. A condition can be negated by prepending a ‘!’ to the value of the condition
543 * property and in that case the behaviour of the action's availability will be inverted.
Andres Olivares3f49f132020-12-03 13:10:27544 */
Andres Olivares0e3a9e82020-12-01 14:03:20545 condition?: Root.Runtime.ConditionName;
Andres Olivares4dba1302021-01-28 23:17:32546 /**
547 * Used to sort actions when all registered actions are queried.
548 */
549 order?: number;
Andres Olivares0e3a9e82020-12-01 14:03:20550}