Skip to content

Commit 579e120

Browse files
committed
[show-hint addon] Set ARIA-related attributes for better screen reader support
1 parent bf786a0 commit 579e120

File tree

1 file changed

+19
-1
lines changed

1 file changed

+19
-1
lines changed

addon/hint/show-hint.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@
224224
}
225225

226226
function Widget(completion, data) {
227+
this.id = "cm-complete-" + Math.floor(Math.random(1e6))
227228
this.completion = completion;
228229
this.data = data;
229230
this.picked = false;
@@ -232,6 +233,9 @@
232233
var parentWindow = ownerDocument.defaultView || ownerDocument.parentWindow;
233234

234235
var hints = this.hints = ownerDocument.createElement("ul");
236+
hints.setAttribute("role", "listbox")
237+
hints.setAttribute("aria-expanded", "true")
238+
hints.id = this.id
235239
var theme = completion.cm.options.theme;
236240
hints.className = "CodeMirror-hints " + theme;
237241
this.selectedHint = data.selectedHint || 0;
@@ -242,6 +246,9 @@
242246
var className = HINT_ELEMENT_CLASS + (i != this.selectedHint ? "" : " " + ACTIVE_HINT_ELEMENT_CLASS);
243247
if (cur.className != null) className = cur.className + " " + className;
244248
elt.className = className;
249+
if (i == this.selectedHint) elt.setAttribute("aria-selected", "true")
250+
elt.id = this.id + "-" + i
251+
elt.setAttribute("role", "option")
245252
if (cur.render) cur.render(elt, data, cur);
246253
else elt.appendChild(ownerDocument.createTextNode(cur.displayText || getText(cur)));
247254
elt.hintId = i;
@@ -267,6 +274,9 @@
267274
var winW = parentWindow.innerWidth || Math.max(ownerDocument.body.offsetWidth, ownerDocument.documentElement.offsetWidth);
268275
var winH = parentWindow.innerHeight || Math.max(ownerDocument.body.offsetHeight, ownerDocument.documentElement.offsetHeight);
269276
container.appendChild(hints);
277+
cm.getInputField().setAttribute("aria-autocomplete", "list")
278+
cm.getInputField().setAttribute("aria-owns", this.id)
279+
cm.getInputField().setAttribute("aria-activedescendant", this.id + "-" + this.selectedHint)
270280

271281
var box = completion.options.moveOnOverlap ? hints.getBoundingClientRect() : new DOMRect();
272282
var scrolls = completion.options.paddingForScrollbar ? hints.scrollHeight > hints.clientHeight + 1 : false;
@@ -364,6 +374,9 @@
364374
this.completion.widget = null;
365375
if (this.hints.parentNode) this.hints.parentNode.removeChild(this.hints);
366376
this.completion.cm.removeKeyMap(this.keyMap);
377+
var input = this.completion.cm.getInputField()
378+
input.removeAttribute("aria-activedescendant")
379+
input.removeAttribute("aria-owns")
367380

368381
var cm = this.completion.cm;
369382
if (this.completion.options.closeOnUnfocus) {
@@ -391,9 +404,14 @@
391404
i = avoidWrap ? 0 : this.data.list.length - 1;
392405
if (this.selectedHint == i) return;
393406
var node = this.hints.childNodes[this.selectedHint];
394-
if (node) node.className = node.className.replace(" " + ACTIVE_HINT_ELEMENT_CLASS, "");
407+
if (node) {
408+
node.className = node.className.replace(" " + ACTIVE_HINT_ELEMENT_CLASS, "");
409+
node.removeAttribute("aria-selected")
410+
}
395411
node = this.hints.childNodes[this.selectedHint = i];
396412
node.className += " " + ACTIVE_HINT_ELEMENT_CLASS;
413+
node.setAttribute("aria-selected", "true")
414+
this.completion.cm.getInputField().setAttribute("aria-activedescendant", node.id)
397415
this.scrollToActive()
398416
CodeMirror.signal(this.data, "select", this.data.list[this.selectedHint], node);
399417
},

0 commit comments

Comments
 (0)