/
commandcollection.ts
135 lines (121 loc) · 3.15 KB
/
commandcollection.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/**
* @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/
/**
* @module core/commandcollection
*/
import { CKEditorError } from '@ckeditor/ckeditor5-utils';
import type Command from './command.js';
/**
* Collection of commands. Its instance is available in {@link module:core/editor/editor~Editor#commands `editor.commands`}.
*/
export default class CommandCollection implements Iterable<[ string, Command ]> {
/**
* Command map.
*/
private _commands: Map<string, Command>;
/**
* Creates collection instance.
*/
constructor() {
this._commands = new Map();
}
/**
* Registers a new command.
*
* @param commandName The name of the command.
*/
public add<TName extends string>(
commandName: TName,
command: CommandsMap[ TName ]
): void {
this._commands.set( commandName, command );
}
/**
* Retrieves a command from the collection.
*
* @param commandName The name of the command.
*/
public get<TName extends string>( commandName: TName ): CommandsMap[ TName ] | undefined {
return this._commands.get( commandName );
}
/**
* Executes a command.
*
* @param commandName The name of the command.
* @param commandParams Command parameters.
* @returns The value returned by the {@link module:core/command~Command#execute `command.execute()`}.
*/
public execute<TName extends string>(
commandName: TName,
...commandParams: Parameters<CommandsMap[ TName ][ 'execute' ]>
): ReturnType<CommandsMap[ TName ][ 'execute' ]> {
const command = this.get( commandName );
if ( !command ) {
/**
* Command does not exist.
*
* @error commandcollection-command-not-found
* @param commandName Name of the command.
*/
throw new CKEditorError( 'commandcollection-command-not-found', this, { commandName } );
}
return command.execute( ...commandParams ) as any;
}
/**
* Returns iterator of command names.
*/
public* names(): IterableIterator<string> {
yield* this._commands.keys();
}
/**
* Returns iterator of command instances.
*/
public* commands(): IterableIterator<Command> {
yield* this._commands.values();
}
/**
* Iterable interface.
*
* Returns `[ commandName, commandInstance ]` pairs.
*/
public [ Symbol.iterator ](): Iterator<[ string, Command ]> {
return this._commands[ Symbol.iterator ]();
}
/**
* Destroys all collection commands.
*/
public destroy(): void {
for ( const command of this.commands() ) {
command.destroy();
}
}
}
/**
* Helper type that maps command names to their types.
* It is meant to be extended with module augmentation.
*
* ```ts
* class MyCommand extends Command {
* public execute( parameter: A ): B {
* // ...
* }
* }
*
* declare module '@ckeditor/ckeditor5-core' {
* interface CommandsMap {
* myCommand: MyCommand;
* }
* }
*
* // Returns `MyCommand | undefined`.
* const myCommand = editor.commands.get( 'myCommand' );
*
* // Expects `A` type as parameter and returns `B`.
* const value = editor.commands.execute( 'myCommand', new A() );
* ```
*/
export interface CommandsMap {
[ name: string ]: Command;
}