Bug 1574082 - Improve the labelling of the table and radio buttons, r=mtigley

This adds some polish to the existing markup, making it all a bit more intuitive.

1. Associate the graph legend to the fake table so it becomes kind of the caption for that table for screen reader users. Screen reader users will then hear something like "Table showing a graph  of .." plus the table information they already get since bug 1573197 landed.

2. Actually combine the number and tab's title into a spoken label for screen readers on each radio button, and for the description, use the explanatory paragraph's content. That way, screen reader users can just tab and arrow to each item in focus mode and hear all the relevant information at once without having to skip back and forth between the elements.

Differential Revision: https://phabricator.services.mozilla.com/D42082

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Marco Zehe 2019-08-15 14:29:48 +00:00
Родитель e53cb2392a
Коммит 6801deffb6
2 изменённых файлов: 59 добавлений и 28 удалений

Просмотреть файл

@ -36,52 +36,52 @@
<div class="body-wrapper">
<p id="graph-week-summary"></p>
<div id="graph-wrapper">
<div id="graph" role="table"></div>
<div id="graph" role="table" aria-labelledby="graphLegendDescription"></div>
<div id="legend">
<label id="graphLegendDescription" data-l10n-id="graph-legend-description"></label>
<input id="tab-social" data-type="social" type="radio" name="tabs" aria-describedby="socialTitle" checked>
<label for="tab-social" data-type="social"></label>
<input id="tab-social" data-type="social" type="radio" name="tabs" aria-labelledby="socialLabel socialTitle" aria-describedby="socialContent" checked>
<label id="socialLabel" for="tab-social" data-type="social"></label>
<input id="tab-cookie" data-type="cookie" type="radio" name="tabs" aria-describedby="cookieTitle">
<label for="tab-cookie" data-type="cookie"></label>
<input id="tab-cookie" data-type="cookie" type="radio" name="tabs" aria-labelledby="cookieLabel cookieTitle" aria-describedby="cookieContent">
<label id="cookieLabel" for="tab-cookie" data-type="cookie"></label>
<input id="tab-tracker" data-type="tracker" type="radio" name="tabs" aria-describedby="trackerTitle">
<label for="tab-tracker" data-type="tracker"></label>
<input id="tab-tracker" data-type="tracker" type="radio" name="tabs" aria-labelledby="trackerLabel trackerTitle" aria-describedby="trackerContent">
<label id="trackerLabel" for="tab-tracker" data-type="tracker"></label>
<input id="tab-fingerprinter" data-type="fingerprinter" type="radio" name="tabs" aria-describedby="fingerprinterTitle">
<label for="tab-fingerprinter" data-type="fingerprinter"></label>
<input id="tab-fingerprinter" data-type="fingerprinter" type="radio" name="tabs" aria-labelledby="fingerprinterLabel fingerprinterTitle" aria-describedby="fingerprinterContent">
<label id="fingerprinterLabel" for="tab-fingerprinter" data-type="fingerprinter"></label>
<input id="tab-cryptominer" data-type="cryptominer" type="radio" name="tabs" aria-describedby="cryptominerTitle">
<label for="tab-cryptominer" data-type="cryptominer"></label>
<input id="tab-cryptominer" data-type="cryptominer" type="radio" name="tabs" aria-labelledby="cryptominerLabel cryptominerTitle" aria-describedby="cryptominerContent">
<label id="cryptominerLabel" for="tab-cryptominer" data-type="cryptominer"></label>
<div id=highlight></div>
<div id=highlight-hover></div>
<div id="social" class="tab-content">
<p id="socialTitle" class="content-title" data-l10n-id="social-tab-title"></p>
<p data-l10n-id="social-tab-contant">
<p id="socialContent" data-l10n-id="social-tab-contant">
<a target="_blank" id="social-link" data-l10n-name="learn-more-link"></a>
</p>
</div>
<div id="cookie" class="tab-content">
<p id="cookieTitle" class="content-title" data-l10n-id="cookie-tab-title"></p>
<p data-l10n-id="cookie-tab-content">
<p id="cookieContent" data-l10n-id="cookie-tab-content">
<a target="_blank" id="cookie-link" data-l10n-name="learn-more-link"></a>
</p>
</div>
<div id="tracker" class="tab-content">
<p id="trackerTitle" class="content-title" data-l10n-id="tracker-tab-title"></p>
<p data-l10n-id="tracker-tab-content">
<p id="trackerContent" data-l10n-id="tracker-tab-content">
<a target="_blank" id="tracker-link" data-l10n-name="learn-more-link"></a>
</p>
</div>
<div id="fingerprinter" class="tab-content">
<p id="fingerprinterTitle" class="content-title" data-l10n-id="fingerprinter-tab-title"></p>
<p data-l10n-id="fingerprinter-tab-content">
<p id="fingerprinterContent" data-l10n-id="fingerprinter-tab-content">
<a target="_blank" id="fingerprinter-link" data-l10n-name="learn-more-link"></a>
</p>
</div>
<div id="cryptominer" class="tab-content">
<p id="cryptominerTitle" class="content-title" data-l10n-id="cryptominer-tab-title"></p>
<p data-l10n-id="cryptominer-tab-content">
<p id="cryptominerContent" data-l10n-id="cryptominer-tab-content">
<a target="_blank" id="cryptominer-link" data-l10n-name="learn-more-link"></a>
</p>
</div>

Просмотреть файл

@ -205,6 +205,11 @@ add_task(async function test_graph_display() {
DATA_TYPES.length + 2,
"Table has the right number of columns"
);
is(
content.document.getElementById("graph").getAttribute("aria-labelledby"),
"graphLegendDescription",
"Table has an accessible label"
);
// today has each type
// yesterday will have no tracking cookies
@ -391,43 +396,69 @@ add_task(async function test_graph_display() {
"Row has the columns in the right order"
);
// Check that each tab has the correct aria-describedby value. This helps screen readers
// know what type of tracker the reported tab number is referencing.
// Check that each tab has the correct aria-labelledby and aria-describedby
// values. This helps screen readers know what type of tracker the reported
// tab number is referencing.
const socialTab = content.document.getElementById("tab-social");
is(
socialTab.getAttribute("aria-labelledby"),
"socialLabel socialTitle",
"aria-labelledby attribute is socialLabel socialTitle"
);
is(
socialTab.getAttribute("aria-describedby"),
"socialTitle",
"aria-describedby attribute is socialTitle"
"socialContent",
"aria-describedby attribute is socialContent"
);
const cookieTab = content.document.getElementById("tab-cookie");
is(
cookieTab.getAttribute("aria-labelledby"),
"cookieLabel cookieTitle",
"aria-labelledby attribute is cookieLabel cookieTitle"
);
is(
cookieTab.getAttribute("aria-describedby"),
"cookieTitle",
"aria-describedby attribute is cookieTitle"
"cookieContent",
"aria-describedby attribute is cookieContent"
);
const trackerTab = content.document.getElementById("tab-tracker");
is(
trackerTab.getAttribute("aria-labelledby"),
"trackerLabel trackerTitle",
"aria-labelledby attribute is trackerLabel trackerTitle"
);
is(
trackerTab.getAttribute("aria-describedby"),
"trackerTitle",
"aria-describedby attribute is trackerTitle"
"trackerContent",
"aria-describedby attribute is trackerContent"
);
const fingerprinterTab = content.document.getElementById(
"tab-fingerprinter"
);
is(
fingerprinterTab.getAttribute("aria-labelledby"),
"fingerprinterLabel fingerprinterTitle",
"aria-labelledby attribute is fingerprinterLabel fingerprinterTitle"
);
is(
fingerprinterTab.getAttribute("aria-describedby"),
"fingerprinterTitle",
"aria-describedby attribute is fingerprinterTitle"
"fingerprinterContent",
"aria-describedby attribute is fingerprinterContent"
);
const cryptominerTab = content.document.getElementById("tab-cryptominer");
is(
cryptominerTab.getAttribute("aria-labelledby"),
"cryptominerLabel cryptominerTitle",
"aria-labelledby attribute is cryptominerLabel cryptominerTitle"
);
is(
cryptominerTab.getAttribute("aria-describedby"),
"cryptominerTitle",
"aria-describedby attribute is cryptominerTitle"
"cryptominerContent",
"aria-describedby attribute is cryptominerContent"
);
});