1 | /**
|
2 | * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
|
3 | * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
4 | */
|
5 | /**
|
6 | * @module core/command
|
7 | */
|
8 | import { type DecoratedMethodEvent } from '@ckeditor/ckeditor5-utils';
|
9 | import type Editor from './editor/editor.js';
|
10 | declare const Command_base: {
|
11 | new (): import("@ckeditor/ckeditor5-utils").Observable;
|
12 | prototype: import("@ckeditor/ckeditor5-utils").Observable;
|
13 | };
|
14 | /**
|
15 | * Base class for the CKEditor commands.
|
16 | *
|
17 | * Commands are the main way to manipulate the editor contents and state. They are mostly used by UI elements (or by other
|
18 | * commands) to make changes in the model. Commands are available in every part of the code that has access to
|
19 | * the {@link module:core/editor/editor~Editor editor} instance.
|
20 | *
|
21 | * Instances of registered commands can be retrieved from {@link module:core/editor/editor~Editor#commands `editor.commands`}.
|
22 | * The easiest way to execute a command is through {@link module:core/editor/editor~Editor#execute `editor.execute()`}.
|
23 | *
|
24 | * By default, commands are disabled when the editor is in the {@link module:core/editor/editor~Editor#isReadOnly read-only} mode
|
25 | * but commands with the {@link module:core/command~Command#affectsData `affectsData`} flag set to `false` will not be disabled.
|
26 | */
|
27 | export default class Command extends /* #__PURE__ */ Command_base {
|
28 | /**
|
29 | * The editor on which this command will be used.
|
30 | */
|
31 | readonly editor: Editor;
|
32 | /**
|
33 | * The value of the command. A given command class should define what it represents for it.
|
34 | *
|
35 | * For example, the `'bold'` command's value indicates whether the selection starts in a bolded text.
|
36 | * And the value of the `'link'` command may be an object with link details.
|
37 | *
|
38 | * It is possible for a command to have no value (e.g. for stateless actions such as `'uploadImage'`).
|
39 | *
|
40 | * A given command class should control this value by overriding the {@link #refresh `refresh()`} method.
|
41 | *
|
42 | * @observable
|
43 | * @readonly
|
44 | */
|
45 | value: unknown;
|
46 | /**
|
47 | * Flag indicating whether a command is enabled or disabled.
|
48 | * A disabled command will do nothing when executed.
|
49 | *
|
50 | * A given command class should control this value by overriding the {@link #refresh `refresh()`} method.
|
51 | *
|
52 | * It is possible to disable a command "from outside" using {@link #forceDisabled} method.
|
53 | *
|
54 | * @observable
|
55 | * @readonly
|
56 | */
|
57 | isEnabled: boolean;
|
58 | /**
|
59 | * A flag indicating whether a command's `isEnabled` state should be changed depending on where the document
|
60 | * selection is placed.
|
61 | *
|
62 | * By default, it is set to `true`. If the document selection is placed in a
|
63 | * {@link module:engine/model/model~Model#canEditAt non-editable} place (such as non-editable root), the command becomes disabled.
|
64 | *
|
65 | * The flag should be changed to `false` in a concrete command's constructor if the command should not change its `isEnabled`
|
66 | * accordingly to the document selection.
|
67 | */
|
68 | protected _isEnabledBasedOnSelection: boolean;
|
69 | /**
|
70 | * A flag indicating whether a command execution changes the editor data or not.
|
71 | *
|
72 | * @see #affectsData
|
73 | */
|
74 | private _affectsData;
|
75 | /**
|
76 | * Holds identifiers for {@link #forceDisabled} mechanism.
|
77 | */
|
78 | private readonly _disableStack;
|
79 | /**
|
80 | * Creates a new `Command` instance.
|
81 | *
|
82 | * @param editor The editor on which this command will be used.
|
83 | */
|
84 | constructor(editor: Editor);
|
85 | /**
|
86 | * A flag indicating whether a command execution changes the editor data or not.
|
87 | *
|
88 | * Commands with `affectsData` set to `false` will not be automatically disabled in
|
89 | * the {module:core/editor/editor~Editor#isReadOnly read-only mode} and
|
90 | * {with restricted user write permissions.
features/read-only#related-features other editor modes} |
91 | *
|
92 | * **Note:** You do not have to set it for your every command. It is `true` by default.
|
93 | *
|
94 | * true
|
95 | */
|
96 | get affectsData(): boolean;
|
97 | protected set affectsData(affectsData: boolean);
|
98 | /**
|
99 | * Refreshes the command. The command should update its {@link #isEnabled} and {@link #value} properties
|
100 | * in this method.
|
101 | *
|
102 | * This method is automatically called when
|
103 | * {@link module:engine/model/document~Document#event:change any changes are applied to the document}.
|
104 | */
|
105 | refresh(): void;
|
106 | /**
|
107 | * Disables the command.
|
108 | *
|
109 | * Command may be disabled by multiple features or algorithms (at once). When disabling a command, unique id should be passed
|
110 | * (e.g. the feature name). The same identifier should be used when {@link #clearForceDisabled enabling back} the command.
|
111 | * The command becomes enabled only after all features {@link #clearForceDisabled enabled it back}.
|
112 | *
|
113 | * Disabling and enabling a command:
|
114 | *
|
115 | * ```ts
|
116 | * command.isEnabled; // -> true
|
117 | * command.forceDisabled( 'MyFeature' );
|
118 | * command.isEnabled; // -> false
|
119 | * command.clearForceDisabled( 'MyFeature' );
|
120 | * command.isEnabled; // -> true
|
121 | * ```
|
122 | *
|
123 | * Command disabled by multiple features:
|
124 | *
|
125 | * ```ts
|
126 | * command.forceDisabled( 'MyFeature' );
|
127 | * command.forceDisabled( 'OtherFeature' );
|
128 | * command.clearForceDisabled( 'MyFeature' );
|
129 | * command.isEnabled; // -> false
|
130 | * command.clearForceDisabled( 'OtherFeature' );
|
131 | * command.isEnabled; // -> true
|
132 | * ```
|
133 | *
|
134 | * Multiple disabling with the same identifier is redundant:
|
135 | *
|
136 | * ```ts
|
137 | * command.forceDisabled( 'MyFeature' );
|
138 | * command.forceDisabled( 'MyFeature' );
|
139 | * command.clearForceDisabled( 'MyFeature' );
|
140 | * command.isEnabled; // -> true
|
141 | * ```
|
142 | *
|
143 | * **Note:** some commands or algorithms may have more complex logic when it comes to enabling or disabling certain commands,
|
144 | * so the command might be still disabled after {@link #clearForceDisabled} was used.
|
145 | *
|
146 | * @param id Unique identifier for disabling. Use the same id when {@link #clearForceDisabled enabling back} the command.
|
147 | */
|
148 | forceDisabled(id: string): void;
|
149 | /**
|
150 | * Clears forced disable previously set through {@link #forceDisabled}. See {@link #forceDisabled}.
|
151 | *
|
152 | * @param id Unique identifier, equal to the one passed in {@link #forceDisabled} call.
|
153 | */
|
154 | clearForceDisabled(id: string): void;
|
155 | /**
|
156 | * Executes the command.
|
157 | *
|
158 | * A command may accept parameters. They will be passed from {@link module:core/editor/editor~Editor#execute `editor.execute()`}
|
159 | * to the command.
|
160 | *
|
161 | * The `execute()` method will automatically abort when the command is disabled ({@link #isEnabled} is `false`).
|
162 | * This behavior is implemented by a high priority listener to the {@link #event:execute} event.
|
163 | *
|
164 | * In order to see how to disable a command from "outside" see the {@link #isEnabled} documentation.
|
165 | *
|
166 | * This method may return a value, which would be forwarded all the way down to the
|
167 | * {@link module:core/editor/editor~Editor#execute `editor.execute()`}.
|
168 | *
|
169 | * @fires execute
|
170 | */
|
171 | execute(...args: Array<unknown>): unknown;
|
172 | /**
|
173 | * Destroys the command.
|
174 | */
|
175 | destroy(): void;
|
176 | }
|
177 | /**
|
178 | * Event fired by the {@link module:core/command~Command#execute} method. The command action is a listener to this event so it's
|
179 | * possible to change/cancel the behavior of the command by listening to this event.
|
180 | *
|
181 | * See {@link module:utils/observablemixin~Observable#decorate} for more information and samples.
|
182 | *
|
183 | * **Note:** This event is fired even if command is disabled. However, it is automatically blocked
|
184 | * by a high priority listener in order to prevent command execution.
|
185 | *
|
186 | * @eventName ~Command#execute
|
187 | */
|
188 | export type CommandExecuteEvent = DecoratedMethodEvent<Command, 'execute'>;
|
189 | export {};
|