From eccc642d831dcd3551d80b93ed6350c61197b067 Mon Sep 17 00:00:00 2001 From: Sem Bauke <46919888+Sembauke@users.noreply.github.com> Date: Fri, 6 Aug 2021 14:17:17 +0200 Subject: [PATCH] fix(client): store accessibility for screenreaders (#42996) * fix: store accessibility for screenreaders * Apply suggestions from code review Co-authored-by: Shaun Hamilton * fix: remove old comments * feat: at short cut announcement when running test * feat: announce that accesibility mode is turned on * fix: use Redux values * Apply suggestions from code review Co-authored-by: Shaun Hamilton * Apply suggestions from Oliver Co-authored-by: Oliver Eyton-Williams * fix: "rip out redux stuff" and use store instead * Apply suggestions from code review Co-authored-by: Oliver Eyton-Williams * Apply suggestions from code review Co-authored-by: Oliver Eyton-Williams * fix: old use of props * Update client/src/templates/Challenges/classic/editor.tsx Co-authored-by: Shaun Hamilton Co-authored-by: Shaun Hamilton Co-authored-by: Oliver Eyton-Williams --- .../Challenges/classic/MultifileEditor.js | 16 +----- .../templates/Challenges/classic/editor.tsx | 56 ++++++++++--------- .../Challenges/components/Tool-Panel.js | 7 ++- .../Challenges/redux/action-types.js | 3 +- .../src/templates/Challenges/redux/index.js | 13 +---- 5 files changed, 38 insertions(+), 57 deletions(-) diff --git a/client/src/templates/Challenges/classic/MultifileEditor.js b/client/src/templates/Challenges/classic/MultifileEditor.js index 101c2c1630c..80427c5e4de 100644 --- a/client/src/templates/Challenges/classic/MultifileEditor.js +++ b/client/src/templates/Challenges/classic/MultifileEditor.js @@ -8,9 +8,7 @@ import { canFocusEditorSelector, consoleOutputSelector, executeChallenge, - inAccessibilityModeSelector, saveEditorContent, - setAccessibilityMode, setEditorFocusability, visibleEditorsSelector, updateFile @@ -31,7 +29,6 @@ const propTypes = { executeChallenge: PropTypes.func.isRequired, ext: PropTypes.string, fileKey: PropTypes.string, - inAccessibilityMode: PropTypes.bool.isRequired, initialEditorContent: PropTypes.string, initialExt: PropTypes.string, output: PropTypes.arrayOf(PropTypes.string), @@ -40,7 +37,6 @@ const propTypes = { onResize: PropTypes.func }), saveEditorContent: PropTypes.func.isRequired, - setAccessibilityMode: PropTypes.func.isRequired, setEditorFocusability: PropTypes.func, theme: PropTypes.string, title: PropTypes.string, @@ -57,21 +53,12 @@ const mapStateToProps = createSelector( visibleEditorsSelector, canFocusEditorSelector, consoleOutputSelector, - inAccessibilityModeSelector, isDonationModalOpenSelector, userSelector, - ( - visibleEditors, - canFocus, - output, - accessibilityMode, - open, - { theme = 'default' } - ) => ({ + (visibleEditors, canFocus, output, open, { theme = 'default' }) => ({ visibleEditors, canFocus: open ? false : canFocus, output, - inAccessibilityMode: accessibilityMode, theme }) ); @@ -79,7 +66,6 @@ const mapStateToProps = createSelector( const mapDispatchToProps = { executeChallenge, saveEditorContent, - setAccessibilityMode, setEditorFocusability, updateFile }; diff --git a/client/src/templates/Challenges/classic/editor.tsx b/client/src/templates/Challenges/classic/editor.tsx index b797bcd65e7..a60b8318679 100644 --- a/client/src/templates/Challenges/classic/editor.tsx +++ b/client/src/templates/Challenges/classic/editor.tsx @@ -16,7 +16,7 @@ import React, { } from 'react'; import { connect } from 'react-redux'; import { createSelector } from 'reselect'; - +import store from 'store'; import { Loader } from '../../../components/helpers'; import { userSelector, isDonationModalOpenSelector } from '../../../redux'; import { @@ -27,14 +27,13 @@ import { ResizePropsType, TestType } from '../../../redux/prop-types'; + import { canFocusEditorSelector, consoleOutputSelector, executeChallenge, - inAccessibilityModeSelector, saveEditorContent, setEditorFocusability, - setAccessibilityMode, updateFile, challengeTestsSelector, submitChallenge @@ -55,13 +54,11 @@ interface EditorProps { executeChallenge: (isShouldCompletionModalOpen?: boolean) => void; ext: ExtTypes; fileKey: FileKeyTypes; - inAccessibilityMode: boolean; initialEditorContent: string; initialExt: string; output: string[]; resizeProps: ResizePropsType; saveEditorContent: () => void; - setAccessibilityMode: (isAccessible: boolean) => void; setEditorFocusability: (isFocusable: boolean) => void; submitChallenge: () => void; tests: TestType[]; @@ -100,21 +97,18 @@ interface EditorPropertyStore { const mapStateToProps = createSelector( canFocusEditorSelector, consoleOutputSelector, - inAccessibilityModeSelector, isDonationModalOpenSelector, userSelector, challengeTestsSelector, ( canFocus: boolean, output: string[], - accessibilityMode: boolean, open, { theme = 'default' }: { theme: string }, tests: [{ text: string; testString: string }] ) => ({ canFocus: open ? false : canFocus, output, - inAccessibilityMode: accessibilityMode, theme, tests }) @@ -125,7 +119,6 @@ const mapStateToProps = createSelector( const mapDispatchToProps = { executeChallenge, saveEditorContent, - setAccessibilityMode, setEditorFocusability, updateFile, submitChallenge @@ -297,12 +290,31 @@ const Editor = (props: EditorProps): JSX.Element => { // TODO this should *probably* be set on focus editorRef.current = editor; data.editor = editor; + + const storedAccessibilityMode = () => { + const accessibility = store.get('accessibilityMode') as boolean; + if (!accessibility) { + store.set('accessibilityMode', false); + } + // Only able to set the arialabel when accessibility mode is set to true + // Otherwise it gets overwritten by the monaco default aria-label + if (accessibility) { + editor.updateOptions({ + ariaLabel: + 'Accessibility mode set to true. Press Ctrl+e to disable or press Alt+F1 for more options' + }); + } + + return accessibility; + }; + + const accessibilityMode = storedAccessibilityMode(); editor.updateOptions({ - accessibilitySupport: props.inAccessibilityMode ? 'on' : 'auto' + accessibilitySupport: accessibilityMode ? 'on' : 'auto' }); // Users who are using screen readers should not have to move focus from // the editor to the description every time they open a challenge. - if (props.canFocus && !props.inAccessibilityMode) { + if (props.canFocus && !accessibilityMode) { // TODO: only one Editor should be calling for focus at once. editor.focus(); } else focusOnHotkeys(); @@ -343,28 +355,18 @@ const Editor = (props: EditorProps): JSX.Element => { editor.addAction({ id: 'toggle-accessibility', label: 'Toggle Accessibility Mode', - keybindings: [monaco.KeyMod.CtrlCmd | monaco.KeyCode.F1], + keybindings: [monaco.KeyMod.CtrlCmd | monaco.KeyCode.KEY_E], run: () => { - const currentAccessibility = props.inAccessibilityMode; - // The store needs to be updated first, as onDidChangeConfiguration is - // called before updateOptions returns - props.setAccessibilityMode(!currentAccessibility); + const currentAccessibility = storedAccessibilityMode(); + + store.set('accessibilityMode', !currentAccessibility); + editor.updateOptions({ - accessibilitySupport: currentAccessibility ? 'auto' : 'on' + accessibilitySupport: storedAccessibilityMode() ? 'on' : 'auto', }); } }); editor.onDidFocusEditorWidget(() => props.setEditorFocusability(true)); - // This is to persist changes caused by the accessibility tooltip. - editor.onDidChangeConfiguration(event => { - if ( - event.hasChanged(monaco.editor.EditorOption.accessibilitySupport) && - editor.getRawOptions().accessibilitySupport === 'on' && - !props.inAccessibilityMode - ) { - props.setAccessibilityMode(true); - } - }); const editableBoundaries = getEditableRegion(); diff --git a/client/src/templates/Challenges/components/Tool-Panel.js b/client/src/templates/Challenges/components/Tool-Panel.js index 4c20bac2079..e0cea1cc236 100644 --- a/client/src/templates/Challenges/components/Tool-Panel.js +++ b/client/src/templates/Challenges/components/Tool-Panel.js @@ -53,7 +53,12 @@ function ToolPanel({ isMobile ? 'tool-panel-group-mobile' : '' }`} > -