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

Writing Flow: Unset typing flag if Escape pressed #10906

Merged
merged 1 commit into from
Oct 26, 2018
Merged
Show file tree
Hide file tree
Changes from all 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
31 changes: 28 additions & 3 deletions packages/editor/src/components/observe-typing/index.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
/**
* External dependencies
*/
import { includes } from 'lodash';
import { over, includes } from 'lodash';

/**
* WordPress dependencies
*/
import { Component } from '@wordpress/element';
import { withSelect, withDispatch } from '@wordpress/data';
import { isTextField } from '@wordpress/dom';
import { UP, RIGHT, DOWN, LEFT, ENTER, BACKSPACE } from '@wordpress/keycodes';
import {
UP,
RIGHT,
DOWN,
LEFT,
ENTER,
BACKSPACE,
ESCAPE,
} from '@wordpress/keycodes';
import { withSafeTimeout, compose } from '@wordpress/compose';

/**
Expand Down Expand Up @@ -41,6 +49,12 @@ class ObserveTyping extends Component {
this.stopTypingOnMouseMove = this.stopTypingOnMouseMove.bind( this );
this.startTypingInTextField = this.startTypingInTextField.bind( this );
this.stopTypingOnNonTextField = this.stopTypingOnNonTextField.bind( this );
this.stopTypingOnEscapeKey = this.stopTypingOnEscapeKey.bind( this );

this.onKeyDown = over( [
this.startTypingInTextField,
this.stopTypingOnEscapeKey,
] );

this.lastMouseMove = null;
}
Expand Down Expand Up @@ -108,6 +122,17 @@ class ObserveTyping extends Component {
}
}

/**
* Unsets typing flag if user presses Escape while typing flag is active.
*
* @param {KeyboardEvent} event Keypress or keydown event to interpret.
*/
stopTypingOnEscapeKey( event ) {
if ( this.props.isTyping && event.keyCode === ESCAPE ) {
this.props.onStopTyping();
}
}

/**
* Handles a keypress or keydown event to infer intention to start typing.
*
Expand Down Expand Up @@ -165,7 +190,7 @@ class ObserveTyping extends Component {
<div
onFocus={ this.stopTypingOnNonTextField }
onKeyPress={ this.startTypingInTextField }
onKeyDown={ this.startTypingInTextField }
onKeyDown={ this.onKeyDown }
>
{ children }
</div>
Expand Down
63 changes: 63 additions & 0 deletions test/e2e/specs/navigable-toolbar.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/**
* External dependencies
*/
import { forEach } from 'lodash';

/**
* Internal dependencies
*/
import { newPost, pressWithModifier } from '../support/utils';

describe( 'block toolbar', () => {
forEach( {
unified: true,
contextual: false,
}, ( isUnifiedToolbar, label ) => {
beforeEach( async () => {
await newPost();

await page.evaluate( ( _isUnifiedToolbar ) => {
const { select, dispatch } = wp.data;
const isCurrentlyUnified = select( 'core/edit-post' ).isFeatureActive( 'fixedToolbar' );
if ( isCurrentlyUnified !== _isUnifiedToolbar ) {
dispatch( 'core/edit-post' ).toggleFeature( 'fixedToolbar' );
}
}, isUnifiedToolbar );
} );

const isInRichTextEditable = () => page.evaluate( () => (
document.activeElement.classList.contains( 'editor-rich-text__tinymce' )
) );

const isInBlockToolbar = () => page.evaluate( () => (
!! document.activeElement.closest( '.editor-block-toolbar' )
) );

describe( label, () => {
it( 'navigates in and out of toolbar by keyboard (Alt+F10, Escape)', async () => {
// Assumes new post focus starts in title. Create first new
// block by ArrowDown.
await page.keyboard.press( 'ArrowDown' );

// [TEMPORARY]: A new paragraph is not technically a block yet
// until starting to type within it.
await page.keyboard.type( 'Example' );

// [TEMPORARY]: With non-unified toolbar, the toolbar will not
// be visible since the user has entered a "typing" mode.
// Future iterations should ensure Alt+F10 works in a block
// to focus the toolbar regardless of whether it is presently
// visible.
await page.keyboard.press( 'Escape' );

// Upward
await pressWithModifier( 'Alt', 'F10' );
expect( await isInBlockToolbar() ).toBe( true );

// Downward
await page.keyboard.press( 'Escape' );
expect( await isInRichTextEditable() ).toBe( true );
} );
} );
} );
} );