fix(a11y): add aria-live for keyboard shortcuts (#2176)

Fixes #2163
This commit is contained in:
Nolan Lawson 2022-11-12 09:47:02 -08:00 committed by GitHub
parent f301fc59f6
commit 19e466aa90
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 22 additions and 4 deletions

View file

@ -104,6 +104,9 @@
<!-- LoadingMask.html gets rendered here --> <!-- LoadingMask.html gets rendered here -->
<div id="loading-mask" aria-hidden="true"></div> <div id="loading-mask" aria-hidden="true"></div>
<!-- announceAriaLivePolite.js gets rendered here -->
<div id="theAriaLive" class="sr-only" aria-live="polite"></div>
<!-- inline SVG --> <!-- inline SVG -->
<!-- Sapper creates a <script> tag containing `templates/client.js` <!-- Sapper creates a <script> tag containing `templates/client.js`

View file

@ -513,6 +513,9 @@ export default {
pollYouCreatedEnded: 'A poll you created has ended', pollYouCreatedEnded: 'A poll you created has ended',
pollYouVotedEnded: 'A poll you voted on has ended', pollYouVotedEnded: 'A poll you voted on has ended',
reblogged: 'boosted', reblogged: 'boosted',
favorited: 'favorited',
unreblogged: 'unboosted',
unfavorited: 'unfavorited',
showSensitiveMedia: 'Show sensitive media', showSensitiveMedia: 'Show sensitive media',
hideSensitiveMedia: 'Hide sensitive media', hideSensitiveMedia: 'Hide sensitive media',
clickToShowSensitive: 'Sensitive content. Click to show.', clickToShowSensitive: 'Sensitive content. Click to show.',

View file

@ -38,9 +38,9 @@
/> />
</div> </div>
{#if enableShortcuts} {#if enableShortcuts}
<Shortcut scope={shortcutScope} key="f" on:pressed="toggleFavorite()"/> <Shortcut scope={shortcutScope} key="f" on:pressed="toggleFavorite(true)"/>
<Shortcut scope={shortcutScope} key="r" on:pressed="reply()"/> <Shortcut scope={shortcutScope} key="r" on:pressed="reply()"/>
<Shortcut scope={shortcutScope} key="b" on:pressed="reblog()"/> <Shortcut scope={shortcutScope} key="b" on:pressed="reblog(true)"/>
{/if} {/if}
<style> <style>
.status-toolbar { .status-toolbar {
@ -77,6 +77,7 @@
import { updateProfileAndRelationship } from '../../_actions/accounts.js' import { updateProfileAndRelationship } from '../../_actions/accounts.js'
import { FAVORITE_ANIMATION, REBLOG_ANIMATION } from '../../_static/animations.js' import { FAVORITE_ANIMATION, REBLOG_ANIMATION } from '../../_static/animations.js'
import { on } from '../../_utils/eventBus.js' import { on } from '../../_utils/eventBus.js'
import { announceAriaLivePolite } from '../../_utils/announceAriaLivePolite.js'
export default { export default {
oncreate () { oncreate () {
@ -112,21 +113,27 @@
}, },
store: () => store, store: () => store,
methods: { methods: {
toggleFavorite () { toggleFavorite (announce) {
const { originalStatusId, favorited } = this.get() const { originalStatusId, favorited } = this.get()
const newFavoritedValue = !favorited const newFavoritedValue = !favorited
/* no await */ setFavorited(originalStatusId, newFavoritedValue) /* no await */ setFavorited(originalStatusId, newFavoritedValue)
if (newFavoritedValue) { if (newFavoritedValue) {
this.refs.favoriteIcon.animate(FAVORITE_ANIMATION) this.refs.favoriteIcon.animate(FAVORITE_ANIMATION)
} }
if (announce) {
announceAriaLivePolite(newFavoritedValue ? 'intl.favorited' : 'intl.unfavorited')
}
}, },
reblog () { reblog (announce) {
const { originalStatusId, reblogged } = this.get() const { originalStatusId, reblogged } = this.get()
const newRebloggedValue = !reblogged const newRebloggedValue = !reblogged
/* no await */ setReblogged(originalStatusId, newRebloggedValue) /* no await */ setReblogged(originalStatusId, newRebloggedValue)
if (newRebloggedValue) { if (newRebloggedValue) {
this.refs.reblogIcon.animate(REBLOG_ANIMATION) this.refs.reblogIcon.animate(REBLOG_ANIMATION)
} }
if (announce) {
announceAriaLivePolite(newRebloggedValue ? 'intl.reblogged' : 'intl.unreblogged')
}
}, },
reply () { reply () {
requestAnimationFrame(() => { requestAnimationFrame(() => {

View file

@ -0,0 +1,5 @@
const ariaLiveElement = process.browser && document.getElementById('theAriaLive')
export function announceAriaLivePolite (text) {
ariaLiveElement.textContent = text
}