diff --git a/packages/block-editor/src/components/block-tools/block-popover.js b/packages/block-editor/src/components/block-tools/block-popover.js index 3797f68edadffc..cfc0fa0b02251f 100644 --- a/packages/block-editor/src/components/block-tools/block-popover.js +++ b/packages/block-editor/src/components/block-tools/block-popover.js @@ -7,7 +7,7 @@ import classnames from 'classnames'; /** * WordPress dependencies */ -import { useState, useCallback, useRef, useEffect } from '@wordpress/element'; +import { useState, useRef, useEffect } from '@wordpress/element'; import { isUnmodifiedDefaultBlock } from '@wordpress/blocks'; import { Popover } from '@wordpress/components'; import { useDispatch, useSelect } from '@wordpress/data'; @@ -107,13 +107,11 @@ function BlockPopover( { useShortcut( 'core/block-editor/focus-toolbar', - useCallback( () => { + () => { setIsToolbarForced( true ); stopTyping( true ); - }, [] ), + }, { - bindGlobal: true, - eventName: 'keydown', isDisabled: ! canFocusHiddenToolbar, } ); diff --git a/packages/block-editor/src/components/iframe/index.js b/packages/block-editor/src/components/iframe/index.js index e5dbb6907094bc..e1de1591e6a0d5 100644 --- a/packages/block-editor/src/components/iframe/index.js +++ b/packages/block-editor/src/components/iframe/index.js @@ -134,7 +134,7 @@ function bubbleEvents( doc ) { } } - const eventTypes = [ 'keydown', 'keypress', 'dragover' ]; + const eventTypes = [ 'dragover' ]; for ( const name of eventTypes ) { doc.addEventListener( name, bubbleEvent ); diff --git a/packages/block-editor/src/components/navigable-toolbar/index.js b/packages/block-editor/src/components/navigable-toolbar/index.js index d010153fb26622..a988fa2c7575fb 100644 --- a/packages/block-editor/src/components/navigable-toolbar/index.js +++ b/packages/block-editor/src/components/navigable-toolbar/index.js @@ -100,10 +100,7 @@ function useToolbarFocus( }, [] ); // Focus on toolbar when pressing alt+F10 when the toolbar is visible - useShortcut( 'core/block-editor/focus-toolbar', focusToolbar, { - bindGlobal: true, - eventName: 'keydown', - } ); + useShortcut( 'core/block-editor/focus-toolbar', focusToolbar ); useEffect( () => { if ( initialFocusOnMount ) { diff --git a/packages/block-editor/src/components/writing-flow/use-tab-nav.js b/packages/block-editor/src/components/writing-flow/use-tab-nav.js index 3b3b3cf607d45b..7f61046809d71a 100644 --- a/packages/block-editor/src/components/writing-flow/use-tab-nav.js +++ b/packages/block-editor/src/components/writing-flow/use-tab-nav.js @@ -27,9 +27,11 @@ export default function useTabNav() { const focusCaptureBeforeRef = useRef(); const focusCaptureAfterRef = useRef(); const lastFocus = useRef(); - const { hasMultiSelection, getSelectedBlockClientId } = useSelect( - blockEditorStore - ); + const { + hasMultiSelection, + getSelectedBlockClientId, + getBlockCount, + } = useSelect( blockEditorStore ); const { setNavigationMode } = useDispatch( blockEditorStore ); const isNavigationMode = useSelect( ( select ) => select( blockEditorStore ).isNavigationMode(), @@ -143,6 +145,18 @@ export default function useTabNav() { function onFocusOut( event ) { 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 diff --git a/packages/customize-widgets/src/components/customize-widgets/index.js b/packages/customize-widgets/src/components/customize-widgets/index.js index d206108398283a..3306e438f80e94 100644 --- a/packages/customize-widgets/src/components/customize-widgets/index.js +++ b/packages/customize-widgets/src/components/customize-widgets/index.js @@ -3,6 +3,7 @@ */ import { useState, useEffect, useRef, createPortal } from '@wordpress/element'; import { SlotFillProvider, Popover } from '@wordpress/components'; +import { ShortcutProvider } from '@wordpress/keyboard-shortcuts'; /** * Internal dependencies @@ -67,16 +68,21 @@ export default function CustomizeWidgets( { ); return ( - - - - { activeSidebar } - { popover } - - - + + + + + { activeSidebar } + { popover } + + + + ); } diff --git a/packages/customize-widgets/src/components/keyboard-shortcut-help-modal/index.js b/packages/customize-widgets/src/components/keyboard-shortcut-help-modal/index.js index e600474a933cb8..77911be2610015 100644 --- a/packages/customize-widgets/src/components/keyboard-shortcut-help-modal/index.js +++ b/packages/customize-widgets/src/components/keyboard-shortcut-help-modal/index.js @@ -101,9 +101,7 @@ export default function KeyboardShortcutHelpModal( { }, } ); - useShortcut( 'core/customize-widgets/keyboard-shortcuts', toggleModal, { - bindGlobal: true, - } ); + useShortcut( 'core/customize-widgets/keyboard-shortcuts', toggleModal ); if ( ! isModalActive ) { return null; diff --git a/packages/customize-widgets/src/components/keyboard-shortcuts/index.js b/packages/customize-widgets/src/components/keyboard-shortcuts/index.js index fe7349fdae04a8..56888f1cfe3ae5 100644 --- a/packages/customize-widgets/src/components/keyboard-shortcuts/index.js +++ b/packages/customize-widgets/src/components/keyboard-shortcuts/index.js @@ -10,32 +10,20 @@ import { useDispatch } from '@wordpress/data'; import { __ } from '@wordpress/i18n'; function KeyboardShortcuts( { undo, redo, save } ) { - useShortcut( - 'core/customize-widgets/undo', - ( event ) => { - undo(); - event.preventDefault(); - }, - { bindGlobal: true } - ); + useShortcut( 'core/customize-widgets/undo', ( event ) => { + undo(); + event.preventDefault(); + } ); - useShortcut( - 'core/customize-widgets/redo', - ( event ) => { - redo(); - event.preventDefault(); - }, - { bindGlobal: true } - ); + useShortcut( 'core/customize-widgets/redo', ( event ) => { + redo(); + event.preventDefault(); + } ); - useShortcut( - 'core/customize-widgets/save', - ( event ) => { - event.preventDefault(); - save(); - }, - { bindGlobal: true } - ); + useShortcut( 'core/customize-widgets/save', ( event ) => { + event.preventDefault(); + save(); + } ); return null; } diff --git a/packages/customize-widgets/src/components/more-menu/index.js b/packages/customize-widgets/src/components/more-menu/index.js index 45c186f467c6e6..c87487ade1bce6 100644 --- a/packages/customize-widgets/src/components/more-menu/index.js +++ b/packages/customize-widgets/src/components/more-menu/index.js @@ -33,10 +33,7 @@ export default function MoreMenu() { useShortcut( 'core/customize-widgets/keyboard-shortcuts', - toggleKeyboardShortcutsModal, - { - bindGlobal: true, - } + toggleKeyboardShortcutsModal ); return ( diff --git a/packages/e2e-tests/specs/performance/site-editor.test.js b/packages/e2e-tests/specs/performance/site-editor.test.js index 70f8922f5edbb9..9bb0f846efff4b 100644 --- a/packages/e2e-tests/specs/performance/site-editor.test.js +++ b/packages/e2e-tests/specs/performance/site-editor.test.js @@ -114,24 +114,9 @@ describe( 'Site Editor Performance', () => { keyUpEvents, ] = getTypingEventDurations( traceResults ); - // Both keydown and keypress events are bubbled from the iframe to the - // 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++ ) { + for ( let j = 0; j < keyDownEvents.length; j++ ) { results.type.push( - _keyDownEvents[ j ] + _keyPressEvents[ j ] + keyUpEvents[ j ] + keyDownEvents[ j ] + keyPressEvents[ j ] + keyUpEvents[ j ] ); } diff --git a/packages/e2e-tests/specs/widgets/editing-widgets.test.js b/packages/e2e-tests/specs/widgets/editing-widgets.test.js index a67c1575e75a48..a883887b4c8615 100644 --- a/packages/e2e-tests/specs/widgets/editing-widgets.test.js +++ b/packages/e2e-tests/specs/widgets/editing-widgets.test.js @@ -822,6 +822,8 @@ describe( 'Widgets screen', () => { // Delete the last block and save again. await pressKeyWithModifier( 'access', 'z' ); await saveWidgets(); + // To do: clicking on the Snackbar causes focus loss. + await page.focus( '.block-editor-writing-flow' ); // Undo block deletion and save again await pressKeyWithModifier( 'primary', 'z' ); diff --git a/packages/edit-navigation/src/components/layout/index.js b/packages/edit-navigation/src/components/layout/index.js index 92dd19040ea0c0..6b03909cf2be3b 100644 --- a/packages/edit-navigation/src/components/layout/index.js +++ b/packages/edit-navigation/src/components/layout/index.js @@ -16,6 +16,7 @@ import { store as interfaceStore, } from '@wordpress/interface'; import { __ } from '@wordpress/i18n'; +import { ShortcutProvider } from '@wordpress/keyboard-shortcuts'; /** * Internal dependencies @@ -96,96 +97,100 @@ export default function Layout( { blockEditorSettings } ) { return ( -