Skip to content

Commit

Permalink
Rich Text: Fix backspace to delete empty paragraph
Browse files Browse the repository at this point in the history
  • Loading branch information
aduth committed Aug 3, 2018
1 parent 289f484 commit d2ba587
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 3 deletions.
14 changes: 11 additions & 3 deletions packages/editor/src/components/rich-text/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -452,12 +452,20 @@ export class RichText extends Component {
return;
}

let isHandled = false;

if ( onMerge ) {
onMerge( ! isReverse );
} else if ( onRemove && this.isEmpty() ) {
isHandled = true;
}

if ( onRemove && this.isEmpty() ) {
onRemove( ! isReverse );
} else {
// Only prevent default behaviors if handled.
isHandled = true;
}

// Only prevent default behaviors if handled.
if ( ! isHandled ) {
return;
}

Expand Down
2 changes: 2 additions & 0 deletions test/e2e/specs/__snapshots__/splitting-merging.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ exports[`splitting and merging blocks Should merge into inline boundary position
<!-- /wp:paragraph -->"
`;

exports[`splitting and merging blocks Should remove empty paragraph block on backspace 1`] = `""`;

exports[`splitting and merging blocks Should split and merge paragraph blocks using Enter and Backspace 1`] = `
"<!-- wp:paragraph -->
<p>First</p>
Expand Down
13 changes: 13 additions & 0 deletions test/e2e/specs/splitting-merging.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ describe( 'splitting and merging blocks', () => {
it( 'Should delete wholly-selected block contents', async () => {
// Regression Test: When all of a paragraph is selected, pressing
// backspace should delete the contents, not merge to previous.
//
// See: https://github.com/WordPress/gutenberg/issues/8268
await insertBlock( 'Paragraph' );
await page.keyboard.type( 'Foo' );
await insertBlock( 'Paragraph' );
Expand All @@ -89,4 +91,15 @@ describe( 'splitting and merging blocks', () => {

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

it( 'Should remove empty paragraph block on backspace', async () => {
// Regression Test: In a sole empty paragraph, pressing backspace
// should remove the block.
//
// See: https://github.com/WordPress/gutenberg/pull/8306
await insertBlock( 'Paragraph' );
await page.keyboard.press( 'Backspace' );

expect( await getEditedPostContent() ).toMatchSnapshot();
} );
} );
29 changes: 29 additions & 0 deletions test/e2e/support/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,34 @@ async function login() {
] );
}

/**
* Returns a promise which resolves once it's determined that the active DOM
* element is not within a RichText field, or the RichText field's TinyMCE has
* completed initialization. This is an unfortunate workaround to address an
* issue where TinyMCE takes its time to become ready for user input.
*
* TODO: This is a code smell, indicating that "too fast" resulting in breakage
* could be equally problematic for a fast human. It should be explored whether
* all event bindings we assign to TinyMCE to handle could be handled through
* the DOM directly instead.
*
* @return {Promise} Promise resolving once RichText is initialized, or is
* determined to not be a container of the active element.
*/
async function waitForRichTextInitialization() {
const isInRichText = await page.evaluate( () => {
return !! document.activeElement.closest( '.editor-rich-text__tinymce' );
} );

if ( ! isInRichText ) {
return;
}

return page.waitForFunction( () => {
return !! document.activeElement.closest( '.mce-content-body' );
} );
}

export async function visitAdmin( adminPath, query ) {
await goToWPPath( join( 'wp-admin', adminPath ), query );

Expand Down Expand Up @@ -201,6 +229,7 @@ export async function searchForBlock( searchTerm ) {
export async function insertBlock( searchTerm ) {
await searchForBlock( searchTerm );
await page.click( `button[aria-label="${ searchTerm }"]` );
await waitForRichTextInitialization();
}

/**
Expand Down

0 comments on commit d2ba587

Please sign in to comment.