fix(a11y): enhance accessibility of prismjs code examples (#48639)

This commit is contained in:
Bruce Blaser
2022-12-05 06:19:36 -08:00
committed by GitHub
parent 801c245326
commit bfcdcf7788
4 changed files with 43 additions and 3 deletions
@@ -503,7 +503,8 @@
"open-preview-in-new-window": "Open the preview in a new window and focus it",
"step": "Step",
"steps": "Steps",
"steps-for": "Steps for {{blockTitle}}"
"steps-for": "Steps for {{blockTitle}}",
"code-example": "{{codeName}} code example"
},
"flash": {
"honest-first": "To claim a certification, you must first accept our academic honesty policy",
@@ -7,7 +7,7 @@ import type {
editor
// eslint-disable-next-line import/no-duplicates
} from 'monaco-editor/esm/vs/editor/editor.api';
import { highlightAllUnder } from 'prismjs';
import Prism from 'prismjs';
import React, {
useEffect,
Suspense,
@@ -66,6 +66,7 @@ import {
isChallengeCompletedSelector
} from '../redux/selectors';
import GreenPass from '../../../assets/icons/green-pass';
import { enhancePrismAccessibility } from '../utils/index';
import LowerJaw from './lower-jaw';
import './editor.css';
@@ -725,7 +726,8 @@ const Editor = (props: EditorProps): JSX.Element => {
descContainer.appendChild(jawHeading);
descContainer.appendChild(desc);
desc.innerHTML = description;
highlightAllUnder(desc);
Prism.hooks.add('complete', enhancePrismAccessibility);
Prism.highlightAllUnder(desc);
domNode.style.userSelect = 'text';
@@ -1,5 +1,6 @@
import Prism from 'prismjs';
import React, { useRef, useEffect } from 'react';
import { enhancePrismAccessibility } from '../utils';
interface PrismFormattedProps {
className?: string;
@@ -12,6 +13,7 @@ function PrismFormatted({ className, text }: PrismFormattedProps): JSX.Element {
useEffect(() => {
// Just in case 'current' has not been created, though it should have been.
if (instructionsRef.current) {
Prism.hooks.add('complete', enhancePrismAccessibility);
Prism.highlightAllUnder(instructionsRef.current);
}
}, []);
@@ -1,3 +1,4 @@
import i18next from 'i18next';
import envData from '../../../../../config/env.json';
const { forumLocation } = envData;
@@ -31,3 +32,37 @@ export function transformEditorLink(url: string): string {
'//glitch.com/edit/#!/$<projectname>'
);
}
export function enhancePrismAccessibility(
prismEnv: Prism.hooks.ElementHighlightedEnvironment
) {
const langs: { [key: string]: string } = {
js: 'JavaScript',
javascript: 'JavaScript',
css: 'CSS',
html: 'HTML',
python: 'python',
py: 'python',
xml: 'XML',
jsx: 'JSX',
scss: 'SCSS',
sql: 'SQL',
http: 'HTTP',
json: 'JSON',
pug: 'pug'
};
const parent = prismEnv?.element?.parentElement;
if (parent && parent.nodeName === 'PRE' && parent.tabIndex === 0) {
parent.setAttribute('role', 'region');
const codeType = prismEnv.element?.className
.replace(/language-(.*)/, '$1')
.toLowerCase();
const codeName = langs[codeType] || '';
parent.setAttribute(
'aria-label',
i18next.t('aria.code-example', {
codeName
})
);
}
}