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

Global shortcuts: use React events (portal bubbles & contextual) #34539

Merged
merged 13 commits into from
Sep 13, 2021
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import classnames from 'classnames';
/** /**
* WordPress dependencies * WordPress dependencies
*/ */
import { useState, useCallback, useRef, useEffect } from '@wordpress/element'; import { useState, useRef, useEffect } from '@wordpress/element';
import { isUnmodifiedDefaultBlock } from '@wordpress/blocks'; import { isUnmodifiedDefaultBlock } from '@wordpress/blocks';
import { Popover } from '@wordpress/components'; import { Popover } from '@wordpress/components';
import { useDispatch, useSelect } from '@wordpress/data'; import { useDispatch, useSelect } from '@wordpress/data';
Expand Down Expand Up @@ -107,13 +107,11 @@ function BlockPopover( {


useShortcut( useShortcut(
'core/block-editor/focus-toolbar', 'core/block-editor/focus-toolbar',
useCallback( () => { () => {
setIsToolbarForced( true ); setIsToolbarForced( true );
stopTyping( true ); stopTyping( true );
}, [] ), },
{ {
bindGlobal: true,
eventName: 'keydown',
isDisabled: ! canFocusHiddenToolbar, isDisabled: ! canFocusHiddenToolbar,
} }
); );
Expand Down
2 changes: 1 addition & 1 deletion packages/block-editor/src/components/iframe/index.js
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ function bubbleEvents( doc ) {
} }
} }


const eventTypes = [ 'keydown', 'keypress', 'dragover' ]; const eventTypes = [ 'dragover' ];


for ( const name of eventTypes ) { for ( const name of eventTypes ) {
doc.addEventListener( name, bubbleEvent ); doc.addEventListener( name, bubbleEvent );
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -100,10 +100,7 @@ function useToolbarFocus(
}, [] ); }, [] );


// Focus on toolbar when pressing alt+F10 when the toolbar is visible // Focus on toolbar when pressing alt+F10 when the toolbar is visible
useShortcut( 'core/block-editor/focus-toolbar', focusToolbar, { useShortcut( 'core/block-editor/focus-toolbar', focusToolbar );
bindGlobal: true,
eventName: 'keydown',
} );


useEffect( () => { useEffect( () => {
if ( initialFocusOnMount ) { if ( initialFocusOnMount ) {
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ export default function useTabNav() {
const focusCaptureBeforeRef = useRef(); const focusCaptureBeforeRef = useRef();
const focusCaptureAfterRef = useRef(); const focusCaptureAfterRef = useRef();
const lastFocus = useRef(); const lastFocus = useRef();
const { hasMultiSelection, getSelectedBlockClientId } = useSelect( const {
blockEditorStore hasMultiSelection,
); getSelectedBlockClientId,
getBlockCount,
} = useSelect( blockEditorStore );
const { setNavigationMode } = useDispatch( blockEditorStore ); const { setNavigationMode } = useDispatch( blockEditorStore );
const isNavigationMode = useSelect( const isNavigationMode = useSelect(
( select ) => select( blockEditorStore ).isNavigationMode(), ( select ) => select( blockEditorStore ).isNavigationMode(),
Expand Down Expand Up @@ -143,6 +145,18 @@ export default function useTabNav() {


function onFocusOut( event ) { function onFocusOut( event ) {
lastFocus.current = event.target; lastFocus.current = event.target;

const { ownerDocument } = node;

// If focus disappears due to there being no blocks, move focus to
// the writing flow wrapper.
if (
! event.relatedTarget &&
ownerDocument.activeElement === ownerDocument.body &&
getBlockCount() === 0
) {
node.focus();
}
} }


// When tabbing back to an element in block list, this event handler prevents scrolling if the // When tabbing back to an element in block list, this event handler prevents scrolling if the
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*/ */
import { useState, useEffect, useRef, createPortal } from '@wordpress/element'; import { useState, useEffect, useRef, createPortal } from '@wordpress/element';
import { SlotFillProvider, Popover } from '@wordpress/components'; import { SlotFillProvider, Popover } from '@wordpress/components';
import { ShortcutProvider } from '@wordpress/keyboard-shortcuts';


/** /**
* Internal dependencies * Internal dependencies
Expand Down Expand Up @@ -67,16 +68,21 @@ export default function CustomizeWidgets( {
); );


return ( return (
<ShortcutProvider>
<SlotFillProvider> <SlotFillProvider>
<SidebarControls <SidebarControls
sidebarControls={ sidebarControls } sidebarControls={ sidebarControls }
activeSidebarControl={ activeSidebarControl } activeSidebarControl={ activeSidebarControl }
> >
<FocusControl api={ api } sidebarControls={ sidebarControls }> <FocusControl
api={ api }
sidebarControls={ sidebarControls }
>
{ activeSidebar } { activeSidebar }
{ popover } { popover }
</FocusControl> </FocusControl>
</SidebarControls> </SidebarControls>
</SlotFillProvider> </SlotFillProvider>
</ShortcutProvider>
); );
} }
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -101,9 +101,7 @@ export default function KeyboardShortcutHelpModal( {
}, },
} ); } );


useShortcut( 'core/customize-widgets/keyboard-shortcuts', toggleModal, { useShortcut( 'core/customize-widgets/keyboard-shortcuts', toggleModal );
bindGlobal: true,
} );


if ( ! isModalActive ) { if ( ! isModalActive ) {
return null; return null;
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -10,32 +10,20 @@ import { useDispatch } from '@wordpress/data';
import { __ } from '@wordpress/i18n'; import { __ } from '@wordpress/i18n';


function KeyboardShortcuts( { undo, redo, save } ) { function KeyboardShortcuts( { undo, redo, save } ) {
useShortcut( useShortcut( 'core/customize-widgets/undo', ( event ) => {
'core/customize-widgets/undo',
( event ) => {
undo(); undo();
event.preventDefault(); event.preventDefault();
}, } );
{ bindGlobal: true }
);


useShortcut( useShortcut( 'core/customize-widgets/redo', ( event ) => {
'core/customize-widgets/redo',
( event ) => {
redo(); redo();
event.preventDefault(); event.preventDefault();
}, } );
{ bindGlobal: true }
);


useShortcut( useShortcut( 'core/customize-widgets/save', ( event ) => {
'core/customize-widgets/save',
( event ) => {
event.preventDefault(); event.preventDefault();
save(); save();
}, } );
{ bindGlobal: true }
);


return null; return null;
} }
Expand Down
5 changes: 1 addition & 4 deletions packages/customize-widgets/src/components/more-menu/index.js
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -33,10 +33,7 @@ export default function MoreMenu() {


useShortcut( useShortcut(
'core/customize-widgets/keyboard-shortcuts', 'core/customize-widgets/keyboard-shortcuts',
toggleKeyboardShortcutsModal, toggleKeyboardShortcutsModal
{
bindGlobal: true,
}
); );


return ( return (
Expand Down
19 changes: 2 additions & 17 deletions packages/e2e-tests/specs/performance/site-editor.test.js
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -114,24 +114,9 @@ describe( 'Site Editor Performance', () => {
keyUpEvents, keyUpEvents,
] = getTypingEventDurations( traceResults ); ] = getTypingEventDurations( traceResults );


// Both keydown and keypress events are bubbled from the iframe to the for ( let j = 0; j < keyDownEvents.length; j++ ) {
// main frame, which must be ignored. These will be the odd values in
// the array.
const _keyDownEvents = keyDownEvents.filter(
( v, ii ) => ii % 2 === 0
);
const _keyPressEvents = keyPressEvents.filter(
( v, ii ) => ii % 2 === 0
);

expect(
_keyDownEvents.length === _keyPressEvents.length &&
_keyPressEvents.length === keyUpEvents.length
).toBe( true );

for ( let j = 0; j < _keyDownEvents.length; j++ ) {
results.type.push( results.type.push(
_keyDownEvents[ j ] + _keyPressEvents[ j ] + keyUpEvents[ j ] keyDownEvents[ j ] + keyPressEvents[ j ] + keyUpEvents[ j ]
); );
} }


Expand Down
2 changes: 2 additions & 0 deletions packages/e2e-tests/specs/widgets/editing-widgets.test.js
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -822,6 +822,8 @@ describe( 'Widgets screen', () => {
// Delete the last block and save again. // Delete the last block and save again.
await pressKeyWithModifier( 'access', 'z' ); await pressKeyWithModifier( 'access', 'z' );
await saveWidgets(); await saveWidgets();
// To do: clicking on the Snackbar causes focus loss.
await page.focus( '.block-editor-writing-flow' );


// Undo block deletion and save again // Undo block deletion and save again
await pressKeyWithModifier( 'primary', 'z' ); await pressKeyWithModifier( 'primary', 'z' );
Expand Down
7 changes: 6 additions & 1 deletion packages/edit-navigation/src/components/layout/index.js
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
store as interfaceStore, store as interfaceStore,
} from '@wordpress/interface'; } from '@wordpress/interface';
import { __ } from '@wordpress/i18n'; import { __ } from '@wordpress/i18n';
import { ShortcutProvider } from '@wordpress/keyboard-shortcuts';


/** /**
* Internal dependencies * Internal dependencies
Expand Down Expand Up @@ -96,6 +97,7 @@ export default function Layout( { blockEditorSettings } ) {


return ( return (
<ErrorBoundary> <ErrorBoundary>
<ShortcutProvider>
<div <div
hidden={ ! isMenuBeingDeleted } hidden={ ! isMenuBeingDeleted }
className={ 'edit-navigation-layout__overlay' } className={ 'edit-navigation-layout__overlay' }
Expand Down Expand Up @@ -139,7 +141,9 @@ export default function Layout( { blockEditorSettings } ) {
} }
content={ content={
<> <>
{ ! hasFinishedInitialLoad && <Spinner /> } { ! hasFinishedInitialLoad && (
<Spinner />
) }


{ ! isMenuSelected && { ! isMenuSelected &&
hasFinishedInitialLoad && ( hasFinishedInitialLoad && (
Expand Down Expand Up @@ -186,6 +190,7 @@ export default function Layout( { blockEditorSettings } ) {
</BlockEditorProvider> </BlockEditorProvider>
<Popover.Slot /> <Popover.Slot />
</SlotFillProvider> </SlotFillProvider>
</ShortcutProvider>
</ErrorBoundary> </ErrorBoundary>
); );
} }
28 changes: 7 additions & 21 deletions packages/edit-navigation/src/components/layout/shortcuts.js
Original file line number Original file line Diff line number Diff line change
@@ -1,7 +1,7 @@
/** /**
* WordPress dependencies * WordPress dependencies
*/ */
import { useEffect, useCallback } from '@wordpress/element'; import { useEffect } from '@wordpress/element';
import { useDispatch } from '@wordpress/data'; import { useDispatch } from '@wordpress/data';
import { import {
useShortcut, useShortcut,
Expand All @@ -11,35 +11,21 @@ import { __ } from '@wordpress/i18n';
import { store as coreStore } from '@wordpress/core-data'; import { store as coreStore } from '@wordpress/core-data';


function NavigationEditorShortcuts( { saveBlocks } ) { function NavigationEditorShortcuts( { saveBlocks } ) {
useShortcut( useShortcut( 'core/edit-navigation/save-menu', ( event ) => {
'core/edit-navigation/save-menu',
useCallback( ( event ) => {
event.preventDefault(); event.preventDefault();
saveBlocks(); saveBlocks();
} ), } );
{
bindGlobal: true,
}
);


const { redo, undo } = useDispatch( coreStore ); const { redo, undo } = useDispatch( coreStore );
useShortcut( useShortcut( 'core/edit-navigation/undo', ( event ) => {
'core/edit-navigation/undo',
( event ) => {
undo(); undo();
event.preventDefault(); event.preventDefault();
}, } );
{ bindGlobal: true }
);


useShortcut( useShortcut( 'core/edit-navigation/redo', ( event ) => {
'core/edit-navigation/redo',
( event ) => {
redo(); redo();
event.preventDefault(); event.preventDefault();
}, } );
{ bindGlobal: true }
);


return null; return null;
} }
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -91,9 +91,7 @@ const ShortcutCategorySection = ( {
}; };


export function KeyboardShortcutHelpModal( { isModalActive, toggleModal } ) { export function KeyboardShortcutHelpModal( { isModalActive, toggleModal } ) {
useShortcut( 'core/edit-post/keyboard-shortcuts', toggleModal, { useShortcut( 'core/edit-post/keyboard-shortcuts', toggleModal );
bindGlobal: true,
} );


if ( ! isModalActive ) { if ( ! isModalActive ) {
return null; return null;
Expand Down
25 changes: 6 additions & 19 deletions packages/edit-post/src/components/keyboard-shortcuts/index.js
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -131,24 +131,15 @@ function KeyboardShortcuts() {
); );
}, },
{ {
bindGlobal: true,
isDisabled: isModeToggleDisabled, isDisabled: isModeToggleDisabled,
} }
); );


useShortcut( useShortcut( 'core/edit-post/toggle-fullscreen', () => {
'core/edit-post/toggle-fullscreen',
() => {
toggleFeature( 'fullscreenMode' ); toggleFeature( 'fullscreenMode' );
}, } );
{
bindGlobal: true,
}
);


useShortcut( useShortcut( 'core/edit-post/toggle-sidebar', ( event ) => {
'core/edit-post/toggle-sidebar',
( event ) => {
// This shortcut has no known clashes, but use preventDefault to prevent any // This shortcut has no known clashes, but use preventDefault to prevent any
// obscure shortcuts from triggering. // obscure shortcuts from triggering.
event.preventDefault(); event.preventDefault();
Expand All @@ -161,14 +152,10 @@ function KeyboardShortcuts() {
: 'edit-post/document'; : 'edit-post/document';
openGeneralSidebar( sidebarToOpen ); openGeneralSidebar( sidebarToOpen );
} }
}, } );
{ bindGlobal: true }
);


useShortcut( useShortcut( 'core/edit-post/toggle-list-view', () =>
'core/edit-post/toggle-list-view', setIsListViewOpened( ! isListViewOpened() )
() => setIsListViewOpened( ! isListViewOpened() ),
{ bindGlobal: true }
); );


return null; return null;
Expand Down
3 changes: 3 additions & 0 deletions packages/edit-post/src/editor.js
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
import { StrictMode, useMemo } from '@wordpress/element'; import { StrictMode, useMemo } from '@wordpress/element';
import { KeyboardShortcuts, SlotFillProvider } from '@wordpress/components'; import { KeyboardShortcuts, SlotFillProvider } from '@wordpress/components';
import { store as coreStore } from '@wordpress/core-data'; import { store as coreStore } from '@wordpress/core-data';
import { ShortcutProvider } from '@wordpress/keyboard-shortcuts';


/** /**
* Internal dependencies * Internal dependencies
Expand Down Expand Up @@ -167,6 +168,7 @@ function Editor( {


return ( return (
<StrictMode> <StrictMode>
<ShortcutProvider>
<EditPostSettings.Provider value={ settings }> <EditPostSettings.Provider value={ settings }>
<SlotFillProvider> <SlotFillProvider>
<EditorProvider <EditorProvider
Expand All @@ -190,6 +192,7 @@ function Editor( {
</EditorProvider> </EditorProvider>
</SlotFillProvider> </SlotFillProvider>
</EditPostSettings.Provider> </EditPostSettings.Provider>
</ShortcutProvider>
</StrictMode> </StrictMode>
); );
} }
Expand Down
Loading