Skip to content

Commit

Permalink
screen readers read out search results/annotations
Browse files Browse the repository at this point in the history
- added aria-live container to reader ui
- during keyboard navigation through annotations or
when going through search results, set a message
inside of the aria-live container to have screen readers
announce them
- this should satisfy vpat 75 and 78 issues

Addresses: zotero/zotero#4223
  • Loading branch information
abaevbog committed Jun 27, 2024
1 parent 669ba6f commit 57062d6
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/common/components/reader-ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ const ReaderUI = React.forwardRef((props, ref) => {
onClose={() => props.onToggleEPUBAppearance({ open: false })}
/>
)}
<div id="a11tyAnnouncement" aria-live="polite"></div>
</Fragment>
);
});
Expand Down
33 changes: 32 additions & 1 deletion src/common/reader.js
Original file line number Diff line number Diff line change
Expand Up @@ -646,18 +646,33 @@ class Reader {
this._updateState({ [primary ? 'primaryViewFindState' : 'secondaryViewFindState']: params });
}

// Announce the index of current search result to screen readers
setA11tySearchResultMessage(primaryView) {
let result = (primaryView ? this._state.primaryViewFindState : this._state.secondaryViewFindState).result;
if (!result) return;
let searchIndex = `${this._getString("pdfReader.searchResultIndex")}: ${result.index + 1}`;
let totalResults = `${this._getString("pdfReader.searchResultTotal")}: ${result.total}`;
this.setA11tyMessage(`${searchIndex}. ${totalResults}`);
}

findNext(primary) {
if (primary === undefined) {
primary = this._lastViewPrimary;
}
(primary ? this._primaryView : this._secondaryView).findNext();
setTimeout(() => {
this.setA11tySearchResultMessage(primary);
});
}

findPrevious(primary) {
if (primary === undefined) {
primary = this._lastViewPrimary;
}
(primary ? this._primaryView : this._secondaryView).findPrevious();
setTimeout(() => {
this.setA11tySearchResultMessage(primary);
});
}

toggleEPUBAppearancePopup({ open }) {
Expand Down Expand Up @@ -830,6 +845,14 @@ class Reader {
this.setErrorMessage(this._getString('pdfReader.epubEncrypted'));
};

let onFocusAnnotation = (annotation) => {
if (!annotation) return;
// Announce the current annotation to screen readers
let annotationType = this._getString(`pdfReader.${annotation.type}Annotation`);
let annotationContent = `${annotationType}. ${annotation.text || annotation.comment}`;
this.setA11tyMessage(annotationContent);
}

let data;
if (this._type === 'pdf') {
data = this._data;
Expand Down Expand Up @@ -875,7 +898,8 @@ class Reader {
onSelectAnnotations,
onTabOut,
onKeyDown,
onKeyUp
onKeyUp,
onFocusAnnotation
};

if (this._type === 'pdf') {
Expand Down Expand Up @@ -925,6 +949,13 @@ class Reader {
this._updateState({ errorMessage });
}

// Set content of aria-live container that screen readers will announce
setA11tyMessage(a11tyMessage) {
// Voiceover won't announce messages inserted via <div id="a11tyAnnouncement" aria-live="polite">{state.a11tyMessage}</div>
// but setting .innerText does work. Likely due to either voiceover bug or not full aria-live support by firefox.
document.getElementById("a11tyAnnouncement").innerText = a11tyMessage;
}

getUnsavedAnnotations() {

}
Expand Down
8 changes: 8 additions & 0 deletions src/en-us.strings.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,14 @@ export default {
'pdfReader.selectArea': 'Select Area',
'pdfReader.addText': 'Add Text',
'pdfReader.draw': 'Draw',
'pdfReader.highlightAnnotation' : 'Highlight annotation',
'pdfReader.underlineAnnotation' : 'Underline annotation',
'pdfReader.noteAnnotation' : 'Note annotation',
'pdfReader.textAnnotation' : 'Text annotation',
'pdfReader.imageAnnotation' : 'Image annotation',
'pdfReader.inkAnnotation' : 'Drawing annotation',
'pdfReader.searchResultIndex' : 'Search result',
'pdfReader.searchResultTotal' : 'Total search results',
'pdfReader.eraser': 'Eraser',
'pdfReader.pickColor': 'Pick a Color',
'pdfReader.addToNote': 'Add to Note',
Expand Down
2 changes: 2 additions & 0 deletions src/pdf/pdf-view.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ class PDFView {
this._onOpenAnnotationContextMenu = options.onOpenAnnotationContextMenu;
this._onKeyUp = options.onKeyUp;
this._onKeyDown = options.onKeyDown;
this._onFocusAnnotation = options.onFocusAnnotation;

this._onTabOut = options.onTabOut;

Expand Down Expand Up @@ -489,6 +490,7 @@ class PDFView {
}
}

this._onFocusAnnotation(this._focusedObject);
this._lastFocusedObject = this._focusedObject;

this._render();
Expand Down

0 comments on commit 57062d6

Please sign in to comment.