chrome-devtools-frontend
Version:
Chrome DevTools UI
94 lines (79 loc) • 2.65 kB
text/typescript
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import {type Action, getRegisteredActionExtensions, reset as resetActionRegistrations} from './ActionRegistration.js';
import {Context} from './Context.js';
let actionRegistryInstance: ActionRegistry|undefined;
export class ActionRegistry {
private readonly actionsById: Map<string, Action>;
private constructor() {
this.actionsById = new Map();
this.registerActions();
}
static instance(opts: {
forceNew: boolean|null,
} = {forceNew: null}): ActionRegistry {
const {forceNew} = opts;
if (!actionRegistryInstance || forceNew) {
actionRegistryInstance = new ActionRegistry();
}
return actionRegistryInstance;
}
static removeInstance(): void {
actionRegistryInstance = undefined;
}
static reset(): void {
ActionRegistry.removeInstance();
resetActionRegistrations();
}
private registerActions(): void {
for (const action of getRegisteredActionExtensions()) {
this.actionsById.set(action.id(), action);
if (!action.canInstantiate()) {
action.setEnabled(false);
}
}
}
availableActions(): Action[] {
return this.applicableActions([...this.actionsById.keys()], Context.instance());
}
actions(): Action[] {
return [...this.actionsById.values()];
}
applicableActions(actionIds: string[], context: Context): Action[] {
const applicableActions: Action[] = [];
for (const actionId of actionIds) {
const action = this.actionsById.get(actionId);
if (action?.enabled()) {
if (isActionApplicableToContextTypes(action, context.flavors())) {
applicableActions.push(action);
}
}
}
return applicableActions;
function isActionApplicableToContextTypes(action: Action, currentContextTypes: Set<unknown>): boolean {
const contextTypes = action.contextTypes();
if (!contextTypes) {
return true;
}
for (let i = 0; i < contextTypes.length; ++i) {
const contextType = contextTypes[i];
const isMatching = Boolean(contextType) && currentContextTypes.has(contextType);
if (isMatching) {
return true;
}
}
return false;
}
}
hasAction(actionId: string): boolean {
return this.actionsById.has(actionId);
}
getAction(actionId: string): Action {
const action = this.actionsById.get(actionId);
if (action) {
return action;
}
throw new Error(`Cannot find registered action with ID '${actionId}'`);
}
}