vpat:25 focusable sections in preferences

- make sections in preferences window focusable so
that all screen readers (particularly JAWS) can announce
section headers
- all other text that is not linked to any specific element
is linked to the sections
- changed all groupboxes for vboxes, otherwise aria-describedby
do not get announced
- a few minor css tweaks to keep old spacing and font as well
as display the focusring on the sections
This commit is contained in:
Bogdan Abaev 2024-07-25 17:54:19 -07:00
parent 9a43e8f057
commit 9e16e98562
9 changed files with 104 additions and 75 deletions

View file

@ -10,14 +10,6 @@ window[windowtype="zotero:pref"] {
color: -moz-DialogText;
}
groupbox > label > h2, groupbox > * > label > h2 {
border-bottom: #b5b5b5 1px solid;
}
groupbox > label > h2, groupbox > * > label > h2, caption {
padding-bottom: 0.2em;
font: caption;
}
.help-button {
appearance: auto;

View file

@ -326,6 +326,7 @@ var Zotero_Preferences = {
};
pane.loadPromise = rest();
await pane.loadPromise;
this._makeSectionsAriaAccessible(id);
},
/**
@ -853,5 +854,32 @@ ${str}
openURL: function (url) {
Zotero.warn("Zotero_Preferences.openURL() is deprecated -- use Zotero.launchURL()");
Zotero.launchURL(url);
},
// Make sections focusable with aria-labels as the closest header.
// This is a workaround for JAWS to announce section titles and textual
// information.
_makeSectionsAriaAccessible: function (sectionID) {
for (let section of document.querySelectorAll(".section,.main-section")) {
let isMain = section.classList.contains("main-section");
let header = section.querySelector(isMain ? "h1" : "h2");
if (!header) continue;
section.setAttribute("tabindex", 0);
section.setAttribute("aria-label", header.textContent);
}
if (sectionID == "zotero-prefpane-cite") {
// Special treatment for integration sections because they are constructed by showPreferences of plugin installers
for (let groupBox of document.querySelectorAll("#zotero-macword-integration, #zotero-libreoffice-integration, #zotero-winword-integration")) {
groupBox.classList.add("section");
groupBox.setAttribute("tabindex", 0);
let header = groupBox.querySelector("h2");
header.setAttribute('id', groupBox.id + '_header');
let wordProcessorInfo = groupBox.querySelector("description");
wordProcessorInfo.setAttribute('id', groupBox.id + '_info');
// Screen readers ignore aria-describedby on groupboxes, so use set aria-labelledby
// even though it sounds a bit odd.
groupBox.setAttribute("aria-labelledby", `${groupBox.id + '_header'} ${groupBox.id + '_info'}`);
}
}
}
};

View file

@ -93,7 +93,7 @@
hidden="true"/>
<search-textbox id="prefs-search" placeholder="&zotero.lookup.button.search;" timeout="1"/>
</html:div>
<html:div id="prefs-content">
<html:div id="prefs-content" tabindex="-1">
<html:div id="prefs-help-container">
<button
oncommand="Zotero_Preferences.openHelpLink()"

View file

@ -25,7 +25,7 @@
<vbox id="zotero-prefpane-advanced" onload="Zotero_Preferences.Advanced.init()">
<vbox class="main-section" id="zotero-prefpane-advanced-general-tab">
<groupbox id="zotero-prefpane-advanced-miscellaneous">
<vbox class="section" id="zotero-prefpane-advanced-miscellaneous">
<label><html:h2>&zotero.preferences.miscellaneous;</html:h2></label>
<html:div class="pref-row">
@ -37,9 +37,9 @@
<checkbox label="&zotero.preferences.reportTranslationFailure;" preference="extensions.zotero.reportTranslationFailure" native="true"/>
<checkbox data-l10n-id="preferences-advanced-enable-local-api" preference="extensions.zotero.httpServer.localAPI.enabled" native="true"/>
</groupbox>
</vbox>
<groupbox>
<vbox class="section">
<label><html:h2 data-l10n-id="preferences-advanced-language-and-region-title"/></label>
<checkbox
@ -47,17 +47,17 @@
preference="bidi.browser.ui"
native="true"
/>
</groupbox>
</vbox>
</vbox>
<vbox class="main-section">
<html:h1>&zotero.preferences.advanced.filesAndFolders;</html:h1>
<groupbox>
<vbox class="section" aria-describedby="attachmentBaseDir_message">
<label><html:h2>&zotero.preferences.attachmentBaseDir.caption;</html:h2></label>
<vbox>
<description>&zotero.preferences.attachmentBaseDir.message;</description>
<description id="attachmentBaseDir_message">&zotero.preferences.attachmentBaseDir.message;</description>
</vbox>
<hbox align="center">
@ -81,9 +81,9 @@
data-search-strings="attachmentBasePath.clearBasePath.message"/>
</hbox>
</groupbox>
</vbox>
<groupbox>
<vbox class="section">
<label><html:h2>&zotero.preferences.dataDir;</html:h2></label>
<radiogroup id="data-dir"
@ -109,9 +109,9 @@
<button id="migrate-data-dir" label="&zotero.preferences.dataDir.migrate;"
oncommand="Zotero_Preferences.Advanced.migrateDataDirectory()" hidden="true"/>
</hbox>
</groupbox>
</vbox>
<groupbox>
<vbox class="section">
<label><html:h2>&zotero.preferences.dbMaintenance;</html:h2></label>
<hbox style="display: block">
@ -124,7 +124,7 @@
label="&zotero.preferences.dbMaintenance.resetStyles;"
oncommand="Zotero_Preferences.Advanced.resetStyles()"/>
</hbox>
</groupbox>
</vbox>
</vbox>
<html:div class="main-section" id="zotero-prefpane-advanced-keys-tab">
@ -171,7 +171,7 @@
<vbox class="main-section" id="zotero-prefpane-advanced-feeds-tab">
<html:h1>&zotero.preferences.feeds;</html:h1>
<groupbox>
<vbox class="section">
<hbox>
<hbox align="center">
<label value="&zotero.preferences.feeds.sorting.label;" control="feed-sort"/>
@ -183,9 +183,9 @@
</menulist>
</hbox>
</hbox>
</groupbox>
</vbox>
<groupbox id="zotero-prefpane-advanced-feeds-feedDefaults">
<vbox class="section" id="zotero-prefpane-advanced-feeds-feedDefaults">
<label><html:h2>&zotero.preferences.feeds.feedDefaults;</html:h2></label>
<hbox>
<hbox align="center">
@ -211,13 +211,13 @@
<label id="zotero-prefpane-feeds-unreadAfter-label2" value="&zotero.feedSettings.cleanupUnreadAfter.label2;"/>
</hbox>
</hbox>
</groupbox>
</vbox>
</vbox>
<vbox class="main-section">
<html:h1>&zotero.preferences.prefpane.search;</html:h1>
<groupbox>
<vbox class="section">
<label><html:h2>&zotero.preferences.search.fulltextCache;</html:h2></label>
<hbox>
@ -242,12 +242,12 @@
<html:input id="fulltext-pdfMaxPages" type="text" size="5" preference="extensions.zotero.fulltext.pdfMaxPages"/>
<html:label>(&zotero.preferences.default; 100)</html:label>
</html:div>
</groupbox>
</vbox>
<groupbox id="fulltext-stats">
<vbox class="section" id="fulltext-stats" aria-describedby="fulltext-stats-info">
<label><html:h2>&zotero.preferences.search.indexStats;</html:h2></label>
<vbox class="form-grid">
<vbox class="form-grid" id="fulltext-stats-info">
<label value="&zotero.preferences.search.indexStats.indexed;"/>
<label id="fulltext-stats-indexed"/>
@ -260,7 +260,7 @@
<label value="&zotero.preferences.search.indexStats.words;"/>
<label id="fulltext-stats-words"/>
</vbox>
</groupbox>
</vbox>
</vbox>
<vbox>

View file

@ -25,7 +25,7 @@
<vbox id="zotero-prefpane-cite" onload="event.waitUntil(Zotero_Preferences.Cite.init())">
<vbox class="main-section" id="styles">
<groupbox flex="1">
<vbox class="section" flex="1">
<!-- HTML needs to be wrapped in an hbox to isolate from XUL box layout -->
<hbox><label control="styleManager-table"><html:h2>&zotero.preferences.cite.styles.styleManager;</html:h2></label></hbox>
@ -44,19 +44,21 @@
<button data-l10n-id="preferences-styleManager-add-button" data-l10n-args='{"label":"+"}'
oncommand="Zotero_Preferences.Cite.addStyle()"/>
</hbox>
</groupbox>
</vbox>
<groupbox>
<vbox class="section">
<label><html:h2>&zotero.preferences.citationOptions.caption;</html:h2></label>
<checkbox label="&zotero.preferences.export.citePaperJournalArticleURL;" preference="extensions.zotero.export.citePaperJournalArticleURL" native="true"/>
<checkbox label="&zotero.preferences.export.citePaperJournalArticleURL;"
preference="extensions.zotero.export.citePaperJournalArticleURL" native="true"
aria-describedby="export-citePaperJournalArticleURL"/>
<!-- This doesn't wrap without an explicit width, for some reason -->
<label id="export-citePaperJournalArticleURL" width="45em">
&zotero.preferences.export.citePaperJournalArticleURL.description;
</label>
</groupbox>
</vbox>
<groupbox>
<vbox class="section">
<label><html:h2>&zotero.general.tools;</html:h2></label>
<hbox>
@ -67,7 +69,7 @@
label="&zotero.preferences.stylePreview;"
oncommand="window.open('chrome://zotero/content/tools/cslpreview.xhtml', '_blank', 'chrome,width=950,height=700,resizable')"/>
</hbox>
</groupbox>
</vbox>
</vbox>
<vbox class="main-section" id="wordProcessors">
<html:h1>&zotero.preferences.cite.wordProcessors;</html:h1>

View file

@ -24,7 +24,7 @@
-->
<vbox id="zotero-prefpane-export" onload="event.waitUntil(Zotero_Preferences.Export.init())">
<groupbox id="zotero-prefpane-export-groupbox">
<vbox class="section" id="zotero-prefpane-export-groupbox" aria-describedby="quickCopy-instructions quickCopy-citationInstructions">
<vbox>
<label><html:h2>&zotero.preferences.quickCopy.caption;</html:h2></label>
</vbox>
@ -89,5 +89,5 @@
<html:input aria-labelledby="zotero-prefpane-quickcopy-draglimit-label1 zotero-prefpane-quickcopy-draglimit-label2" type="text" preference="extensions.zotero.export.quickCopy.dragLimit" size="3"/>
<label id="zotero-prefpane-quickcopy-draglimit-label2" value="&zotero.preferences.items;" flex="1"/>
</hbox>
</groupbox>
</vbox>
</vbox>

View file

@ -24,7 +24,7 @@
-->
<vbox id="zotero-prefpane-general" onload="Zotero_Preferences.General.init()">
<vbox class="main-section">
<groupbox>
<vbox class="section">
<label><html:h2>&zotero.preferences.interface;</html:h2></label>
<hbox align="center">
@ -78,9 +78,9 @@
><menupopup/></menulist>
</hbox>
</vbox>
</groupbox>
</vbox>
<groupbox id="zotero-prefpane-file-handling-groupbox">
<vbox class="section" id="zotero-prefpane-file-handling-groupbox">
<label><html:h2>&zotero.preferences.fileHandling;</html:h2></label>
<vbox>
@ -99,13 +99,13 @@
/>
</vbox>
</groupbox>
</vbox>
<groupbox id="zotero-prefpane-file-renaming-groupbox">
<vbox id="zotero-prefpane-file-renaming-groupbox" class="section" aria-describedby="preferences-file-renaming-intro">
<label><html:h2 data-l10n-id="preferences-file-renaming-title"/></label>
<vbox align="start">
<label data-l10n-id="preferences-file-renaming-intro"/>
<label id="preferences-file-renaming-intro" data-l10n-id="preferences-file-renaming-intro"/>
<separator class="thin"/>
<checkbox data-l10n-id="preferences-file-renaming-auto-rename-files"
preference="extensions.zotero.autoRenameFiles"
@ -122,9 +122,9 @@
oncommand="Zotero_Preferences.navigateToPane('zotero-subpane-file-renaming')"
/>
</vbox>
</groupbox>
</vbox>
<groupbox id="zotero-prefpane-reader-groupbox">
<vbox class="section" id="zotero-prefpane-reader-groupbox">
<label><html:h2 data-l10n-id="preferences-reader-title"/></label>
<vbox class="fileHandler-menus">
@ -196,12 +196,12 @@
data-l10n-id="preferences-reader-ebook-hyphenate"
native="true"
/>
</groupbox>
</vbox>
<groupbox id="zotero-prefpane-locate-groupbox">
<vbox class="section" id="zotero-prefpane-locate-groupbox" aria-describedby="preferences-locate-library-lookup-intro">
<label><html:h2>&zotero.preferences.prefpane.locate;</html:h2></label>
<label data-l10n-id="preferences-locate-library-lookup-intro"/>
<label id="preferences-locate-library-lookup-intro" data-l10n-id="preferences-locate-library-lookup-intro"/>
<separator class="thin"/>
<hbox align="center">
@ -225,9 +225,9 @@
/>
</hbox>
</groupbox>
</vbox>
<groupbox id="zotero-prefpane-miscellaneous-groupbox">
<vbox class="section" id="zotero-prefpane-miscellaneous-groupbox">
<label><html:h2>&zotero.preferences.miscellaneous;</html:h2></label>
<checkbox label="&zotero.preferences.automaticTags;" preference="extensions.zotero.automaticTags" native="true"/>
@ -236,19 +236,19 @@
<html:input aria-labelledby="trashAutoEmpty-label1 trashAutoEmpty-label2" type="text" size="2" preference="extensions.zotero.trashAutoEmptyDays"/>
<label id="trashAutoEmpty-label2" value="&zotero.preferences.trashAutoEmptyDaysPost;"/>
</hbox>
</groupbox>
</vbox>
<groupbox>
<vbox class="section">
<label><html:h2>&zotero.preferences.groups;</html:h2></label>
<label value="&zotero.preferences.groups.whenCopyingInclude;"/>
<label id="preferences-whenCopyingInclude" value="&zotero.preferences.groups.whenCopyingInclude;"/>
<vbox style="margin-left: 2em">
<checkbox label="&zotero.preferences.groups.childNotes;" preference="extensions.zotero.groups.copyChildNotes" native="true"/>
<checkbox label="&zotero.preferences.groups.childFiles;" preference="extensions.zotero.groups.copyChildFileAttachments" native="true"/>
<checkbox label="&zotero.preferences.groups.annotations;" preference="extensions.zotero.groups.copyAnnotations" native="true"/>
<checkbox label="&zotero.preferences.groups.childLinks;" preference="extensions.zotero.groups.copyChildLinks" native="true"/>
<checkbox label="&zotero.preferences.groups.tags;" preference="extensions.zotero.groups.copyTags" native="true"/>
<checkbox label="&zotero.preferences.groups.childNotes;" preference="extensions.zotero.groups.copyChildNotes" native="true" aria-describedby="preferences-whenCopyingInclude"/>
<checkbox label="&zotero.preferences.groups.childFiles;" preference="extensions.zotero.groups.copyChildFileAttachments" native="true" aria-describedby="preferences-whenCopyingInclude"/>
<checkbox label="&zotero.preferences.groups.annotations;" preference="extensions.zotero.groups.copyAnnotations" native="true" aria-describedby="preferences-whenCopyingInclude"/>
<checkbox label="&zotero.preferences.groups.childLinks;" preference="extensions.zotero.groups.copyChildLinks" native="true" aria-describedby="preferences-whenCopyingInclude"/>
<checkbox label="&zotero.preferences.groups.tags;" preference="extensions.zotero.groups.copyTags" native="true" aria-describedby="preferences-whenCopyingInclude"/>
</vbox>
</groupbox>
</vbox>
</vbox>
</vbox>

View file

@ -25,7 +25,7 @@
<vbox id="zotero-prefpane-sync" onload="Zotero_Preferences.Sync.init()">
<vbox class="main-section">
<vbox id="sync-unauthorized">
<groupbox>
<vbox class="section">
<label><html:h2>&zotero.preferences.sync.syncServer;</html:h2></label>
<hbox>
@ -62,11 +62,11 @@
<label is="zotero-text-link" value="&zotero.preferences.sync.about;" href="http://www.zotero.org/support/sync"/>
</vbox>
</hbox>
</groupbox>
</vbox>
</vbox>
<vbox id="sync-authorized" hidden="true">
<groupbox>
<vbox class="section">
<label><html:h2>&zotero.preferences.sync.syncServer;</html:h2></label>
<html:div class="form-grid">
@ -74,7 +74,8 @@
<hbox>
<label id="sync-username" value="Username"/>
<button label="&zotero.preferences.sync.unlinkAccount;"
oncommand="Zotero_Preferences.Sync.unlinkAccount()"/>
oncommand="Zotero_Preferences.Sync.unlinkAccount()"
aria-describedby="sync-username"/>
</hbox>
<box/>
@ -99,9 +100,9 @@
<label is="zotero-text-link" value="&zotero.preferences.sync.about;" href="http://www.zotero.org/support/sync"/>
</html:div>
</groupbox>
</vbox>
<groupbox id="storage-settings">
<vbox class="section" id="storage-settings">
<label><html:h2>&zotero.preferences.sync.fileSyncing;</html:h2></label>
<!-- My Library -->
@ -215,12 +216,12 @@
<vbox id="storage-terms">
<hbox style="margin-top: .4em; display: block" align="center">
<label>&zotero.preferences.sync.fileSyncing.tos1;</label>
<label is="zotero-text-link" href="https://www.zotero.org/support/terms/terms_of_service" value="&zotero.preferences.sync.fileSyncing.tos2;"/>
<label id="terms-label">&zotero.preferences.sync.fileSyncing.tos1;</label>
<label is="zotero-text-link" href="https://www.zotero.org/support/terms/terms_of_service" value="&zotero.preferences.sync.fileSyncing.tos2;" aria-describedby="terms-label"/>
<label>&zotero.preferences.period;</label>
</hbox>
</vbox>
</groupbox>
</vbox>
</vbox>
</vbox>

View file

@ -160,18 +160,24 @@ h1 {
}
}
groupbox > label > h2, groupbox > * > label > h2 {
border-bottom: none;
font-size: 15px;
font-weight: 600;
.section, .main-section {
@include focus-ring;
border-radius: 5px;
}
groupbox:first-of-type label > h2 {
.section > label > h2, .section > * > label > h2 {
border-bottom: none;
font-size: 14px;
font-weight: 600;
margin-bottom: 0.3em;
}
.section:first-of-type label > h2 {
margin-top: .5em !important;
}
/* Space out sections */
groupbox:not(:first-of-type) label > h2 {
.section:not(:first-of-type) label > h2 {
margin-top: 2em !important;
}