Skip to content

Commit

Permalink
RichText: try alternative list shortcuts (to tab) (#14343)
Browse files Browse the repository at this point in the history
* RichText: try alternative list shortcuts

* Try tooltips

* Change tooltips to use text

* Add inline comments

* Add e2e test

* Rebase
  • Loading branch information
ellatrix authored and youknowriad committed Mar 20, 2019
1 parent 68c04f3 commit 3d38a16
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 18 deletions.
79 changes: 62 additions & 17 deletions packages/block-editor/src/components/rich-text/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,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 } from '@wordpress/keycodes';
import { BACKSPACE, DELETE, ENTER, LEFT, RIGHT, SPACE } 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 All @@ -37,13 +37,11 @@ import {
insertLineSeparator,
isEmptyLine,
unstableToDom,
getSelectionStart,
getSelectionEnd,
remove,
removeFormat,
isCollapsed,
LINE_SEPARATOR,
charAt,
indentListItems,
} from '@wordpress/rich-text';
import { decodeEntities } from '@wordpress/html-entities';
import { withFilters, IsolatedEventContainer } from '@wordpress/components';
Expand Down Expand Up @@ -599,10 +597,26 @@ export class RichText extends Component {
this.handleHorizontalNavigation( event );
}

// Use the space key in list items (at the start of an item) to indent
// the list item.
if ( keyCode === SPACE && this.multilineTag === 'li' ) {
const value = this.createRecord();

if ( isCollapsed( value ) ) {
const { text, start } = value;
const characterBefore = text[ start - 1 ];

// The caret must be at the start of a line.
if ( ! characterBefore || characterBefore === LINE_SEPARATOR ) {
this.onChange( indentListItems( value, { type: this.props.tagName } ) );
event.preventDefault();
}
}
}

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

// Always handle full content deletion ourselves.
if ( start === 0 && end !== 0 && end === value.text.length ) {
Expand All @@ -615,22 +629,53 @@ export class RichText extends Component {
let newValue;

if ( keyCode === BACKSPACE ) {
if ( charAt( value, start - 1 ) === LINE_SEPARATOR ) {
const index = start - 1;

if ( text[ index ] === LINE_SEPARATOR ) {
const collapsed = isCollapsed( value );

// If the line separator that is about te be removed
// contains wrappers, remove the wrappers first.
if ( collapsed && replacements[ index ] && replacements[ index ].length ) {
const newReplacements = replacements.slice();

newReplacements[ index ] = replacements[ index ].slice( 0, -1 );
newValue = {
...value,
replacements: newReplacements,
};
} else {
newValue = remove(
value,
// Only remove the line if the selection is
// collapsed, otherwise remove the selection.
collapsed ? start - 1 : start,
end
);
}
}
} else if ( text[ end ] === LINE_SEPARATOR ) {
const collapsed = isCollapsed( value );

// If the line separator that is about te be removed
// contains wrappers, remove the wrappers first.
if ( collapsed && replacements[ end ] && replacements[ end ].length ) {
const newReplacements = replacements.slice();

newReplacements[ end ] = replacements[ end ].slice( 0, -1 );
newValue = {
...value,
replacements: newReplacements,
};
} else {
newValue = remove(
value,
start,
// Only remove the line if the selection is
// collapsed.
isCollapsed( value ) ? start - 1 : start,
end
// collapsed, otherwise remove the selection.
collapsed ? end + 1 : end,
);
}
} else if ( charAt( value, end ) === LINE_SEPARATOR ) {
newValue = remove(
value,
start,
// Only remove the line if the selection is collapsed.
isCollapsed( value ) ? end + 1 : end,
);
}

if ( newValue ) {
Expand Down
4 changes: 3 additions & 1 deletion packages/block-editor/src/components/rich-text/list-edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*/

import { Toolbar } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { __, _x } from '@wordpress/i18n';
import { Fragment } from '@wordpress/element';
import {
indentListItems,
Expand Down Expand Up @@ -149,13 +149,15 @@ export const ListEdit = ( {
{
icon: 'editor-outdent',
title: __( 'Outdent list item' ),
shortcut: _x( 'Backspace', 'keyboard key' ),
onClick: () => {
onChange( outdentListItems( value ) );
},
},
{
icon: 'editor-indent',
title: __( 'Indent list item' ),
shortcut: _x( 'Space', 'keyboard key' ),
onClick: () => {
onChange( indentListItems( value, { type: tagName } ) );
},
Expand Down
38 changes: 38 additions & 0 deletions packages/e2e-tests/specs/blocks/__snapshots__/list.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,44 @@ exports[`List should change the indented list type 1`] = `
<!-- /wp:list -->"
`;
exports[`List should create and remove indented list with keyboard only 1`] = `
"<!-- wp:list -->
<ul><li>1<ul><li>a<ul><li>i</li></ul></li></ul></li></ul>
<!-- /wp:list -->"
`;
exports[`List should create and remove indented list with keyboard only 2`] = `
"<!-- wp:list -->
<ul><li>1<ul><li>a</li><li></li></ul></li></ul>
<!-- /wp:list -->"
`;
exports[`List should create and remove indented list with keyboard only 3`] = `
"<!-- wp:list -->
<ul><li>1<ul><li>a</li></ul></li><li></li></ul>
<!-- /wp:list -->"
`;
exports[`List should create and remove indented list with keyboard only 4`] = `
"<!-- wp:list -->
<ul><li>1<ul><li>a</li></ul></li></ul>
<!-- /wp:list -->"
`;
exports[`List should create and remove indented list with keyboard only 5`] = `
"<!-- wp:list -->
<ul><li>1</li><li></li></ul>
<!-- /wp:list -->"
`;
exports[`List should create and remove indented list with keyboard only 6`] = `
"<!-- wp:list -->
<ul><li>1</li></ul>
<!-- /wp:list -->"
`;
exports[`List should create and remove indented list with keyboard only 7`] = `""`;
exports[`List should create paragraph on split at end and merge back with content 1`] = `
"<!-- wp:list -->
<ul><li>one</li></ul>
Expand Down
42 changes: 42 additions & 0 deletions packages/e2e-tests/specs/blocks/list.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -304,4 +304,46 @@ describe( 'List', () => {

expect( await getEditedPostContent() ).toMatchSnapshot();
} );

it( 'should create and remove indented list with keyboard only', async () => {
await clickBlockAppender();

await page.keyboard.type( '* 1' ); // Should be at level 0.
await page.keyboard.press( 'Enter' );
await page.keyboard.type( ' a' ); // Should be at level 1.
await page.keyboard.press( 'Enter' );
await page.keyboard.type( ' i' ); // Should be at level 2.

expect( await getEditedPostContent() ).toMatchSnapshot();

await page.keyboard.press( 'Backspace' );
await page.keyboard.press( 'Backspace' ); // Should be at level 1.

expect( await getEditedPostContent() ).toMatchSnapshot();

await page.keyboard.press( 'Backspace' ); // Should be at level 0.

expect( await getEditedPostContent() ).toMatchSnapshot();

await page.keyboard.press( 'Backspace' ); // Should be at level 1.

expect( await getEditedPostContent() ).toMatchSnapshot();

await page.keyboard.press( 'Backspace' );
await page.keyboard.press( 'Backspace' ); // Should be at level 0.

expect( await getEditedPostContent() ).toMatchSnapshot();

await page.keyboard.press( 'Backspace' ); // Should be at level 0.

expect( await getEditedPostContent() ).toMatchSnapshot();

await page.keyboard.press( 'Backspace' );
await page.keyboard.press( 'Backspace' ); // Should remove list.

expect( await getEditedPostContent() ).toMatchSnapshot();

// That's 9 key presses to create the list, and 9 key presses to remove
// the list. ;)
} );
} );

0 comments on commit 3d38a16

Please sign in to comment.