diff options
author | Eugen Rochko <eugen@zeonfederated.com> | 2018-08-23 20:56:57 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-08-23 20:56:57 +0200 |
commit | 248df68c36a2f1ffd9c214afe7d1b0c62b4a5f27 (patch) | |
tree | 8b4cbde77f19dbcc6927682df83373aebf707b0e /app/javascript | |
parent | 43b8df3228291a879170be4da84db63eeacdf144 (diff) |
Give focused status a sensible aria-label for screen readers (#8387)
* Give focused status a sensible aria-label for screen readers Fix #8192 * Use content warning in aria-label unless expanded
Diffstat (limited to 'app/javascript')
-rw-r--r-- | app/javascript/mastodon/components/status.js | 28 | ||||
-rw-r--r-- | app/javascript/mastodon/features/status/index.js | 3 |
2 files changed, 26 insertions, 5 deletions
diff --git a/app/javascript/mastodon/components/status.js b/app/javascript/mastodon/components/status.js index e653906f1..9a3fd3576 100644 --- a/app/javascript/mastodon/components/status.js +++ b/app/javascript/mastodon/components/status.js @@ -8,7 +8,7 @@ import DisplayName from './display_name'; import StatusContent from './status_content'; import StatusActionBar from './status_action_bar'; import AttachmentList from './attachment_list'; -import { FormattedMessage } from 'react-intl'; +import { injectIntl, FormattedMessage } from 'react-intl'; import ImmutablePureComponent from 'react-immutable-pure-component'; import { MediaGallery, Video } from '../features/ui/util/async-components'; import { HotKeys } from 'react-hotkeys'; @@ -18,6 +18,24 @@ import classNames from 'classnames'; // to use the progress bar to show download progress import Bundle from '../features/ui/components/bundle'; +export const textForScreenReader = (intl, status, rebloggedByText = false, expanded = false) => { + const displayName = status.getIn(['account', 'display_name']); + + const values = [ + displayName.length === 0 ? status.getIn(['account', 'acct']).split('@')[0] : displayName, + status.get('spoiler_text') && !expanded ? status.get('spoiler_text') : status.get('search_index').slice(status.get('spoiler_text').length), + intl.formatDate(status.get('created_at'), { hour: '2-digit', minute: '2-digit', month: 'short', day: 'numeric' }), + status.getIn(['account', 'acct']), + ]; + + if (rebloggedByText) { + values.push(rebloggedByText); + } + + return values.join(', '); +}; + +@injectIntl export default class Status extends ImmutablePureComponent { static contextTypes = { @@ -138,9 +156,9 @@ export default class Status extends ImmutablePureComponent { render () { let media = null; - let statusAvatar, prepend; + let statusAvatar, prepend, rebloggedByText; - const { hidden, featured } = this.props; + const { intl, hidden, featured } = this.props; let { status, account, ...other } = this.props; @@ -189,6 +207,8 @@ export default class Status extends ImmutablePureComponent { </div> ); + rebloggedByText = intl.formatMessage({ id: 'status.reblogged_by', defaultMessage: '{name} boosted' }, { name: status.getIn(['account', 'acct']) }); + account = status.get('account'); status = status.get('reblog'); } @@ -248,7 +268,7 @@ export default class Status extends ImmutablePureComponent { return ( <HotKeys handlers={handlers}> - <div className={classNames('status__wrapper', `status__wrapper-${status.get('visibility')}`, { focusable: !this.props.muted })} tabIndex={this.props.muted ? null : 0} data-featured={featured ? 'true' : null}> + <div className={classNames('status__wrapper', `status__wrapper-${status.get('visibility')}`, { focusable: !this.props.muted })} tabIndex={this.props.muted ? null : 0} data-featured={featured ? 'true' : null} aria-label={textForScreenReader(intl, status, rebloggedByText, !status.get('hidden'))}> {prepend} <div className={classNames('status', `status-${status.get('visibility')}`, { muted: this.props.muted })} data-id={status.get('id')}> diff --git a/app/javascript/mastodon/features/status/index.js b/app/javascript/mastodon/features/status/index.js index 98b321dbd..45e36e3eb 100644 --- a/app/javascript/mastodon/features/status/index.js +++ b/app/javascript/mastodon/features/status/index.js @@ -43,6 +43,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component'; import { HotKeys } from 'react-hotkeys'; import { boostModal, deleteModal } from '../../initial_state'; import { attachFullscreenListener, detachFullscreenListener, isFullscreen } from '../ui/util/fullscreen'; +import { textForScreenReader } from '../../components/status'; const messages = defineMessages({ deleteConfirm: { id: 'confirmations.delete.confirm', defaultMessage: 'Delete' }, @@ -418,7 +419,7 @@ export default class Status extends ImmutablePureComponent { {ancestors} <HotKeys handlers={handlers}> - <div className='focusable' tabIndex='0'> + <div className='focusable' tabIndex='0' aria-label={textForScreenReader(intl, status, false, !status.get('hidden'))}> <DetailedStatus status={status} onOpenVideo={this.handleOpenVideo} |