Skip to content

Commit

Permalink
use document.l10n to format a11y strings
Browse files Browse the repository at this point in the history
- For zotero build, add "reader.ftl" for localization
- Remove redundant a11y strings from en-us.strings.js
- Use document.l10n.formatValue for live messages
and just data-l10n-id for aria labels
- If document.l10n is undefined, nothing will be announced.
That is until web library supports fluent.
  • Loading branch information
abaevbog committed Oct 14, 2024
1 parent 1918a73 commit 13a3f68
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 67 deletions.
1 change: 1 addition & 0 deletions index.reader.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<script src="resource://zotero/react-dom.js"></script>
<script src="resource://zotero/react-intl.js"></script>
<script src="resource://zotero/prop-types.js"></script>
<link rel="localization" href="reader.ftl"/>
<% } %>
</head>
<body class="sidebar-open">
Expand Down
22 changes: 6 additions & 16 deletions src/common/components/toolbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { useIntl } from 'react-intl';
import cx from 'classnames';
import CustomSections from './common/custom-sections';
import { ReaderContext } from '../reader';
import { isMac } from '../lib/utilities';
import { IconColor20 } from './common/icons';

import IconSidebar from '../../../res/icons/20/sidebar.svg';
Expand Down Expand Up @@ -72,15 +71,6 @@ function Toolbar(props) {
}
}

// Add aria instructions on how to add annotations with keyboard
function _constructAriaDecription(number) {
// Cmd/Alt+Option+1/2
let underlineOrHighlight = number <= 2;
let instruction = intl.formatMessage({ id: `pdfReader.a11y${underlineOrHighlight ? 'Textual' : ''}AnnotationInstruction` });
let modifier = intl.formatMessage({ id: `pdfReader.a11yAnnotationModifier${isMac() ? 'Mac' : ''}` });
return `${instruction} ${modifier} - ${number}`;
}

return (
<div className="toolbar" data-tabstop={1}>
<div className="start">
Expand Down Expand Up @@ -186,7 +176,7 @@ function Toolbar(props) {
title={intl.formatMessage({ id: 'pdfReader.highlightText' })}
disabled={props.readOnly}
onClick={() => handleToolClick('highlight')}
aria-description={_constructAriaDecription(1)}
data-l10n-id="pdfReader-toolbar-highlight"
><IconHighlight/></button>
{ (platform !== 'web' || ['epub', 'snapshot'].includes(props.type)) && (
<button
Expand All @@ -195,7 +185,7 @@ function Toolbar(props) {
title={intl.formatMessage({ id: 'pdfReader.underlineText' })}
disabled={props.readOnly}
onClick={() => handleToolClick('underline')}
aria-description={_constructAriaDecription(2)}
data-l10n-id="pdfReader-toolbar-underline"
><IconUnderline/></button>
)}
<button
Expand All @@ -206,7 +196,7 @@ function Toolbar(props) {
title={intl.formatMessage({ id: 'pdfReader.addNote' })}
disabled={props.readOnly}
onClick={() => handleToolClick('note')}
aria-description={_constructAriaDecription(3)}
data-l10n-id="pdfReader-toolbar-note"
><IconNote/></button>
{props.type === 'pdf' && platform !== 'web' && (
<button
Expand All @@ -215,7 +205,7 @@ function Toolbar(props) {
title={intl.formatMessage({ id: 'pdfReader.addText' })}
disabled={props.readOnly}
onClick={() => handleToolClick('text')}
aria-description={_constructAriaDecription(4)}
data-l10n-id="pdfReader-toolbar-text"
><IconText/></button>
)}
{props.type === 'pdf' && (
Expand All @@ -225,7 +215,7 @@ function Toolbar(props) {
title={intl.formatMessage({ id: 'pdfReader.selectArea' })}
disabled={props.readOnly}
onClick={() => handleToolClick('image')}
aria-description={_constructAriaDecription(5)}
data-l10n-id="pdfReader-toolbar-area"
><IconImage/></button>
)}
{props.type === 'pdf' && (
Expand All @@ -235,7 +225,7 @@ function Toolbar(props) {
title={intl.formatMessage({ id: 'pdfReader.draw' })}
disabled={props.readOnly}
onClick={() => handleToolClick('ink')}
aria-description={intl.formatMessage({ id: 'pdfReader.a11yAnnotationNotSupported' })}
data-l10n-id="pdfReader-toolbar-draw"
><IconInk/></button>
)}
<div className="divider"/>
Expand Down
8 changes: 2 additions & 6 deletions src/common/components/view-popup/find-popup.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { DEBOUNCE_FIND_POPUP_INPUT } from '../../defines';
import IconChevronUp from '../../../../res/icons/20/chevron-up.svg';
import IconChevronDown from '../../../../res/icons/20/chevron-down.svg';
import IconClose from '../../../../res/icons/20/x.svg';
import { getCodeCombination, getKeyCombination, isMac } from '../../lib/utilities';
import { getCodeCombination, getKeyCombination } from '../../lib/utilities';

function FindPopup({ params, onChange, onFindNext, onFindPrevious, onAddAnnotation, tools }) {
const intl = useIntl();
Expand Down Expand Up @@ -116,11 +116,7 @@ function FindPopup({ params, onChange, onFindNext, onFindPrevious, onAddAnnotati
title={intl.formatMessage({ id: 'pdfReader.find' })}
className="toolbar-text-input"
placeholder="Find in document…"
aria-description={
intl.formatMessage({ id: 'pdfReader.a11yTextualAnnotationFindInDocumentInstruction' })
+ ` ${intl.formatMessage({ id: 'pdfReader.a11yAnnotationModifierControl' })} - ${intl.formatMessage({ id: `pdfReader.a11yAnnotationModifier${isMac() ? 'Mac' : ''}` })} - ${1}`
+ `, ${intl.formatMessage({ id: 'pdfReader.a11yAnnotationModifierControl' })} - ${intl.formatMessage({ id: `pdfReader.a11yAnnotationModifier${isMac() ? 'Mac' : ''}` })} - ${2}`
}
data-l10n-id="pdfReader-findInDocumentInput"
value={query !== null ? query : params.query}
tabIndex="-1"
data-tabstop={1}
Expand Down
37 changes: 15 additions & 22 deletions src/common/reader.js
Original file line number Diff line number Diff line change
Expand Up @@ -272,8 +272,11 @@ class Reader {
onAddAnnotation={(annotation, select) => {
annotation = this._annotationManager.addAnnotation(annotation);
// Tell screen readers the annotation was added after focus is settled
setTimeout(() => {
this.setA11yMessage(this._getString(`pdfReader.a11yAnnotationCreated.${annotation.type}`));
setTimeout(async () => {
// Temporary until web library supports fluent
if (!document.l10n) return;
let msg = await document.l10n.formatValue('pdfReader-a11yAnnotationCreated', { type : annotation.type } );
this.setA11yMessage(msg);
}, 100);
if (select) {
this.setSelectedAnnotations([annotation.id]);
Expand Down Expand Up @@ -787,8 +790,11 @@ class Reader {
let onAddAnnotation = (annotation, select) => {
annotation = this._annotationManager.addAnnotation(annotation);
// Tell screen readers the annotation was added after focus is settled
setTimeout(() => {
this.setA11yMessage(this._getString(`pdfReader.a11yAnnotationCreated.${annotation.type}`));
setTimeout(async () => {
// Temporary until web library supports fluent
if (!document.l10n) return;
let msg = await document.l10n.formatValue('pdfReader-a11yAnnotationCreated', { type : annotation.type } );
this.setA11yMessage(msg);
}, 100);
if (select) {
this.setSelectedAnnotations([annotation.id], true);
Expand Down Expand Up @@ -1215,24 +1221,11 @@ class Reader {
}
// After a small delay for focus to settle, announce to screen readers that annotation
// is selected and how one can manipulate it
setTimeout(() => {
let a11yAnnouncement = this._getString(`pdfReader.a11yAnnotationSelected.${annotation.type}`);
if (document.querySelector('.annotation-popup')) {
// add note that popup is opened
a11yAnnouncement += ' ' + this._getString('pdfReader.a11yAnnotationPopupAppeared');
}
if (['highlight', 'underline'].includes(annotation.type)) {
// tell how to edit highlight/underline annotations
a11yAnnouncement += ' ' + this._getString('pdfReader.a11yEditTextAnnotation') + ' ' + this._getString(`pdfReader.a11yAnnotationModifier${isMac() ? 'Mac' : ''}`);
}
else if (['note', 'text', 'image'].includes(annotation.type)) {
// tell how to move and resize remaining types
a11yAnnouncement += ' ' + this._getString('pdfReader.a11yMoveAnnotation');
if (['text', 'image'].includes(annotation.type)) {
a11yAnnouncement += ' ' + this._getString('pdfReader.a11yResizeAnnotation');
}
}

setTimeout(async () => {
// Temporary until web library supports fluent
if (!document.l10n) return;
let popupVisible = document.querySelector('.annotation-popup') ? "yes" : "no";
let a11yAnnouncement = await document.l10n.formatValue('pdfReader-a11yAnnotationSelected', { type: annotation.type, popupVisible });
// only announce if the content view is focused. E.g. if comment in
// sidebar has focus, say nothing as it will not be relevant
if (document.activeElement.nodeName === 'IFRAME') {
Expand Down
23 changes: 0 additions & 23 deletions src/en-us.strings.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,27 +192,4 @@ export default {
'pdfReader.size': 'Size',
'pdfReader.merge': 'Merge',
'pdfReader.copyLink': 'Copy Link',
'pdfReader.a11yAnnotationModifierMac': 'Option',
'pdfReader.a11yAnnotationModifier': 'Alt',
'pdfReader.a11yAnnotationModifierControl': 'Control',
'pdfReader.a11yTextualAnnotationFindInDocumentInstruction': 'To turn a search result into a highlight or underline annotation, press',
'pdfReader.a11yTextualAnnotationInstruction': 'To annotate text via the keyboard, first use “Find in Document” to locate the phrase. Then, to turn the search result into an annotation, press Control -',
'pdfReader.a11yAnnotationInstruction': 'To add this annotation to the document, focus the document and press Control -',
'pdfReader.a11yAnnotationNotSupported': 'This annotation type cannot be created via the keyboard.',
'pdfReader.a11yMoveAnnotation': 'Use the arrow keys to move the annotation.',
'pdfReader.a11yEditTextAnnotation': 'To move the end of the text annotation, use the left/right arrow keys while holding Shift. To move the start of the annotation, use the arrow keys while holding Shift -',
'pdfReader.a11yResizeAnnotation': 'To resize the annotation, use the arrow keys while holding Shift.',
'pdfReader.a11yAnnotationPopupAppeared': 'Use Tab to navigate the annotation popup.',

"pdfReader.a11yAnnotationCreated.highlight": "Highlight annotation created",
"pdfReader.a11yAnnotationCreated.underline": "Underline annotation created",
"pdfReader.a11yAnnotationCreated.note": "Note annotation created",
"pdfReader.a11yAnnotationCreated.text": "Text annotation created",
"pdfReader.a11yAnnotationCreated.image": "Image annotation created",

"pdfReader.a11yAnnotationSelected.highlight": "Highlight annotation selected",
"pdfReader.a11yAnnotationSelected.underline": "Underline annotation selected",
"pdfReader.a11yAnnotationSelected.note": "Note annotation selected",
"pdfReader.a11yAnnotationSelected.text": "Text annotation selected",
"pdfReader.a11yAnnotationSelected.image": "Image annotation selected"
};

0 comments on commit 13a3f68

Please sign in to comment.