Skip to content

Commit

Permalink
HTML block: Fix accessibility issues on back-end (#54408)
Browse files Browse the repository at this point in the history
* Accessibility fixes for HTML block.

* Remove focus handling code.

* Cleaner useInstanceId handling.

* Add tabindex -1 and title to iFrame.

* README and changelog.

* Revert odd changes.

* Reviewer feedback.

Co-authored-by: Marco Ciampini <marco.ciampo@gmail.com>

* Revert change.

---------

Co-authored-by: Marco Ciampini <marco.ciampo@gmail.com>
  • Loading branch information
alexstine and ciampo authored Sep 20, 2023
1 parent bf9e018 commit ceadbe4
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 8 deletions.
32 changes: 26 additions & 6 deletions packages/block-library/src/html/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@ import {
PlainText,
useBlockProps,
} from '@wordpress/block-editor';
import { ToolbarButton, Disabled, ToolbarGroup } from '@wordpress/components';
import {
ToolbarButton,
Disabled,
ToolbarGroup,
VisuallyHidden,
} from '@wordpress/components';
import { useInstanceId } from '@wordpress/compose';

/**
* Internal dependencies
Expand All @@ -19,6 +25,8 @@ export default function HTMLEdit( { attributes, setAttributes, isSelected } ) {
const [ isPreview, setIsPreview ] = useState();
const isDisabled = useContext( Disabled.Context );

const instanceId = useInstanceId( HTMLEdit, 'html-edit-desc' );

function switchToPreview() {
setIsPreview( true );
}
Expand All @@ -27,8 +35,13 @@ export default function HTMLEdit( { attributes, setAttributes, isSelected } ) {
setIsPreview( false );
}

const blockProps = useBlockProps( {
className: 'block-library-html__edit',
'aria-describedby': isPreview ? instanceId : undefined,
} );

return (
<div { ...useBlockProps( { className: 'block-library-html__edit' } ) }>
<div { ...blockProps }>
<BlockControls>
<ToolbarGroup>
<ToolbarButton
Expand All @@ -48,10 +61,17 @@ export default function HTMLEdit( { attributes, setAttributes, isSelected } ) {
</ToolbarGroup>
</BlockControls>
{ isPreview || isDisabled ? (
<Preview
content={ attributes.content }
isSelected={ isSelected }
/>
<>
<Preview
content={ attributes.content }
isSelected={ isSelected }
/>
<VisuallyHidden id={ instanceId }>
{ __(
'HTML preview is not yet fully accessible. Please switch screen reader to virtualized mode to navigate the below iFrame.'
) }
</VisuallyHidden>
</>
) : (
<PlainText
value={ attributes.content }
Expand Down
8 changes: 7 additions & 1 deletion packages/block-library/src/html/preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
} from '@wordpress/block-editor';
import { SandBox } from '@wordpress/components';
import { useSelect } from '@wordpress/data';
import { __ } from '@wordpress/i18n';

// Default styles used to unset some of the styles
// that might be inherited from the editor style.
Expand All @@ -32,7 +33,12 @@ export default function HTMLEditPreview( { content, isSelected } ) {

return (
<>
<SandBox html={ content } styles={ styles } />
<SandBox
html={ content }
styles={ styles }
title={ __( 'Custom HTML Preview' ) }
tabIndex={ -1 }
/>
{ /*
An overlay is added when the block is not selected in order to register click events.
Some browsers do not bubble up the clicks from the sandboxed iframe, which makes it
Expand Down
1 change: 1 addition & 0 deletions packages/components/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
- `DuotonePicker/ColorListPicker`: Adds appropriate labels to 'Duotone Filter' color pickers ([#54468](https://github.com/WordPress/gutenberg/pull/54468)).
- `SearchControl`: support new `40px` and `32px` sizes ([#54548](https://github.com/WordPress/gutenberg/pull/54548)).
- `FormTokenField`: Add `tokenizeOnBlur` prop to add any incompleteTokenValue as a new token when field loses focus ([#54445](https://github.com/WordPress/gutenberg/pull/54445)).
- `Sandbox`: Add `tabIndex` prop ([#54408](https://github.com/WordPress/gutenberg/pull/54408)).

### Bug Fix

Expand Down
8 changes: 7 additions & 1 deletion packages/components/src/sandbox/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,10 @@ The `<title>` of the iframe document.
The CSS class name to apply to the `<html>` and `<body>` elements of the iframe.

- Required: No
- Default: ""
- Default: ""

### `tabIndex`: `HTMLElement[ 'tabIndex' ]`

The `tabindex` the iframe should receive.

- Required: No
2 changes: 2 additions & 0 deletions packages/components/src/sandbox/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ function SandBox( {
styles = [],
scripts = [],
onFocus,
tabIndex,
}: SandBoxProps ) {
const ref = useRef< HTMLIFrameElement >();
const [ width, setWidth ] = useState( 0 );
Expand Down Expand Up @@ -282,6 +283,7 @@ function SandBox( {
<iframe
ref={ useMergeRefs( [ ref, useFocusableIframe() ] ) }
title={ title }
tabIndex={ tabIndex }
className="components-sandbox"
sandbox="allow-scripts allow-same-origin allow-presentation"
onFocus={ onFocus }
Expand Down
6 changes: 6 additions & 0 deletions packages/components/src/sandbox/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,10 @@ export type SandBoxProps = {
* The `onFocus` callback for the iframe.
*/
onFocus?: React.DOMAttributes< HTMLIFrameElement >[ 'onFocus' ];
/**
* The `tabindex` the iframe should receive.
*
* @default 0
*/
tabIndex?: HTMLElement[ 'tabIndex' ];
};

1 comment on commit ceadbe4

@github-actions
Copy link

Choose a reason for hiding this comment

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

Flaky tests detected in ceadbe4.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/6250277156
📝 Reported issues:

Please sign in to comment.