Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rich Text: Treat ctrl+d as delete #15019

Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions packages/block-editor/src/components/rich-text/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import memize from 'memize';
import { Component, Fragment, RawHTML } from '@wordpress/element';
import { isHorizontalEdge } from '@wordpress/dom';
import { createBlobURL } from '@wordpress/blob';
import { BACKSPACE, DELETE, ENTER, LEFT, RIGHT, SPACE } from '@wordpress/keycodes';
import { BACKSPACE, ENTER, LEFT, RIGHT, SPACE, isDeleteKeyboardEvent, isReverseDeleteKeyboardEvent } from '@wordpress/keycodes';
import { withDispatch, withSelect } from '@wordpress/data';
import { pasteHandler, children, getBlockTransforms, findTransform } from '@wordpress/blocks';
import { withInstanceId, withSafeTimeout, compose } from '@wordpress/compose';
Expand Down Expand Up @@ -551,15 +551,13 @@ export class RichText extends Component {
return;
}

const { keyCode } = event;
const isReverse = keyCode === BACKSPACE;

// Only process delete if the key press occurs at uncollapsed edge.
if ( ! isCollapsed( this.createRecord() ) ) {
return;
}

const empty = this.isEmpty();
const isReverse = isReverseDeleteKeyboardEvent( event );

// It is important to consider emptiness because an empty container
// will include a padding BR node _after_ the caret, so in a forward
Expand Down Expand Up @@ -619,7 +617,7 @@ export class RichText extends Component {
}
}

if ( keyCode === DELETE || keyCode === BACKSPACE ) {
if ( isDeleteKeyboardEvent( event ) ) {
const value = this.createRecord();
const { replacements, text, start, end } = value;

Expand Down
34 changes: 34 additions & 0 deletions packages/keycodes/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ Keycode for COMMAND/META key.

Keycode for CTRL key.

<a name="D" href="#D">#</a> **D**

Keycode for the D key

<a name="DELETE" href="#DELETE">#</a> **DELETE**

Keycode for DELETE key.
Expand Down Expand Up @@ -92,6 +96,23 @@ Keycode for ESCAPE key.

Keycode for F10 key.

<a name="H" href="#H">#</a> **H**

Keycode for the H key

<a name="isDeleteKeyboardEvent" href="#isDeleteKeyboardEvent">#</a> **isDeleteKeyboardEvent**

Determine if an event is a "delete" keyboard event.
This includes keypresses to `delete`, `backspace`, `ctrl+d`, `ctrl+h`, etc.

_Parameters_

- _event_ `SyntheticEvent`: A synthetic keyboard event.

_Returns_

- `boolean`: True if the event is a "delete" keyboard event, otherwise false.

<a name="isKeyboardEvent" href="#isKeyboardEvent">#</a> **isKeyboardEvent**

An object that contains functions to check if a keyboard event matches a
Expand All @@ -103,6 +124,19 @@ _Type_

- `Object` Keyed map of functions to match events.

<a name="isReverseDeleteKeyboardEvent" href="#isReverseDeleteKeyboardEvent">#</a> **isReverseDeleteKeyboardEvent**

Determine if an event is a "reverse delete" keyboard event.
This includes keypresses to `backspace`, `ctrl+h`, etc.

_Parameters_

- _event_ `SyntheticEvent`: A synthetic keyboard event.

_Returns_

- `boolean`: True if the event is a "reverse delete" keyboard event, otherwise false.

<a name="LEFT" href="#LEFT">#</a> **LEFT**

Keycode for LEFT key.
Expand Down
32 changes: 32 additions & 0 deletions packages/keycodes/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,14 @@ export const COMMAND = 'meta';
* Keycode for SHIFT key.
*/
export const SHIFT = 'shift';
/**
* Keycode for the D key
*/
export const D = 'D'.charCodeAt( 0 );
/**
* Keycode for the H key
*/
export const H = 'H'.charCodeAt( 0 );

/**
* Object that contains functions that return the available modifier
Expand Down Expand Up @@ -216,3 +224,27 @@ export const isKeyboardEvent = mapValues( modifiers, ( getModifiers ) => {
return event.key === character;
};
} );

/**
* Determine if an event is a "delete" keyboard event.
* This includes keypresses to `delete`, `backspace`, `ctrl+d`, `ctrl+h`, etc.
* @param {SyntheticEvent} event A synthetic keyboard event.
* @return {boolean} True if the event is a "delete" keyboard event, otherwise false.
*/
export const isDeleteKeyboardEvent = ( { keyCode, ctrlKey } ) => (
keyCode === DELETE ||
keyCode === BACKSPACE ||
// On Apple devices, treat control + d & control + h as delete events
( isAppleOS && ctrlKey && [ D, H ].includes( keyCode ) )
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, I'm not sure if this should be generally applied regardless of OS.

We should either take out the isAppleOS check or apply it to isReverseDeleteKeyboardEvent as well. Open to suggestions!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went ahead and removed it for now so this is easier to test on other environments.

);

/**
* Determine if an event is a "reverse delete" keyboard event.
* This includes keypresses to `backspace`, `ctrl+h`, etc.
* @param {SyntheticEvent} event A synthetic keyboard event.
* @return {boolean} True if the event is a "reverse delete" keyboard event, otherwise false.
*/
export const isReverseDeleteKeyboardEvent = ( { keyCode, ctrlKey } ) => (
keyCode === BACKSPACE ||
( ctrlKey && keyCode === H )
);