feat: Allow image descriptions to be read automatically by screen readers without needing to expand media. (#2269)
Fixes #2257. Co-authored-by: Nolan Lawson <nolan@nolanlawson.com>
This commit is contained in:
parent
a775bd9193
commit
8fc9d5c728
|
@ -37,12 +37,15 @@ function cleanupText (text) {
|
||||||
export function getAccessibleLabelForStatus (originalAccount, account, plainTextContent,
|
export function getAccessibleLabelForStatus (originalAccount, account, plainTextContent,
|
||||||
shortInlineFormattedDate, spoilerText, showContent,
|
shortInlineFormattedDate, spoilerText, showContent,
|
||||||
reblog, notification, visibility, omitEmojiInDisplayNames,
|
reblog, notification, visibility, omitEmojiInDisplayNames,
|
||||||
disableLongAriaLabels, showMedia, showPoll) {
|
disableLongAriaLabels, showMedia, sensitive, sensitiveShown, mediaAttachments, showPoll) {
|
||||||
const originalAccountDisplayName = getAccountAccessibleName(originalAccount, omitEmojiInDisplayNames)
|
const originalAccountDisplayName = getAccountAccessibleName(originalAccount, omitEmojiInDisplayNames)
|
||||||
const contentTextToShow = (showContent || !spoilerText)
|
const contentTextToShow = (showContent || !spoilerText)
|
||||||
? cleanupText(plainTextContent)
|
? cleanupText(plainTextContent)
|
||||||
: formatIntl('intl.contentWarningContent', { spoiler: cleanupText(spoilerText) })
|
: formatIntl('intl.contentWarningContent', { spoiler: cleanupText(spoilerText) })
|
||||||
const mediaTextToShow = showMedia && 'intl.hasMedia'
|
const mediaTextToShow = showMedia && 'intl.hasMedia'
|
||||||
|
const mediaDescText = (showMedia && (!sensitive || sensitiveShown))
|
||||||
|
? mediaAttachments.map(media => media.description)
|
||||||
|
: []
|
||||||
const pollTextToShow = showPoll && 'intl.hasPoll'
|
const pollTextToShow = showPoll && 'intl.hasPoll'
|
||||||
const privacyText = getPrivacyText(visibility)
|
const privacyText = getPrivacyText(visibility)
|
||||||
|
|
||||||
|
@ -57,6 +60,7 @@ export function getAccessibleLabelForStatus (originalAccount, account, plainText
|
||||||
originalAccountDisplayName,
|
originalAccountDisplayName,
|
||||||
contentTextToShow,
|
contentTextToShow,
|
||||||
mediaTextToShow,
|
mediaTextToShow,
|
||||||
|
...mediaDescText,
|
||||||
pollTextToShow,
|
pollTextToShow,
|
||||||
shortInlineFormattedDate,
|
shortInlineFormattedDate,
|
||||||
`@${originalAccount.acct}`,
|
`@${originalAccount.acct}`,
|
||||||
|
|
|
@ -270,6 +270,13 @@
|
||||||
originalStatus.media_attachments &&
|
originalStatus.media_attachments &&
|
||||||
originalStatus.media_attachments.length
|
originalStatus.media_attachments.length
|
||||||
),
|
),
|
||||||
|
mediaAttachments: ({ originalStatus }) => (
|
||||||
|
originalStatus.media_attachments
|
||||||
|
),
|
||||||
|
sensitiveShown: ({ $sensitivesShown, uuid }) => !!$sensitivesShown[uuid],
|
||||||
|
sensitive: ({ originalStatus, $markMediaAsSensitive, $neverMarkMediaAsSensitive }) => (
|
||||||
|
!$neverMarkMediaAsSensitive && ($markMediaAsSensitive || originalStatus.sensitive)
|
||||||
|
),
|
||||||
originalAccountEmojis: ({ originalAccount }) => (originalAccount.emojis || []),
|
originalAccountEmojis: ({ originalAccount }) => (originalAccount.emojis || []),
|
||||||
originalStatusEmojis: ({ originalStatus }) => (originalStatus.emojis || []),
|
originalStatusEmojis: ({ originalStatus }) => (originalStatus.emojis || []),
|
||||||
originalAccountDisplayName: ({ originalAccount }) => (originalAccount.display_name || originalAccount.username),
|
originalAccountDisplayName: ({ originalAccount }) => (originalAccount.display_name || originalAccount.username),
|
||||||
|
@ -288,12 +295,12 @@
|
||||||
ariaLabel: ({
|
ariaLabel: ({
|
||||||
originalAccount, account, plainTextContent, shortInlineFormattedDate, spoilerText,
|
originalAccount, account, plainTextContent, shortInlineFormattedDate, spoilerText,
|
||||||
showContent, reblog, notification, visibility, $omitEmojiInDisplayNames, $disableLongAriaLabels,
|
showContent, reblog, notification, visibility, $omitEmojiInDisplayNames, $disableLongAriaLabels,
|
||||||
showMedia, showPoll
|
showMedia, sensitive, sensitiveShown, mediaAttachments, showPoll
|
||||||
}) => (
|
}) => (
|
||||||
getAccessibleLabelForStatus(originalAccount, account, plainTextContent,
|
getAccessibleLabelForStatus(originalAccount, account, plainTextContent,
|
||||||
shortInlineFormattedDate, spoilerText, showContent,
|
shortInlineFormattedDate, spoilerText, showContent,
|
||||||
reblog, notification, visibility, $omitEmojiInDisplayNames, $disableLongAriaLabels,
|
reblog, notification, visibility, $omitEmojiInDisplayNames, $disableLongAriaLabels,
|
||||||
showMedia, showPoll
|
showMedia, sensitive, sensitiveShown, mediaAttachments, showPoll
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
showHeader: ({ notification, status, timelineType }) => (
|
showHeader: ({ notification, status, timelineType }) => (
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { loginAsFoobar } from '../roles'
|
||||||
import {
|
import {
|
||||||
generalSettingsButton,
|
generalSettingsButton,
|
||||||
getNthShowOrHideButton,
|
getNthShowOrHideButton,
|
||||||
getNthStatus, getNthStatusRelativeDateTime, homeNavButton,
|
getNthStatus, getNthStatusAndSensitiveButton, getNthStatusRelativeDateTime, homeNavButton,
|
||||||
notificationsNavButton,
|
notificationsNavButton,
|
||||||
scrollToStatus,
|
scrollToStatus,
|
||||||
settingsNavButton
|
settingsNavButton
|
||||||
|
@ -39,6 +39,7 @@ test('aria-labels for CWed statuses', async t => {
|
||||||
.expect(getNthStatus(1 + kittenIdx).getAttribute('aria-label')).match(
|
.expect(getNthStatus(1 + kittenIdx).getAttribute('aria-label')).match(
|
||||||
/foobar, Content warning: kitten CW, .* ago, @foobar, Public/i
|
/foobar, Content warning: kitten CW, .* ago, @foobar, Public/i
|
||||||
)
|
)
|
||||||
|
// toggle the CW button
|
||||||
.click(getNthShowOrHideButton(1 + kittenIdx))
|
.click(getNthShowOrHideButton(1 + kittenIdx))
|
||||||
.expect(getNthStatus(1 + kittenIdx).getAttribute('aria-label')).match(
|
.expect(getNthStatus(1 + kittenIdx).getAttribute('aria-label')).match(
|
||||||
/foobar, here's a kitten with a CW, .* ago, @foobar, Public/i
|
/foobar, here's a kitten with a CW, .* ago, @foobar, Public/i
|
||||||
|
@ -47,6 +48,26 @@ test('aria-labels for CWed statuses', async t => {
|
||||||
.expect(getNthStatus(1 + kittenIdx).getAttribute('aria-label')).match(
|
.expect(getNthStatus(1 + kittenIdx).getAttribute('aria-label')).match(
|
||||||
/foobar, Content warning: kitten CW, .* ago, @foobar, Public/i
|
/foobar, Content warning: kitten CW, .* ago, @foobar, Public/i
|
||||||
)
|
)
|
||||||
|
// toggle the "show sensitive media" button
|
||||||
|
.click(getNthStatusAndSensitiveButton(1 + kittenIdx, 1))
|
||||||
|
.expect(getNthStatus(1 + kittenIdx).getAttribute('aria-label')).match(
|
||||||
|
/foobar, Content warning: kitten CW, has media, kitten, .* ago, @foobar, Public/i
|
||||||
|
)
|
||||||
|
.click(getNthStatusAndSensitiveButton(1 + kittenIdx, 1))
|
||||||
|
.expect(getNthStatus(1 + kittenIdx).getAttribute('aria-label')).match(
|
||||||
|
/foobar, Content warning: kitten CW, .* ago, @foobar, Public/i
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('aria-labels for two media attachments', async t => {
|
||||||
|
await loginAsFoobar(t)
|
||||||
|
const twoKittensIdx = homeTimeline.findIndex(_ => _.content === 'here\'s 2 kitten photos')
|
||||||
|
await scrollToStatus(t, 1 + twoKittensIdx)
|
||||||
|
await t
|
||||||
|
.hover(getNthStatus(1 + twoKittensIdx))
|
||||||
|
.expect(getNthStatus(1 + twoKittensIdx).getAttribute('aria-label')).match(
|
||||||
|
/foobar, here's 2 kitten photos, has media, kitten, kitten, .* ago, @foobar, Public/i
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('aria-labels for notifications', async t => {
|
test('aria-labels for notifications', async t => {
|
||||||
|
|
|
@ -11,7 +11,7 @@ test('aria-labels for statuses with no content text', async t => {
|
||||||
await t
|
await t
|
||||||
.hover(getNthStatus(1))
|
.hover(getNthStatus(1))
|
||||||
.expect(getNthStatus(1).getAttribute('aria-label')).match(
|
.expect(getNthStatus(1).getAttribute('aria-label')).match(
|
||||||
/foobar, has media, (.+ ago|just now), @foobar, Public/i
|
/foobar, has media, kitteh, (.+ ago|just now), @foobar, Public/i
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue