Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use fluent to format a11y strings in reader #144

Merged
merged 1 commit into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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"
};
Loading