|
224 | 224 | } |
225 | 225 |
|
226 | 226 | function Widget(completion, data) { |
| 227 | + this.id = "cm-complete-" + Math.floor(Math.random(1e6)) |
227 | 228 | this.completion = completion; |
228 | 229 | this.data = data; |
229 | 230 | this.picked = false; |
|
232 | 233 | var parentWindow = ownerDocument.defaultView || ownerDocument.parentWindow; |
233 | 234 |
|
234 | 235 | var hints = this.hints = ownerDocument.createElement("ul"); |
| 236 | + hints.setAttribute("role", "listbox") |
| 237 | + hints.setAttribute("aria-expanded", "true") |
| 238 | + hints.id = this.id |
235 | 239 | var theme = completion.cm.options.theme; |
236 | 240 | hints.className = "CodeMirror-hints " + theme; |
237 | 241 | this.selectedHint = data.selectedHint || 0; |
|
242 | 246 | var className = HINT_ELEMENT_CLASS + (i != this.selectedHint ? "" : " " + ACTIVE_HINT_ELEMENT_CLASS); |
243 | 247 | if (cur.className != null) className = cur.className + " " + className; |
244 | 248 | elt.className = className; |
| 249 | + if (i == this.selectedHint) elt.setAttribute("aria-selected", "true") |
| 250 | + elt.id = this.id + "-" + i |
| 251 | + elt.setAttribute("role", "option") |
245 | 252 | if (cur.render) cur.render(elt, data, cur); |
246 | 253 | else elt.appendChild(ownerDocument.createTextNode(cur.displayText || getText(cur))); |
247 | 254 | elt.hintId = i; |
|
267 | 274 | var winW = parentWindow.innerWidth || Math.max(ownerDocument.body.offsetWidth, ownerDocument.documentElement.offsetWidth); |
268 | 275 | var winH = parentWindow.innerHeight || Math.max(ownerDocument.body.offsetHeight, ownerDocument.documentElement.offsetHeight); |
269 | 276 | 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) |
270 | 280 |
|
271 | 281 | var box = completion.options.moveOnOverlap ? hints.getBoundingClientRect() : new DOMRect(); |
272 | 282 | var scrolls = completion.options.paddingForScrollbar ? hints.scrollHeight > hints.clientHeight + 1 : false; |
|
364 | 374 | this.completion.widget = null; |
365 | 375 | if (this.hints.parentNode) this.hints.parentNode.removeChild(this.hints); |
366 | 376 | this.completion.cm.removeKeyMap(this.keyMap); |
| 377 | + var input = this.completion.cm.getInputField() |
| 378 | + input.removeAttribute("aria-activedescendant") |
| 379 | + input.removeAttribute("aria-owns") |
367 | 380 |
|
368 | 381 | var cm = this.completion.cm; |
369 | 382 | if (this.completion.options.closeOnUnfocus) { |
|
391 | 404 | i = avoidWrap ? 0 : this.data.list.length - 1; |
392 | 405 | if (this.selectedHint == i) return; |
393 | 406 | 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 | + } |
395 | 411 | node = this.hints.childNodes[this.selectedHint = i]; |
396 | 412 | node.className += " " + ACTIVE_HINT_ELEMENT_CLASS; |
| 413 | + node.setAttribute("aria-selected", "true") |
| 414 | + this.completion.cm.getInputField().setAttribute("aria-activedescendant", node.id) |
397 | 415 | this.scrollToActive() |
398 | 416 | CodeMirror.signal(this.data, "select", this.data.list[this.selectedHint], node); |
399 | 417 | }, |
|
0 commit comments