Skip to content

Commit c6cfd9e

Browse files
committed
Initial import of ReviewBoardA11yFixes.
This does the following: * Makes diff file names headings instead of table headers, thus preventing it from being reported as a header for every cell. * Makes the revision cells normal cells instead of headers, again preventing them from being reported inappropriately as headers for other cells. * For inserted and replaced lines, prefixes the right hand line number with off-screen text indicating the type of change.
1 parent 13d47a6 commit c6cfd9e

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed

ReviewBoardA11yFixes.user.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// ==UserScript==
2+
// @name Review Board Accessibility Fixes
3+
// @namespace http://axSGrease.nvaccess.org/
4+
// @description Improves the accessibility of Review Board.
5+
// @author James Teh <jamie@nvaccess.org>
6+
// @copyright 2016 NV Access Limited
7+
// @license GNU General Public License version 2.0
8+
// @version 2016.1
9+
// @grant GM_log
10+
// @include https://reviewboard.*/r/*/diff/*
11+
// ==/UserScript==
12+
13+
function tweakSideBySide(side) {
14+
// Make the diff file name into a heading instead of a table header.
15+
// Among other things, this prevents it from being reported as a header for every cell.
16+
var elem = side.querySelector('thead th');
17+
if (elem) {
18+
elem.setAttribute("role", "heading");
19+
elem.setAttribute("aria-level", "2");
20+
}
21+
// Similarly, don't treat the revision cells as headers.
22+
for (elem of side.querySelectorAll(".revision-col"))
23+
elem.setAttribute("role", "cell");
24+
25+
// For changed lines, prefix the right hand line number with off-screen text indicating the type of change.
26+
for (var tbody of side.querySelectorAll("tbody.insert,tbody.replace")) {
27+
for (var th of tbody.querySelectorAll("tr th:nth-child(3)"))
28+
th.innerHTML = '<span style="position: absolute; left: -10000px;">' + tbody.className + '</span> ' + th.innerHTML;
29+
}
30+
}
31+
32+
function onNodeAdded(target) {
33+
if (target.classList.contains("sidebyside"))
34+
tweakSideBySide(target);
35+
}
36+
37+
var observer = new MutationObserver(function(mutations) {
38+
for (var mutation of mutations) {
39+
try {
40+
if (mutation.type === "childList") {
41+
for (var node of mutation.addedNodes) {
42+
if (node.nodeType != Node.ELEMENT_NODE)
43+
continue;
44+
onNodeAdded(node);
45+
}
46+
}
47+
} catch (e) {
48+
// Catch exceptions for individual mutations so other mutations are still handled.
49+
GM_log("Exception while handling mutation: " + e);
50+
}
51+
}
52+
});
53+
observer.observe(document, {childList: true, subtree: true});

0 commit comments

Comments
 (0)