blob: 4be2b66c6102206c60e0724552ba6f082c6df565 [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
222 condition(): string|undefined {
Jack Franklin01d09b02020-12-02 15:15:20223 return this.actionRegistration.condition;
Andres Olivares0e3a9e82020-12-01 14:03:20224 }
Andres Olivares4dba1302021-01-28 23:17:32225
226 order(): number|undefined {
227 return this.actionRegistration.order;
228 }
Andres Olivares0e3a9e82020-12-01 14:03:20229}
230
Benedikt Meurerc9fb2be2024-01-15 09:06:42231const registeredActions = new Map<string, Action>();
Andres Olivares0e3a9e82020-12-01 14:03:20232
Tim van der Lipped946df02020-12-14 14:35:49233export function registerActionExtension(registration: ActionRegistration): void {
Andres Olivares0e3a9e82020-12-01 14:03:20234 const actionId = registration.actionId;
Benedikt Meurerc9fb2be2024-01-15 09:06:42235 if (registeredActions.has(actionId)) {
Benedikt Meurere0b4b922024-01-15 13:33:53236 throw new Error(`Duplicate action ID '${actionId}'`);
237 }
238 if (!Platform.StringUtilities.isExtendedKebabCase(actionId)) {
239 throw new Error(`Invalid action ID '${actionId}'`);
Andres Olivares0e3a9e82020-12-01 14:03:20240 }
Benedikt Meurerc9fb2be2024-01-15 09:06:42241 registeredActions.set(actionId, new Action(registration));
Andres Olivares0e3a9e82020-12-01 14:03:20242}
243
Andrés Olivaresb0fcd182023-02-21 10:13:28244export function reset(): void {
Benedikt Meurerc9fb2be2024-01-15 09:06:42245 registeredActions.clear();
Andrés Olivaresb0fcd182023-02-21 10:13:28246}
247
Andres Olivaresf2a2ddd2021-02-03 17:27:51248export function getRegisteredActionExtensions(): Array<Action> {
Benedikt Meurerc9fb2be2024-01-15 09:06:42249 return Array.from(registeredActions.values())
Andres Olivares4dba1302021-01-28 23:17:32250 .filter(
251 action => Root.Runtime.Runtime.isDescriptorEnabled(
252 {experiment: action.experiment(), condition: action.condition()}))
253 .sort((firstAction, secondAction) => {
254 const order1 = firstAction.order() || 0;
255 const order2 = secondAction.order() || 0;
256 return order1 - order2;
257 });
Andres Olivares0e3a9e82020-12-01 14:03:20258}
259
Andres Olivares975c3022021-03-29 13:45:24260export function maybeRemoveActionExtension(actionId: string): boolean {
Benedikt Meurerc9fb2be2024-01-15 09:06:42261 return registeredActions.delete(actionId);
Andres Olivares975c3022021-03-29 13:45:24262}
263
Andres Olivares4ce36a52021-01-18 18:35:05264export const enum Platforms {
Andres Olivares0e3a9e82020-12-01 14:03:20265 All = 'All platforms',
266 Mac = 'mac',
267 WindowsLinux = 'windows,linux',
268 Android = 'Android',
Andres Olivares70556d62021-02-02 19:09:01269 Windows = 'windows',
Andres Olivares0e3a9e82020-12-01 14:03:20270}
271
Kateryna Prokopenkoa72448b2021-08-31 14:16:16272export const enum Events {
273 Enabled = 'Enabled',
274 Toggled = 'Toggled',
275}
276
277export type EventTypes = {
278 [Events.Enabled]: boolean,
279 [Events.Toggled]: boolean,
Andres Olivares0e3a9e82020-12-01 14:03:20280};
281
Douglas Chiang5f52fb62023-04-05 08:43:10282// eslint-disable-next-line rulesdir/const_enum
283export enum ActionCategory {
284 NONE = '', // `NONE` must be a falsy value. Legacy code uses if-checks for the category.
285 ELEMENTS = 'ELEMENTS',
286 SCREENSHOT = 'SCREENSHOT',
287 NETWORK = 'NETWORK',
288 MEMORY = 'MEMORY',
289 JAVASCRIPT_PROFILER = 'JAVASCRIPT_PROFILER',
290 CONSOLE = 'CONSOLE',
291 PERFORMANCE = 'PERFORMANCE',
292 MOBILE = 'MOBILE',
293 HELP = 'HELP',
294 LAYERS = 'LAYERS',
295 NAVIGATION = 'NAVIGATION',
296 DRAWER = 'DRAWER',
297 GLOBAL = 'GLOBAL',
298 RESOURCES = 'RESOURCES',
299 BACKGROUND_SERVICES = 'BACKGROUND_SERVICES',
300 SETTINGS = 'SETTINGS',
301 DEBUGGER = 'DEBUGGER',
302 SOURCES = 'SOURCES',
303 RENDERING = 'RENDERING',
Nikolay Vitkov8f7bda52023-11-10 16:46:13304 RECORDER = 'RECORDER',
Benedikt Meurer01fabc62023-11-16 10:24:16305 CHANGES = 'CHANGES',
Douglas Chiang5f52fb62023-04-05 08:43:10306}
Andres Olivares0e3a9e82020-12-01 14:03:20307
Douglas Chiang5f52fb62023-04-05 08:43:10308export function getLocalizedActionCategory(category: ActionCategory): Platform.UIString.LocalizedString {
309 switch (category) {
310 case ActionCategory.ELEMENTS:
311 return i18nString(UIStrings.elements);
312 case ActionCategory.SCREENSHOT:
313 return i18nString(UIStrings.screenshot);
314 case ActionCategory.NETWORK:
315 return i18nString(UIStrings.network);
316 case ActionCategory.MEMORY:
317 return i18nString(UIStrings.memory);
318 case ActionCategory.JAVASCRIPT_PROFILER:
319 return i18nString(UIStrings.javascript_profiler);
320 case ActionCategory.CONSOLE:
321 return i18nString(UIStrings.console);
322 case ActionCategory.PERFORMANCE:
323 return i18nString(UIStrings.performance);
324 case ActionCategory.MOBILE:
325 return i18nString(UIStrings.mobile);
326 case ActionCategory.HELP:
327 return i18nString(UIStrings.help);
328 case ActionCategory.LAYERS:
329 return i18nString(UIStrings.layers);
330 case ActionCategory.NAVIGATION:
331 return i18nString(UIStrings.navigation);
332 case ActionCategory.DRAWER:
333 return i18nString(UIStrings.drawer);
334 case ActionCategory.GLOBAL:
335 return i18nString(UIStrings.global);
336 case ActionCategory.RESOURCES:
337 return i18nString(UIStrings.resources);
338 case ActionCategory.BACKGROUND_SERVICES:
339 return i18nString(UIStrings.background_services);
340 case ActionCategory.SETTINGS:
341 return i18nString(UIStrings.settings);
342 case ActionCategory.DEBUGGER:
343 return i18nString(UIStrings.debugger);
344 case ActionCategory.SOURCES:
345 return i18nString(UIStrings.sources);
346 case ActionCategory.RENDERING:
347 return i18nString(UIStrings.rendering);
Nikolay Vitkov8f7bda52023-11-10 16:46:13348 case ActionCategory.RECORDER:
349 return i18nString(UIStrings.recorder);
Benedikt Meurer01fabc62023-11-16 10:24:16350 case ActionCategory.CHANGES:
351 return i18nString(UIStrings.changes);
Douglas Chiang5f52fb62023-04-05 08:43:10352 case ActionCategory.NONE:
353 return i18n.i18n.lockedString('');
354 }
Simon Zündd2132fb2023-04-05 11:39:15355 // Not all categories are cleanly typed yet. Return the category as-is in this case.
356 return i18n.i18n.lockedString(category);
Douglas Chiang5f52fb62023-04-05 08:43:10357}
Andres Olivares0e3a9e82020-12-01 14:03:20358
359export const enum IconClass {
Kateryna Prokopenko910cb532023-03-28 09:36:46360 LARGEICON_NODE_SEARCH = 'select-element',
Kateryna Prokopenko75da9712023-03-31 11:56:38361 START_RECORDING = 'record-start',
362 STOP_RECORDING = 'record-stop',
Kateryna Prokopenko551f9c82023-04-04 14:34:21363 REFRESH = 'refresh',
Kateryna Prokopenko05ade9a2023-03-31 10:57:05364 CLEAR = 'clear',
365 EYE = 'eye',
Kateryna Prokopenko910cb532023-03-28 09:36:46366 LARGEICON_PHONE = 'devices',
Benedikt Meurer58fea3a2023-04-13 05:48:47367 PLAY = 'play',
Benedikt Meurerc4ad9d92023-04-11 07:25:02368 DOWNLOAD = 'download',
Benedikt Meurer4878f6a2023-03-29 12:01:44369 LARGEICON_PAUSE = 'pause',
370 LARGEICON_RESUME = 'resume',
Muhammad Mahad88237102023-12-10 10:24:03371 MOP = 'mop',
Benedikt Meurer178c0c32023-03-31 04:50:06372 BIN = 'bin',
Kateryna Prokopenko910cb532023-03-28 09:36:46373 LARGEICON_SETTINGS_GEAR = 'gear',
Benedikt Meurer4878f6a2023-03-29 12:01:44374 LARGEICON_STEP_OVER = 'step-over',
375 LARGE_ICON_STEP_INTO = 'step-into',
376 LARGE_ICON_STEP = 'step',
377 LARGE_ICON_STEP_OUT = 'step-out',
Benedikt Meurer32c2a1b2023-03-30 07:09:59378 BREAKPOINT_CROSSED_FILLED = 'breakpoint-crossed-filled',
379 BREAKPOINT_CROSSED = 'breakpoint-crossed',
Benedikt Meurer7d5cc372023-04-12 12:20:41380 PLUS = 'plus',
Benedikt Meurer01fabc62023-11-16 10:24:16381 UNDO = 'undo',
382 COPY = 'copy',
Benedikt Meurer92795632023-11-30 14:00:57383 IMPORT = 'import',
Andres Olivares0e3a9e82020-12-01 14:03:20384}
385
386export const enum KeybindSet {
387 DEVTOOLS_DEFAULT = 'devToolsDefault',
388 VS_CODE = 'vsCode',
389}
390
391export interface ExtensionOption {
392 value: boolean;
Andres Olivares4ce36a52021-01-18 18:35:05393 title: () => Platform.UIString.LocalizedString;
Andres Olivares0e3a9e82020-12-01 14:03:20394 text?: string;
395}
396
397export interface Binding {
Andres Olivares4ce36a52021-01-18 18:35:05398 platform?: Platforms;
Andres Olivares0e3a9e82020-12-01 14:03:20399 shortcut: string;
400 keybindSets?: Array<KeybindSet>;
401}
402
Andres Olivares3f49f132020-12-03 13:10:27403/**
404 * The representation of an action extension to be registered.
405 */
Andres Olivares0e3a9e82020-12-01 14:03:20406export interface ActionRegistration {
Andres Olivares3f49f132020-12-03 13:10:27407 /**
408 * The unique id of an Action extension.
409 */
Andres Olivares0e3a9e82020-12-01 14:03:20410 actionId: string;
Andres Olivares3f49f132020-12-03 13:10:27411 /**
412 * The category with which the action is displayed in the UI.
413 */
Andres Olivares0e3a9e82020-12-01 14:03:20414 category: ActionCategory;
Andres Olivares3f49f132020-12-03 13:10:27415 /**
416 * The title with which the action is displayed in the UI.
417 */
Andres Olivares4ce36a52021-01-18 18:35:05418 title?: () => Platform.UIString.LocalizedString;
Andres Olivares3f49f132020-12-03 13:10:27419 /**
420 * The type of the icon used to trigger the action.
421 */
Andres Olivares844c58d2021-01-26 13:09:07422 iconClass?: IconClass;
Andres Olivares3f49f132020-12-03 13:10:27423 /**
424 * Whether the style of the icon toggles on interaction.
425 */
Andres Olivares844c58d2021-01-26 13:09:07426 toggledIconClass?: IconClass;
Andres Olivares3f49f132020-12-03 13:10:27427 /**
428 * Whether the class 'toolbar-toggle-with-red-color' is toggled on the icon on interaction.
429 */
Andres Olivares0e3a9e82020-12-01 14:03:20430 toggleWithRedColor?: boolean;
Andres Olivares3f49f132020-12-03 13:10:27431 /**
432 * Words used to find an action in the Command Menu.
433 */
Andres Olivares4ce36a52021-01-18 18:35:05434 tags?: Array<() => Platform.UIString.LocalizedString>;
Andres Olivares3f49f132020-12-03 13:10:27435 /**
436 * Whether the action is toggleable.
437 */
Andres Olivares0e3a9e82020-12-01 14:03:20438 toggleable?: boolean;
Andres Olivares3f49f132020-12-03 13:10:27439 /**
Andres Olivaresa0cdb382021-01-21 15:44:33440 * Loads the class that handles the action when it is triggered. The common pattern for implementing
441 * this function relies on having the module that contains the action’s handler lazily loaded. For example:
442 * ```js
443 * let loadedElementsModule;
444 *
445 * async function loadElementsModule() {
446 *
447 * if (!loadedElementsModule) {
448 * loadedElementsModule = await import('./elements.js');
449 * }
450 * return loadedElementsModule;
451 * }
452 * UI.ActionRegistration.registerActionExtension({
453 * <...>
454 * async loadActionDelegate() {
455 * const Elements = await loadElementsModule();
Benedikt Meurer64d1fec2023-11-24 10:32:08456 * return new Elements.ElementsPanel.ElementsActionDelegate();
Andres Olivaresa0cdb382021-01-21 15:44:33457 * },
458 * <...>
459 * });
460 * ```
Andres Olivares3f49f132020-12-03 13:10:27461 */
Andres Olivares0e3a9e82020-12-01 14:03:20462 loadActionDelegate?: () => Promise<ActionDelegate>;
Andres Olivares3f49f132020-12-03 13:10:27463 /**
464 * Returns the classes that represent the 'context flavors' under which the action is available for triggering.
465 * The context of the application is described in 'flavors' that are usually views added and removed to the context
466 * as the user interacts with the application (e.g when the user moves across views). (See UI.Context)
467 * When the action is supposed to be available globally, that is, it does not depend on the application to have
468 * a specific context, the value of this property should be undefined.
469 *
470 * Because the method is synchronous, context types should be already loaded when the method is invoked.
471 * In the case that an action has context types it depends on, and they haven't been loaded yet, the function should
472 * return an empty array. Once the context types have been loaded, the function should return an array with all types
473 * that it depends on.
474 *
475 * The common pattern for implementing this function is relying on having the module with the corresponding context
476 * types loaded and stored when the related 'view' extension is loaded asynchronously. As an example:
477 *
478 * ```js
479 * let loadedElementsModule;
480 *
481 * async function loadElementsModule() {
482 *
483 * if (!loadedElementsModule) {
484 * loadedElementsModule = await import('./elements.js');
485 * }
486 * return loadedElementsModule;
487 * }
488 * function maybeRetrieveContextTypes(getClassCallBack: (elementsModule: typeof Elements) => unknown[]): unknown[] {
489 *
490 * if (loadedElementsModule === undefined) {
491 * return [];
492 * }
493 * return getClassCallBack(loadedElementsModule);
494 * }
495 * UI.ActionRegistration.registerActionExtension({
496 *
497 * contextTypes() {
498 * return maybeRetrieveContextTypes(Elements => [Elements.ElementsPanel.ElementsPanel]);
499 * }
500 * <...>
501 * });
502 * ```
503 */
Sigurd Schneider61fc9bd2021-07-14 09:01:53504 contextTypes?: () => Array<Function>;
Andres Olivares3f49f132020-12-03 13:10:27505 /**
Andres Olivaresa0cdb382021-01-21 15:44:33506 * The descriptions for each of the two states in which a toggleable action can be.
Andres Olivares3f49f132020-12-03 13:10:27507 */
Andres Olivares0e3a9e82020-12-01 14:03:20508 options?: Array<ExtensionOption>;
Andres Olivares3f49f132020-12-03 13:10:27509 /**
510 * The description of the variables (e.g. platform, keys and keybind sets) under which a keyboard shortcut triggers the action.
511 * If a keybind must be available on all platforms, its 'platform' property must be undefined. The same applies to keybind sets
512 * and the keybindSet property.
513 *
514 * Keybinds also depend on the context types of their corresponding action, and so they will only be available when such context types
515 * are flavors of the current appliaction context.
516 */
Andres Olivares0e3a9e82020-12-01 14:03:20517 bindings?: Array<Binding>;
Andres Olivares3f49f132020-12-03 13:10:27518 /**
Andres Olivaresa0cdb382021-01-21 15:44:33519 * The name of the experiment an action is associated with. Enabling and disabling the declared
520 * experiment will enable and disable the action respectively.
Andres Olivares3f49f132020-12-03 13:10:27521 */
Andres Olivares0e3a9e82020-12-01 14:03:20522 experiment?: Root.Runtime.ExperimentName;
Andres Olivares3f49f132020-12-03 13:10:27523 /**
Andres Olivaresa0cdb382021-01-21 15:44:33524 * A condition represented as a string the action's availability depends on. Conditions come
525 * from the queryParamsObject defined in Runtime and just as the experiment field, they determine the availability
526 * of the setting. A condition can be negated by prepending a ‘!’ to the value of the condition
527 * property and in that case the behaviour of the action's availability will be inverted.
Andres Olivares3f49f132020-12-03 13:10:27528 */
Andres Olivares0e3a9e82020-12-01 14:03:20529 condition?: Root.Runtime.ConditionName;
Andres Olivares4dba1302021-01-28 23:17:32530 /**
531 * Used to sort actions when all registered actions are queried.
532 */
533 order?: number;
Andres Olivares0e3a9e82020-12-01 14:03:20534}