1 | import type { AnyFunction, CommandFunction, CommandFunctionProps, EmptyShape, Fragment, FromToProps, LiteralUnion, MarkType, NodeType, PrimitiveSelection, ProsemirrorAttributes, ProsemirrorNode, RemirrorContentType, Static, Transaction } from '@remirror/core-types';
|
2 | import { RemoveMarkProps, ReplaceTextProps, ToggleBlockItemProps } from '@remirror/core-utils';
|
3 | import { Mark } from '@remirror/pm/model';
|
4 | import type { EditorView } from '@remirror/pm/view';
|
5 | import { InsertTextOptions, ToggleMarkProps } from '../commands';
|
6 | import { AnyExtension, ChainedFromExtensions, CommandNames, CommandsFromExtensions, Helper, PlainExtension, UiCommandNames } from '../extension';
|
7 | import type { CreateExtensionPlugin, ExtensionCommandReturn, FocusType, StateUpdateLifecycleProps } from '../types';
|
8 | import { CommandDecoratorOptions } from './builtin-decorators';
|
9 | export interface CommandOptions {
|
10 | |
11 |
|
12 |
|
13 |
|
14 |
|
15 | trackerClassName?: Static<string>;
|
16 | |
17 |
|
18 |
|
19 |
|
20 |
|
21 | trackerNodeName?: Static<string>;
|
22 | }
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 | export declare class CommandsExtension extends PlainExtension<CommandOptions> {
|
34 | get name(): "commands";
|
35 | |
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 |
|
42 |
|
43 | get transaction(): Transaction;
|
44 | |
45 |
|
46 |
|
47 |
|
48 |
|
49 |
|
50 | private _transaction?;
|
51 | |
52 |
|
53 |
|
54 | private readonly decorated;
|
55 | onCreate(): void;
|
56 | |
57 |
|
58 |
|
59 | onView(view: EditorView): void;
|
60 | |
61 |
|
62 |
|
63 | onStateUpdate({ state }: StateUpdateLifecycleProps): void;
|
64 | |
65 |
|
66 |
|
67 |
|
68 | createPlugin(): CreateExtensionPlugin;
|
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 | customDispatch(command: CommandFunction): CommandFunction;
|
124 | |
125 |
|
126 |
|
127 |
|
128 |
|
129 | insertText(text: string | (() => Promise<string>), options?: InsertTextOptions): CommandFunction;
|
130 | /**
|
131 | * Select the text within the provided range.
|
132 | *
|
133 | * Here are some ways it can be used.
|
134 | *
|
135 | * ```ts
|
136 | * // Set to the end of the document.
|
137 | * commands.selectText('end');
|
138 | *
|
139 | * // Set the selection to the start of the document.
|
140 | * commands.selectText('start');
|
141 | *
|
142 | * // Select all the text in the document.
|
143 | * commands.selectText('all')
|
144 | *
|
145 | * // Select a range of text. It's up to you to make sure the selected
|
146 | * // range is valid.
|
147 | * commands.selectText({ from: 10, to: 15 });
|
148 | *
|
149 | * // Specify the anchor and range in the selection.
|
150 | * commands.selectText({ anchor: 10, head: 15 });
|
151 | *
|
152 | * // Set to a specific position.
|
153 | * commands.selectText(10);
|
154 | *
|
155 | * // Use a ProseMirror selection
|
156 | * commands.selectText(TextSelection.near(state.doc.resolve(10)))
|
157 | * ```
|
158 | *
|
159 | * Although this is called `selectText` you can provide your own selection
|
160 | * option which can be any type of selection.
|
161 | */
|
162 | selectText(selection: PrimitiveSelection, options?: {
|
163 | forceUpdate?: boolean;
|
164 | }): CommandFunction;
|
165 | /**
|
166 | * Select the link at the current location.
|
167 | */
|
168 | selectMark(type: string | MarkType): CommandFunction;
|
169 | /**
|
170 | * Delete the provided range or current selection.
|
171 | */
|
172 | delete(range?: FromToProps): CommandFunction;
|
173 | /**
|
174 | * Fire an empty update to trigger an update to all decorations, and state
|
175 | * that may not yet have run.
|
176 | *
|
177 | * This can be used in extensions to trigger updates when certain options that
|
178 | * affect the editor state have changed.
|
179 | *
|
180 | * @param action - provide an action which is called just before the empty
|
181 | * update is dispatched (only when dispatch is available). This can be used in
|
182 | * chainable editor scenarios when you want to lazily invoke an action at the
|
183 | * point the update is about to be applied.
|
184 | */
|
185 | emptyUpdate(action?: () => void): CommandFunction;
|
186 | /**
|
187 | * Force an update of the specific updatable ProseMirror props.
|
188 | *
|
189 | * This command is always available as a builtin command.
|
190 | *
|
191 | * @category Builtin Command
|
192 | */
|
193 | forceUpdate(...keys: UpdatableViewProps[]): CommandFunction;
|
194 | /**
|
195 | * Update the attributes for the node at the specified `pos` in the
|
196 | * editor.
|
197 | *
|
198 | * @category Builtin Command
|
199 | */
|
200 | updateNodeAttributes<Type extends object>(pos: number, attrs: ProsemirrorAttributes<Type>): CommandFunction;
|
201 | /**
|
202 | * Set the content of the editor while preserving history.
|
203 | *
|
204 | * Under the hood this is replacing the content in the document with the new
|
205 | * state.doc of the provided content.
|
206 | *
|
207 | * If the content is a string you will need to ensure you have the proper
|
208 | * string handler set up in the editor.
|
209 | */
|
210 | setContent(content: RemirrorContentType, selection?: PrimitiveSelection): CommandFunction;
|
211 | /**
|
212 | * Reset the content of the editor while preserving the history.
|
213 | *
|
214 | * This means that undo and redo will still be active since the doc is replaced with a new doc.
|
215 | */
|
216 | resetContent(): CommandFunction;
|
217 | /**
|
218 | * Fire an update to remove the current range selection. The cursor will
|
219 | * be placed at the anchor of the current range selection.
|
220 | *
|
221 | * A range selection is a non-empty text selection.
|
222 | *
|
223 | * @category Builtin Command
|
224 | */
|
225 | emptySelection(): CommandFunction;
|
226 | /**
|
227 | * Insert a new line into the editor.
|
228 | *
|
229 | * Depending on editor setup and where the cursor is placed this may have
|
230 | * differing impacts.
|
231 | *
|
232 | * @category Builtin Command
|
233 | */
|
234 | insertNewLine(): CommandFunction;
|
235 | /**
|
236 | * Insert a node into the editor with the provided content.
|
237 | *
|
238 | * @category Builtin Command
|
239 | */
|
240 | insertNode(node: string | NodeType | ProsemirrorNode | Fragment, options?: InsertNodeOptions): CommandFunction;
|
241 | /**
|
242 | * Set the focus for the editor.
|
243 | *
|
244 | * If using this with chaining this should only be placed at the end of
|
245 | * the chain. It can cause hard to debug issues when used in the middle of
|
246 | * a chain.
|
247 | *
|
248 | * ```tsx
|
249 | * import { useCallback } from 'react';
|
250 | * import { useRemirrorContext } from '@remirror/react';
|
251 | *
|
252 | * const MenuButton = () => {
|
253 | * const { chain } = useRemirrorContext();
|
254 | * const onClick = useCallback(() => {
|
255 | * chain
|
256 | * .toggleBold()
|
257 | * .focus('end')
|
258 | * .run();
|
259 | * }, [chain])
|
260 | *
|
261 | * return <button onClick={onClick}>Bold</button>
|
262 | * }
|
263 | * ```
|
264 | */
|
265 | focus(position?: FocusType): CommandFunction;
|
266 | /**
|
267 | * Blur focus from the editor and also update the selection at the same
|
268 | * time.
|
269 | */
|
270 | blur(position?: PrimitiveSelection): CommandFunction;
|
271 | /**
|
272 | * Set the block type of the current selection or the provided range.
|
273 | *
|
274 | * @param nodeType - the node type to create
|
275 | * @param attrs - the attributes to add to the node type
|
276 | * @param selection - the position in the document to set the block node
|
277 | * @param preserveAttrs - when true preserve the attributes at the provided selection
|
278 | */
|
279 | setBlockNodeType(nodeType: string | NodeType, attrs?: ProsemirrorAttributes, selection?: PrimitiveSelection, preserveAttrs?: boolean): CommandFunction;
|
280 | /**
|
281 | * Toggle between wrapping an inactive node with the provided node type, and
|
282 | * lifting it up into it's parent.
|
283 | *
|
284 | * @param nodeType - the node type to toggle
|
285 | * @param attrs - the attrs to use for the node
|
286 | * @param selection - the selection point in the editor to perform the action
|
287 | */
|
288 | toggleWrappingNode(nodeType: string | NodeType, attrs?: ProsemirrorAttributes, selection?: PrimitiveSelection): CommandFunction;
|
289 | /**
|
290 | * Toggle a block between the provided type and toggleType.
|
291 | */
|
292 | toggleBlockNodeItem(toggleProps: ToggleBlockItemProps): CommandFunction;
|
293 | /**
|
294 | * Wrap the selection or the provided text in a node of the given type with the
|
295 | * given attributes.
|
296 | */
|
297 | wrapInNode(nodeType: string | NodeType, attrs?: ProsemirrorAttributes, range?: FromToProps | undefined): CommandFunction;
|
298 | /**
|
299 | * Removes a mark from the current selection or provided range.
|
300 | */
|
301 | applyMark(markType: string | MarkType, attrs?: ProsemirrorAttributes, selection?: PrimitiveSelection): CommandFunction;
|
302 | /**
|
303 | * Removes a mark from the current selection or provided range.
|
304 | */
|
305 | toggleMark(props: ToggleMarkProps): CommandFunction;
|
306 | /**
|
307 | * Removes a mark from the current selection or provided range.
|
308 | */
|
309 | removeMark(props: RemoveMarkProps): CommandFunction;
|
310 | /**
|
311 | * Set the meta data to attach to the editor on the next update.
|
312 | */
|
313 | setMeta(name: string, value: unknown): CommandFunction;
|
314 | /**
|
315 | * Select all text in the editor.
|
316 | */
|
317 | selectAll(): CommandFunction;
|
318 | /**
|
319 | * Copy the selected content for non empty selections.
|
320 | */
|
321 | copy(): CommandFunction;
|
322 | /**
|
323 | * Select all text in the editor.
|
324 | */
|
325 | paste(): CommandFunction;
|
326 | /**
|
327 | * Cut the selected content.
|
328 | */
|
329 | cut(): CommandFunction;
|
330 | /**
|
331 | * Replaces text with an optional appended string at the end. The replacement
|
332 | * can be text, or a custom node.
|
333 | *
|
334 | * @param props - see [[`ReplaceTextProps`]]
|
335 | */
|
336 | replaceText(props: ReplaceTextProps): CommandFunction;
|
337 | /**
|
338 | * Get the all the decorated commands available on the editor instance.
|
339 | */
|
340 | getAllCommandOptions(): Helper<Record<string, WithName<CommandDecoratorOptions>>>;
|
341 | /**
|
342 | * Get the options that were passed into the provided command.
|
343 | */
|
344 | getCommandOptions(name: string): Helper<WithName<CommandDecoratorOptions> | undefined>;
|
345 | /**
|
346 | * A short hand way of getting the `view`, `state`, `tr` and `dispatch`
|
347 | * methods.
|
348 | */
|
349 | getCommandProp(): Helper<Required<CommandFunctionProps>>;
|
350 | /**
|
351 | * Update the command options via a shallow merge of the provided options. If
|
352 | * no options are provided the entry is deleted.
|
353 | *
|
354 | * @internal
|
355 | */
|
356 | updateDecorated(name: string, options?: Partial<WithName<CommandDecoratorOptions>>): void;
|
357 | /**
|
358 | * Needed on iOS since `requestAnimationFrame` doesn't breaks the focus
|
359 | * implementation.
|
360 | */
|
361 | private handleIosFocus;
|
362 | /**
|
363 | * Focus the editor after a slight delay.
|
364 | */
|
365 | private delayedFocus;
|
366 | /**
|
367 | * A helper for forcing through updates in the view layer. The view layer can
|
368 | * check for the meta data of the transaction with
|
369 | * `manager.store.getForcedUpdate(tr)`. If that has a value then it should use
|
370 | * the unique symbol to update the key.
|
371 | */
|
372 | private readonly forceUpdateTransaction;
|
373 | /**
|
374 | * Check for a forced update in the transaction. This pulls the meta data
|
375 | * from the transaction and if it is true then it was a forced update.
|
376 | *
|
377 | * ```ts
|
378 | * import { CommandsExtension } from 'remirror/extensions';
|
379 | *
|
380 | * const commandsExtension = manager.getExtension(CommandsExtension);
|
381 | * log(commandsExtension.getForcedUpdates(tr))
|
382 | * ```
|
383 | *
|
384 | * This can be used for updating:
|
385 | *
|
386 | * - `nodeViews`
|
387 | * - `editable` status of the editor
|
388 | * - `attributes` - for the top level node
|
389 | *
|
390 | * @internal
|
391 | */
|
392 | private getForcedUpdates;
|
393 | /**
|
394 | * Get the command metadata.
|
395 | */
|
396 | private getCommandMeta;
|
397 | private setCommandMeta;
|
398 | /**
|
399 | * Add the commands from the provided `commands` property to the `chained`,
|
400 | * `original` and `unchained` objects.
|
401 | */
|
402 | private addCommands;
|
403 | /**
|
404 | * Create an unchained command method.
|
405 | */
|
406 | private unchainedFactory;
|
407 | /**
|
408 | * Create the unchained command.
|
409 | */
|
410 | private createUnchainedCommand;
|
411 | /**
|
412 | * Create a chained command method.
|
413 | */
|
414 | private chainedFactory;
|
415 | }
|
416 | export interface InsertNodeOptions {
|
417 | attrs?: ProsemirrorAttributes;
|
418 | marks?: Array<Mark | string | MarkType>;
|
419 | /**
|
420 | * The content to insert.
|
421 | */
|
422 | content?: Fragment | ProsemirrorNode | ProsemirrorNode[] | string;
|
423 | /**
|
424 | * @deprecated use selection property instead.
|
425 | */
|
426 | range?: FromToProps;
|
427 | /**
|
428 | * Set the selection where the command should occur.
|
429 | */
|
430 | selection?: PrimitiveSelection;
|
431 | /**
|
432 | * Set this to true to replace an empty parent block with this content (if the
|
433 | * content is a block node).
|
434 | */
|
435 | replaceEmptyParentBlock?: boolean;
|
436 | }
|
437 | /**
|
438 | * Provides the list of Prosemirror EditorView props that should be updated/
|
439 | */
|
440 | export type ForcedUpdateMeta = UpdatableViewProps[];
|
441 | export type UpdatableViewProps = 'attributes' | 'editable';
|
442 | export interface CommandExtensionMeta {
|
443 | forcedUpdates?: UpdatableViewProps[];
|
444 | }
|
445 | /**
|
446 | * A type with a name property.
|
447 | */
|
448 | type WithName<Type> = Type & {
|
449 | name: string;
|
450 | };
|
451 | declare global {
|
452 | namespace Remirror {
|
453 | interface ManagerStore<Extension extends AnyExtension> {
|
454 | /**
|
455 | * Get the forced updates from the provided transaction.
|
456 | */
|
457 | getForcedUpdates: (tr: Transaction) => ForcedUpdateMeta;
|
458 | /**
|
459 | * Enables the use of custom commands created by extensions which extend
|
460 | * the functionality of your editor in an expressive way.
|
461 | *
|
462 | * @remarks
|
463 | *
|
464 | * Commands are synchronous and immediately dispatched. This means that
|
465 | * they can be used to create menu items when the functionality you need
|
466 | * is already available by the commands.
|
467 | *
|
468 | * ```ts
|
469 | * if (commands.toggleBold.isEnabled()) {
|
470 | * commands.toggleBold();
|
471 | * }
|
472 | * ```
|
473 | */
|
474 | commands: CommandsFromExtensions<Extension>;
|
475 | /**
|
476 | * Chainable commands for composing functionality together in quaint and
|
477 | * beautiful ways
|
478 | *
|
479 | * @remarks
|
480 | *
|
481 | * You can use this property to create expressive and complex commands
|
482 | * that build up the transaction until it can be run.
|
483 | *
|
484 | * The way chainable commands work is by adding multiple steps to a shared
|
485 | * transaction which is then dispatched when the `run` command is called.
|
486 | * This requires making sure that commands within your code use the `tr`
|
487 | * that is provided rather than the `state.tr` property. `state.tr`
|
488 | * creates a new transaction which is not shared by the other steps in a
|
489 | * chainable command.
|
490 | *
|
491 | * The aim is to make as many commands as possible chainable as explained
|
492 | * [here](https://github.com/remirror/remirror/issues/418#issuecomment-666922209).
|
493 | *
|
494 | * There are certain commands that can't be made chainable.
|
495 | *
|
496 | * - undo
|
497 | * - redo
|
498 | *
|
499 | * ```ts
|
500 | * chain
|
501 | * .toggleBold()
|
502 | * .insertText('Hi')
|
503 | * .setSelection('all')
|
504 | * .run();
|
505 | * ```
|
506 | *
|
507 | * The `run()` method ends the chain and dispatches the command.
|
508 | */
|
509 | chain: ChainedFromExtensions<Extension>;
|
510 | }
|
511 | interface BaseExtension {
|
512 | /**
|
513 | * `ExtensionCommands`
|
514 | *
|
515 | * This pseudo property makes it easier to infer Generic types of this
|
516 | * class.
|
517 | *
|
518 | * @internal
|
519 | */
|
520 | ['~C']: this['createCommands'] extends AnyFunction ? ReturnType<this['createCommands']> : EmptyShape;
|
521 | /**
|
522 | * @experimental
|
523 | *
|
524 | * Stores all the command names for this decoration that have been added
|
525 | * as decorators to the extension instance. This is used by the
|
526 | * `CommandsExtension` to pick the commands and store meta data attached
|
527 | * to each command.
|
528 | *
|
529 | * @internal
|
530 | */
|
531 | decoratedCommands?: Record<string, CommandDecoratorOptions>;
|
532 | /**
|
533 | * Create and register commands for that can be called within the editor.
|
534 | *
|
535 | * These are typically used to create menu's actions and as a direct
|
536 | * response to user actions.
|
537 | *
|
538 | * @remarks
|
539 | *
|
540 | * The `createCommands` method should return an object with each key being
|
541 | * unique within the editor. To ensure that this is the case it is
|
542 | * recommended that the keys of the command are namespaced with the name
|
543 | * of the extension.
|
544 | *
|
545 | * ```ts
|
546 | * import { ExtensionFactory } from '@remirror/core';
|
547 | *
|
548 | * const MyExtension = ExtensionFactory.plain({
|
549 | * name: 'myExtension',
|
550 | * version: '1.0.0',
|
551 | * createCommands() {
|
552 | * return {
|
553 | * haveFun() {
|
554 | * return ({ state, dispatch }) => {
|
555 | * if (dispatch) {
|
556 | * dispatch(tr.insertText('Have fun!'));
|
557 | * }
|
558 | *
|
559 | * return true;
|
560 | * }
|
561 | * },
|
562 | * }
|
563 | * }
|
564 | * })
|
565 | * ```
|
566 | *
|
567 | * The actions available in this case would be `undoHistory` and
|
568 | * `redoHistory`. It is unlikely that any other extension would override
|
569 | * these commands.
|
570 | *
|
571 | * Another benefit of commands is that they are picked up by typescript
|
572 | * and can provide code completion for consumers of the extension.
|
573 | */
|
574 | createCommands?(): ExtensionCommandReturn;
|
575 | }
|
576 | interface ExtensionStore {
|
577 | /**
|
578 | * A property containing all the available commands in the editor.
|
579 | *
|
580 | * This should only be accessed after the `onView` lifecycle method
|
581 | * otherwise it will throw an error. If you want to use it in the
|
582 | * `createCommands` function then make sure it is used within the returned
|
583 | * function scope and not in the outer scope.
|
584 | */
|
585 | commands: CommandsFromExtensions<Extensions | (AnyExtension & {
|
586 | _T: false;
|
587 | })>;
|
588 | /**
|
589 | * A method that returns an object with all the chainable commands
|
590 | * available to be run.
|
591 | *
|
592 | * @remarks
|
593 | *
|
594 | * Each chainable command mutates the states transaction so after running
|
595 | * all your commands. you should dispatch the desired transaction.
|
596 | *
|
597 | * This should only be called when the view has been initialized (i.e.)
|
598 | * within the `createCommands` method calls.
|
599 | *
|
600 | * ```ts
|
601 | * import { ExtensionFactory } from '@remirror/core';
|
602 | *
|
603 | * const MyExtension = ExtensionFactory.plain({
|
604 | * name: 'myExtension',
|
605 | * version: '1.0.0',
|
606 | * createCommands: () => {
|
607 | *
|
608 | * methods.
|
609 | * const chain = this.store.chain;
|
610 | *
|
611 | * return {
|
612 | *
|
613 | * haveFun() {
|
614 | * return ({ state, dispatch }) =>
|
615 | * this.store.chain.insertText('fun!').run(); ✅
|
616 | * },
|
617 | * }
|
618 | * }
|
619 | * })
|
620 | * ```
|
621 | *
|
622 | * This should only be accessed after the `EditorView` has been fully
|
623 | * attached to the `RemirrorManager`.
|
624 | *
|
625 | * The chain can also be called as a function with a custom `tr`
|
626 | * parameter. This allows you to provide a custom transaction to use
|
627 | * within the chainable commands.
|
628 | *
|
629 | * Use the command at the beginning of the command chain to override the
|
630 | * shared transaction.
|
631 | *
|
632 | * There are times when you want to be sure of the transaction which is
|
633 | * being updated.
|
634 | *
|
635 | * To restore the previous transaction call the `restore` chained method.
|
636 | *
|
637 | * @param tr - the transaction to set
|
638 | */
|
639 | chain: ChainedFromExtensions<Extensions | (AnyExtension & {
|
640 | _T: false;
|
641 | })>;
|
642 | }
|
643 | interface AllExtensions {
|
644 | commands: CommandsExtension;
|
645 | }
|
646 | /**
|
647 | * The command names for all core extensions.
|
648 | */
|
649 | type AllCommandNames = LiteralUnion<CommandNames<Remirror.Extensions>, string>;
|
650 | /**
|
651 | * The command names for all core extensions.
|
652 | */
|
653 | type AllUiCommandNames = LiteralUnion<UiCommandNames<Remirror.Extensions>, string>;
|
654 | }
|
655 | }
|
656 | export {};
|
657 |
|
\ | No newline at end of file |