From ded35e43a04cf01c94f4b30f9c0b9f58d2ba6db2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20V=C3=A1gner?= Date: Tue, 2 Oct 2018 13:55:24 +0200 Subject: [PATCH] A11y: repurpose more divs into AccessibleButtons. With this more of the controls that look like buttons can be operated via the keyboard and navigated to by screen reader users. This includes editor buttons such as File upload, Audio / Video call, Right pannel hide button, Jump to the bottom timeline button, and some more buttons found in the user settings. Also I have added alt texts to some images that in turn label buttons which these happen to be packed in and removed some untranslated alt texts from decorative non-actionable images that might add more verbosity when talking about screen reader user experience. --- src/components/structures/RightPanel.js | 7 +++-- src/components/structures/RoomStatusBar.js | 11 +++++--- src/components/structures/UserSettings.js | 28 +++++++++---------- src/components/views/elements/AppWarning.js | 2 +- src/components/views/globals/CookieBar.js | 4 +-- src/components/views/globals/MatrixToolbar.js | 4 +-- src/components/views/globals/NewVersionBar.js | 2 +- .../views/globals/PasswordNagBar.js | 2 +- .../views/globals/UpdateCheckBar.js | 6 ++-- src/components/views/rooms/AppsDrawer.js | 7 ++--- src/components/views/rooms/MemberInfo.js | 2 +- src/components/views/rooms/MessageComposer.js | 23 +++++++-------- src/components/views/settings/DevicesPanel.js | 5 ++-- src/components/views/voip/CallView.js | 5 ++-- 14 files changed, 57 insertions(+), 51 deletions(-) diff --git a/src/components/structures/RightPanel.js b/src/components/structures/RightPanel.js index 86870718e8..9017447a34 100644 --- a/src/components/structures/RightPanel.js +++ b/src/components/structures/RightPanel.js @@ -51,6 +51,7 @@ class HeaderButton extends React.Component { return @@ -345,11 +346,11 @@ module.exports = React.createClass({ // being put in the RoomHeader or GroupView header, so only show the minimise // button on these 2 screens or you won't be able to re-expand the panel. headerButtons.push( -
- -
, + +
, ); } diff --git a/src/components/structures/RoomStatusBar.js b/src/components/structures/RoomStatusBar.js index fec59aadd5..4f9ac153f5 100644 --- a/src/components/structures/RoomStatusBar.js +++ b/src/components/structures/RoomStatusBar.js @@ -223,14 +223,15 @@ module.exports = React.createClass({ ); } + const AccessibleButton = sdk.getComponent("elements.AccessibleButton"); if (!this.props.atEndOfLiveTimeline) { return ( -
{_t("Scroll -
+ ); } @@ -385,7 +386,7 @@ module.exports = React.createClass({ } return
- {_t("Warning")} +
{ title } @@ -485,7 +486,9 @@ module.exports = React.createClass({
{ indicator }
- { content } +
+ { content } +
); }, diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index 68009a74a8..7b79eebbb6 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -831,9 +831,9 @@ module.exports = React.createClass({
{ _t('Privacy is important to us, so we don\'t collect any personal' + ' or identifiable data for our analytics.') } -
+ { _t('Learn more about how we use analytics.') } -
+ { ANALYTICS_SETTINGS.map( this._renderDeviceSetting ) }
; @@ -1065,9 +1065,9 @@ module.exports = React.createClass({ _renderWebRtcDeviceSettings: function() { if (this.state.mediaDevices === false) { return ( -

+ { _t('Missing Media Permissions, click here to request.') } -

+ ); } else if (!this.state.mediaDevices) return; @@ -1233,10 +1233,10 @@ module.exports = React.createClass({ value={this.presentableTextForThreepid(val)} disabled /> -
+ {_t("Remove")} -
+ ); }); @@ -1258,9 +1258,9 @@ module.exports = React.createClass({ blurToCancel={false} onValueChanged={this._onAddEmailEditFinished} /> -
+ {_t("Add")} -
+ ); } @@ -1328,25 +1328,25 @@ module.exports = React.createClass({
-
+ {_t("Remove -
+
-
+ -
+
@@ -1395,11 +1395,11 @@ module.exports = React.createClass({
{ _t('Access Token:') + ' ' } - <{ _t("click to reveal") }> - +
{ _t("Homeserver is") } { MatrixClientPeg.get().getHomeserverUrl() } diff --git a/src/components/views/elements/AppWarning.js b/src/components/views/elements/AppWarning.js index f4015ae5b7..60809f5ca1 100644 --- a/src/components/views/elements/AppWarning.js +++ b/src/components/views/elements/AppWarning.js @@ -6,7 +6,7 @@ const AppWarning = (props) => { return (
- {_t('Warning!')} +
{ props.errorMsg } diff --git a/src/components/views/globals/CookieBar.js b/src/components/views/globals/CookieBar.js index a63a163dd1..3dc618edf5 100644 --- a/src/components/views/globals/CookieBar.js +++ b/src/components/views/globals/CookieBar.js @@ -51,7 +51,7 @@ export default class CookieBar extends React.Component { const toolbarClasses = "mx_MatrixToolbar"; return (
- Warning +
{ this.props.policyUrl ? _t( "Please help improve Riot.im by sending anonymous usage data. " + @@ -95,7 +95,7 @@ export default class CookieBar extends React.Component { { _t("Yes, I want to help!") } - + {_t('Close')}/
); diff --git a/src/components/views/globals/MatrixToolbar.js b/src/components/views/globals/MatrixToolbar.js index f85a30bcdf..45feede5a0 100644 --- a/src/components/views/globals/MatrixToolbar.js +++ b/src/components/views/globals/MatrixToolbar.js @@ -35,11 +35,11 @@ module.exports = React.createClass({ render: function() { return (
- Warning +
{ _t('You are not receiving desktop notifications') } { _t('Enable them now') }
- + {_t('Close')}/
); }, diff --git a/src/components/views/globals/NewVersionBar.js b/src/components/views/globals/NewVersionBar.js index 527df5f864..1bd0bde526 100644 --- a/src/components/views/globals/NewVersionBar.js +++ b/src/components/views/globals/NewVersionBar.js @@ -96,7 +96,7 @@ export default React.createClass({ } return (
- Warning +
{_t("A new version of Riot is available.")}
diff --git a/src/components/views/globals/PasswordNagBar.js b/src/components/views/globals/PasswordNagBar.js index 4233363b95..5e3da3ad6d 100644 --- a/src/components/views/globals/PasswordNagBar.js +++ b/src/components/views/globals/PasswordNagBar.js @@ -34,7 +34,7 @@ export default React.createClass({ src="img/warning.svg" width="24" height="23" - alt="Warning" + alt="" />
{ _t( diff --git a/src/components/views/globals/UpdateCheckBar.js b/src/components/views/globals/UpdateCheckBar.js index 53801311d8..e499ddab31 100644 --- a/src/components/views/globals/UpdateCheckBar.js +++ b/src/components/views/globals/UpdateCheckBar.js @@ -71,9 +71,9 @@ export default React.createClass({ let image; if (doneStatuses.includes(this.props.status)) { - image = {warning}/; + image = ; } else { - image = {message}/; + image = ; } return ( @@ -83,7 +83,7 @@ export default React.createClass({ {message}
- + {_t('Close')}/
); diff --git a/src/components/views/rooms/AppsDrawer.js b/src/components/views/rooms/AppsDrawer.js index e6fe445b45..77d912ef2a 100644 --- a/src/components/views/rooms/AppsDrawer.js +++ b/src/components/views/rooms/AppsDrawer.js @@ -30,6 +30,7 @@ import ScalarMessaging from '../../../ScalarMessaging'; import { _t } from '../../../languageHandler'; import WidgetUtils from '../../../utils/WidgetUtils'; import WidgetEchoStore from "../../../stores/WidgetEchoStore"; +import AccessibleButton from '../elements/AccessibleButton'; // The maximum number of widgets that can be added in a room const MAX_WIDGETS = 2; @@ -193,17 +194,15 @@ module.exports = React.createClass({ if (this.props.showApps && this._canUserModify() ) { - addWidget =
[+] { _t('Add a widget') } -
; + ; } let spinner; diff --git a/src/components/views/rooms/MemberInfo.js b/src/components/views/rooms/MemberInfo.js index e6e6350083..ff5f41c7d1 100644 --- a/src/components/views/rooms/MemberInfo.js +++ b/src/components/views/rooms/MemberInfo.js @@ -935,7 +935,7 @@ module.exports = withMatrixClient(React.createClass({
- + {_t('Close')}
diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index c5e389aa06..66f3fdaa97 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -292,21 +292,22 @@ export default class MessageComposer extends React.Component { let videoCallButton; let hangupButton; + const AccessibleButton = sdk.getComponent('elements.AccessibleButton'); // Call buttons if (this.props.callState && this.props.callState !== 'ended') { hangupButton = -
+ {_t('Hangup')} -
; + ; } else { callButton = -
+ -
; + ; videoCallButton = -
+ -
; + ; } const canSendMessages = !this.state.tombstone && @@ -317,18 +318,19 @@ export default class MessageComposer extends React.Component { // check separately for whether we can call, but this is slightly // complex because of conference calls. const uploadButton = ( -
-
+ ); const formattingButton = this.state.inputState.isRichTextEnabled ? ( - {_t("Show
@@ -423,7 +424,7 @@ export default class MessageComposer extends React.Component { onMouseDown={this.onToggleMarkdownClicked} className="mx_MessageComposer_formatbar_markdown mx_filterFlipColor" src={`img/button-md-${!this.state.inputState.isRichTextEnabled}.png`} /> - diff --git a/src/components/views/settings/DevicesPanel.js b/src/components/views/settings/DevicesPanel.js index f0fec2cf63..25850819bd 100644 --- a/src/components/views/settings/DevicesPanel.js +++ b/src/components/views/settings/DevicesPanel.js @@ -164,6 +164,7 @@ export default class DevicesPanel extends React.Component { render() { const Spinner = sdk.getComponent("elements.Spinner"); + const AccessibleButton = sdk.getComponent("elements.AccessibleButton"); if (this.state.deviceLoadError !== undefined) { const classes = classNames(this.props.className, "error"); @@ -185,9 +186,9 @@ export default class DevicesPanel extends React.Component { const deleteButton = this.state.deleting ? : -
+ { _t("Delete %(count)s devices", {count: this.state.selectedDevices.length}) } -
; + ; const classes = classNames(this.props.className, "mx_DevicesPanel"); return ( diff --git a/src/components/views/voip/CallView.js b/src/components/views/voip/CallView.js index 47e8ae22db..1a84d23f9b 100644 --- a/src/components/views/voip/CallView.js +++ b/src/components/views/voip/CallView.js @@ -125,14 +125,15 @@ module.exports = React.createClass({ render: function() { const VideoView = sdk.getComponent('voip.VideoView'); + const AccessibleButton = sdk.getComponent('elements.AccessibleButton'); let voice; if (this.state.call && this.state.call.type === "voice" && this.props.showVoice) { const callRoom = MatrixClientPeg.get().getRoom(this.state.call.roomId); voice = ( -
+ { _t("Active call (%(roomName)s)", {roomName: callRoom.name}) } -
+ ); }