Skip to content

Commit 61f7707

Browse files
committed
Initial import of SimplenoteA11yFixes.
- Marks the Notes list as a labelled region. - Marks the note as the main landmark. - Marks the Search field as a search landmark. - Marks certain buttons that were previously just clickable text as buttons. Marks them as pressed if they are active. - Focuses the Pin to top check box when the Info pop-up appears.
1 parent 802cb04 commit 61f7707

File tree

1 file changed

+73
-0
lines changed

1 file changed

+73
-0
lines changed

SimplenoteA11yFixes.user.js

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// ==UserScript==
2+
// @name Simplenote Accessibility Fixes
3+
// @namespace http://axSGrease.nvaccess.org/
4+
// @description Improves the accessibility of Simplenote.
5+
// @author James Teh <jamie@nvaccess.org>
6+
// @copyright 2015 NV Access Limited
7+
// @license GNU General Public License version 2.0
8+
// @version 2015.1
9+
// @grant GM_log
10+
// @include https://app.simplenote.com/
11+
// ==/UserScript==
12+
13+
function init() {
14+
var elem;
15+
16+
if (elem = document.querySelector(".notes")) {
17+
// Notes list.
18+
elem.setAttribute("role", "list region");
19+
elem.setAttribute("aria-label", "Notes");
20+
}
21+
22+
if (elem = document.querySelector(".note")) // The note itself.
23+
elem.setAttribute("role", "main");
24+
25+
for (var elem of document.querySelectorAll(".button"))
26+
elem.setAttribute("role", "button");
27+
28+
if (elem = document.querySelector(".searchfield")) // Search box.
29+
elem.setAttribute("role", "search");
30+
}
31+
32+
function onNodeAdded(target) {
33+
var elem;
34+
35+
if (target.id === "details_form") {
36+
// The Info screen just appeared.
37+
// Focus the "Pin to top" check box (the first focusable item therein).
38+
if (elem = document.getElementById("details_pinned_chk"))
39+
elem.focus();
40+
}
41+
}
42+
43+
function onClassModified(target) {
44+
var classes = target.classList;
45+
if (!classes)
46+
return;
47+
if (classes.contains("button"))
48+
target.setAttribute("aria-pressed", classes.contains("active") ? "true" : "false");
49+
}
50+
51+
var observer = new MutationObserver(function(mutations) {
52+
for (var mutation of mutations) {
53+
try {
54+
if (mutation.type === "childList") {
55+
for (var node of mutation.addedNodes) {
56+
if (node.nodeType != Node.ELEMENT_NODE)
57+
continue;
58+
onNodeAdded(node);
59+
}
60+
} else if (mutation.type === "attributes") {
61+
if (mutation.attributeName == "class")
62+
onClassModified(mutation.target);
63+
}
64+
} catch (e) {
65+
// Catch exceptions for individual mutations so other mutations are still handled.
66+
GM_log("Exception while handling mutation: " + e);
67+
}
68+
}
69+
});
70+
observer.observe(document, {childList: true, attributes: true,
71+
subtree: true, attributeFilter: ["class"]});
72+
73+
init();

0 commit comments

Comments
 (0)