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

Focus Editor Region from Template Footer Click #62595

Merged
merged 3 commits into from
Jun 26, 2024
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
17 changes: 16 additions & 1 deletion packages/block-editor/src/components/block-breadcrumb/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { chevronRightSmall, Icon } from '@wordpress/icons';
import BlockTitle from '../block-title';
import { store as blockEditorStore } from '../../store';
import { unlock } from '../../lock-unlock';
import { __unstableUseBlockRef as useBlockRef } from '../block-list/use-block-props/use-block-refs';
import getEditorRegion from '../../utils/get-editor-region';

/**
* Block breadcrumb component, displaying the hierarchy of the current block selection as a breadcrumb.
Expand All @@ -37,6 +39,10 @@ function BlockBreadcrumb( { rootLabelText } ) {
}, [] );
const rootLabel = rootLabelText || __( 'Document' );

// We don't care about this specific ref, but this is a way
// to get a ref within the editor canvas so we can focus it later.
const blockRef = useBlockRef( clientId );

/*
* Disable reason: The `list` ARIA role is redundant but
* Safari+VoiceOver won't announce the list otherwise.
Expand All @@ -60,7 +66,16 @@ function BlockBreadcrumb( { rootLabelText } ) {
<Button
className="block-editor-block-breadcrumb__button"
variant="tertiary"
onClick={ clearSelectedBlock }
onClick={ () => {
// Find the block editor wrapper for the selected block
const blockEditor = blockRef.current?.closest(
'.editor-styles-wrapper'
);

clearSelectedBlock();

getEditorRegion( blockEditor ).focus();
} }
>
{ rootLabel }
</Button>
Expand Down
29 changes: 2 additions & 27 deletions packages/block-editor/src/components/block-tools/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import usePopoverScroll from '../block-popover/use-popover-scroll';
import ZoomOutModeInserters from './zoom-out-mode-inserters';
import { useShowBlockTools } from './use-show-block-tools';
import { unlock } from '../../lock-unlock';
import getEditorRegion from '../../utils/get-editor-region';

function selector( select ) {
const {
Expand Down Expand Up @@ -161,33 +162,7 @@ export default function BlockTools( {
) {
event.preventDefault();
clearSelectedBlock();
// If there are multiple editors, we need to find the iframe that contains our contentRef to make sure
// we're focusing the region that contains this editor.
const editorCanvas =
Array.from(
document
.querySelectorAll( 'iframe[name="editor-canvas"]' )
.values()
).find( ( iframe ) => {
// Find the iframe that contains our contentRef
const iframeDocument =
iframe.contentDocument ||
iframe.contentWindow.document;

return (
iframeDocument ===
__unstableContentRef.current.ownerDocument
);
} ) ?? __unstableContentRef.current;

// The region is provivided by the editor, not the block-editor.
// We should send focus to the region if one is available to reuse the
// same interface for navigating landmarks. If no region is available,
// use the canvas instead.
const focusableWrapper =
editorCanvas?.closest( '[role="region"]' ) ?? editorCanvas;

focusableWrapper.focus();
getEditorRegion( __unstableContentRef.current ).focus();
}
} else if ( isMatch( 'core/block-editor/collapse-list-view', event ) ) {
// If focus is currently within a text field, such as a rich text block or other editable field,
Expand Down
31 changes: 31 additions & 0 deletions packages/block-editor/src/utils/get-editor-region.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* Gets the editor region for a given editor canvas element or
* returns the passed element if no region is found
*
* @param { Object } editor The editor canvas element.
* @return { Object } The editor region or given editor element
*/
export default function getEditorRegion( editor ) {
if ( ! editor ) {
return null;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that this could be returning null, but you're calling focus() unconditionally.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! Fixed here: #62980

}

// If there are multiple editors, we need to find the iframe that contains our contentRef to make sure
// we're focusing the region that contains this editor.
const editorCanvas =
Array.from(
document.querySelectorAll( 'iframe[name="editor-canvas"]' ).values()
).find( ( iframe ) => {
// Find the iframe that contains our contentRef
const iframeDocument =
iframe.contentDocument || iframe.contentWindow.document;

return iframeDocument === editor.ownerDocument;
} ) ?? editor;

// The region is provivided by the editor, not the block-editor.
// We should send focus to the region if one is available to reuse the
// same interface for navigating landmarks. If no region is available,
// use the canvas instead.
return editorCanvas?.closest( '[role="region"]' ) ?? editorCanvas;
}
Loading