From de475b6d82b5e3645daaaf8b84b1948f49bf62d0 Mon Sep 17 00:00:00 2001 From: Tim Baumann Date: Fri, 10 Jul 2020 15:38:30 +0200 Subject: [PATCH] prosemirror-commands: Fix Command type (#45972) The 'dispatch' and 'view' arguments must be optional to support 'dry runs'. Also add doc comment for 'Command' type by copying relevant the part from the ProseMirror documentation. Also simplify type definition of 'chainCommands' using 'Command'. --- types/prosemirror-commands/index.d.ts | 18 +++++++++++------- .../prosemirror-commands-tests.ts | 4 ++++ .../prosemirror-keymap-tests.ts | 8 ++++++-- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/types/prosemirror-commands/index.d.ts b/types/prosemirror-commands/index.d.ts index 7f070ebb5d..50f3d93f53 100644 --- a/types/prosemirror-commands/index.d.ts +++ b/types/prosemirror-commands/index.d.ts @@ -12,11 +12,19 @@ import { MarkType, Node as ProsemirrorNode, NodeType, Schema } from 'prosemirror import { EditorState, Transaction } from 'prosemirror-state'; import { EditorView } from 'prosemirror-view'; +/** + * A command function takes an editor state, *optionally* a `dispatch` + * function that it can use to dispatch a transaction and optionally + * an `EditorView` instance. It should return a boolean that indicates + * whether it could perform any action. When no `dispatch` callback is + * passed, the command should do a 'dry run', determining whether it is + * applicable, but not actually doing anything. + */ export interface Command { ( state: EditorState, - dispatch: (tr: Transaction) => void, - view: EditorView + dispatch?: (tr: Transaction) => void, + view?: EditorView ): boolean; } @@ -218,11 +226,7 @@ export function autoJoin( * Combine a number of command functions into a single function (which * calls them one by one until one returns true). */ -export function chainCommands( - ...commands: Array< - (p1: EditorState, p2?: (tr: Transaction) => void, p3?: EditorView) => boolean - > -): (p1: EditorState, p2?: (tr: Transaction) => void, p3?: EditorView) => boolean; +export function chainCommands(...commands: Array>): Command; /** * A basic keymap containing bindings not specific to any schema. * Binds the following keys (when multiple commands are listed, they diff --git a/types/prosemirror-commands/prosemirror-commands-tests.ts b/types/prosemirror-commands/prosemirror-commands-tests.ts index 9db641b03f..ab7e5fc1a0 100644 --- a/types/prosemirror-commands/prosemirror-commands-tests.ts +++ b/types/prosemirror-commands/prosemirror-commands-tests.ts @@ -19,3 +19,7 @@ const keymap: commands.Keymap = { ArrowLeft: commands.joinBackward, // takes three args ArrowRight: (state, dispatch, view) => true, // arg types inferred }; + +Object.keys(commands.baseKeymap).forEach(key => { + keymap[key] = keymap[key] ? commands.chainCommands(keymap[key], commands.baseKeymap[key]) : commands.baseKeymap[key]; +}); diff --git a/types/prosemirror-keymap/prosemirror-keymap-tests.ts b/types/prosemirror-keymap/prosemirror-keymap-tests.ts index 803adde2b1..8b8d515b9f 100644 --- a/types/prosemirror-keymap/prosemirror-keymap-tests.ts +++ b/types/prosemirror-keymap/prosemirror-keymap-tests.ts @@ -4,7 +4,9 @@ import { Plugin } from 'prosemirror-state'; const plugin1: Plugin = keymap.keymap({ // Test that the argument types are correctly inferred Enter: (state, dispatch, view) => { - dispatch(state.tr.insertText("hello")); + if (dispatch) { + dispatch(state.tr.insertText("hello")); + } return true; }, }); @@ -14,7 +16,9 @@ const plugin2 = new Plugin({ handleKeyDown: keymap.keydownHandler({ // Test that the argument types are correctly inferred Enter: (state, dispatch, view) => { - dispatch(state.tr.insertText("hello")); + if (dispatch) { + dispatch(state.tr.insertText("hello")); + } return true; } }),