3

Background

Hi Everyone! I'm recently dived into Gutenberg to try and convert an old theme. One problem that I've ran into multiple times is that if I have a paragraph block, and I'm deleting the text to start over, I'll hold down backspace. What happens i:

  1. It'll empty out the block
  2. Eventually, the last character is erased, and then the block is removed.
  3. The browser navigates backwards a page before I can let go of the cursor.

I've had this happen multiple times.

Question

How can I disable the behavior of backspace removing an empty paragraph block? I'd prefer to have the backspace key do nothing at all if the cursor is in an empty paragraph block.

2

After trial and error, I've figured out a way. It may not be perfect but it works for every circumstance I've tried.

We need to use the wp.data.select function, and select the 'core/block-editor', and finally use the getSelectionStart() function. That will tell us if the current block has selectable text, and if so, where our selection starts. If there is no selection, or the selection starts at zero, I want to prevent Backspace from doing anything.

The Code

document.body.addEventListener('keydown', function(event){

    if ( ( event.key == 'Backspace' ) ) {

        let selectionStart = wp.data.select('core/block-editor').getSelectionStart();

        // selectionStart will return an empty object {} if there is no block selected that has editable text. If will have the key 'offset' if there is. So we check for offset, and whether it's value is 0.

        if ( ( ! ( 'offset' in selectionStart ) ) || ( selectionStart.offset === 0 ) ) {

            event.preventDefault();

        }

    }

});

Edit: Another Option

After further playing around with this, I decided I wanted to allow backspace to remove blocks if the blocks were NOT the first child of a parent block. That means if I have three paragraphs in a row, I want to be able to hold backspace and remove paragraph three, then two, but stop with parapgraph one. Here is a version that does that.

document.body.addEventListener('keydown', function(event){

    if ( ( event.key == 'Backspace' ) ) {

        let selectionStart = select('core/block-editor').getSelectionStart();

        let notInEditableBlock = ! ( 'offset' in selectionStart );

        let cursorIsAtBeginningOfEditableBlock = notInEditableBlock ? false : selectionStart.offset === 0;

        let currentBlockIsFirstChild = select('core/block-editor').getPreviousBlockClientId() === null;

        if ( ( notInEditableBlock ) || ( cursorIsAtBeginningOfEditableBlock && currentBlockIsFirstChild ) ) {

            event.preventDefault();

        }

    }

});

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.