Sign up (with export icon)

Handling keystrokes

Contribute to this guide Show the table of contents

Accessibility

Copy link

Currently, our highlight plugin requires the user to click the button in the editor’s toolbar to highlight selected text. This can be a problem for users who rely on the keyboard, so let’s add a keyboard shortcut as an alternative way to highlight the text.

Adding keyboard shortcuts

Copy link

A common shortcut for highlighting text is Ctrl + Alt + H (on Windows systems), so this is what we are going to use in our plugin. On macOS these keystrokes will get automatically translated to Cmd + + H

To execute the highlight command when those keys are pressed, add the following code to the end of the Highlight function:

editor.keystrokes.set( 'Ctrl+Alt+H', 'highlight' );
Copy code

As you can see, the first parameter passed to the function is a string representing the keys that need to be pressed, while the second parameter is the name of the command to be executed. Alternatively, instead of the command name, you can pass a callback and call the command inside:

editor.keystrokes.set( 'Ctrl+Alt+H', ( event, cancel ) => {
    editor.execute( 'highlight' );
    cancel();
} );
Copy code

Adding shortcut information to the Accessibility help dialog

Copy link

The Accessibility help dialog displays a complete list of available keyboard shortcuts with their descriptions. It can be opened by pressing Alt + 0 (on Windows) or ⌥0 (on macOS). It does not know about the shortcut we just added, though.

The dialog reads from the editor.accessibility namespace where all the information about keystrokes and their accessible labels is stored. There is an API to add new entries: (addKeystrokeInfos, addKeystrokeInfoGroup, and addKeystrokeInfoCategory methods).

In this case, a simple editor.accessibility.addKeystrokeInfos( ... ) is all you need for the Accessibility help dialog to learn about the new shortcut:

const t = editor.t;

editor.accessibility.addKeystrokeInfos( {
    keystrokes: [
        {
            label: t( 'Highlight text' ),
            keystroke: 'Ctrl+Alt+H'
        }
    ]
} );
Copy code

You can learn more about the AccessibilityHelp plugin and the editor.accessibility namespace in the API reference.

Updating button tooltip

Copy link

When you hover over the “Undo” and “Redo” buttons, you will see a tooltip containing the name of the operation and their respective keyboard shortcuts. However, when hovering over the “Highlight” button, the keyboard shortcut is missing.

We can fix this, by adding the keystroke attribute to the button:

button.set( {
    label: t( 'Highlight' ),
    withText: true,
    tooltip: true,
    isToggleable: true,
    keystroke: 'Ctrl+Alt+H' // Add this attribute.
} );
Copy code

Deep dive

Copy link

The one-liner we used to register a new keyboard shortcut hides a lot of complexity. Let’s see how we can achieve the same effect using more low-level APIs to better understand what is really happening.

To get the keystrokes, we can listen to the events from the event system we explored in the previous tutorial chapter fired from the Editing view document.

// 5570632 is the code for the 'Ctrl+Alt+H' keyboard shortcut.
editor.editing.view.document.on( 'keydown:5570632', ( event, data ) => {
    // Call the `highlight` command.
    editor.execute( 'highlight' );

    // Stop the event in the DOM.
    data.preventDefault();
    data.stopPropagation();

    // Stop the event in the framework.
    event.stop();

    // Mark this event as handled.
    event.return = true;
} );
Copy code

As you can see above, we registered a listener that listens to the events fired when the Ctrl + Alt + H keys are pressed. When this happens, the callback is called and it executes the highlight command.

To make sure that nothing unexpected happens (for example if some browser extension also uses this keyboard shortcut), we stop further propagation of the event. This prevents any other DOM or framework listeners from reacting to this key combination and marks the event as handled.

What’s next

Copy link

In the next and final chapter, you will learn more about plugin configuration.