- commit
- c2268727f934d830276b5cdde18e1d261864d830
- parent
- d1e55b782fec41c41d3f77fd6cc46c4d6acd9196
- Author
- Tobias Bengfort <tobias.bengfort@posteo.de>
- Date
- 2024-11-01 12:46
bump version to 0.8.0
Diffstat
| M | CHANGES.md | 10 | ++++++++++ |
| M | dist/aria.js | 2458 | ++++++++++++++++++++++++++++++------------------------------- |
| M | package.json | 2 | +- |
3 files changed, 1224 insertions, 1246 deletions
diff --git a/CHANGES.md b/CHANGES.md
@@ -1,3 +1,13 @@ -1 1 0.8.0 (2024-11-01) -1 2 ------------------ -1 3 -1 4 - Convert the source code to ES modules. `dist/aria.js` is still an UMD bundle. -1 5 - The internal re-exports `query.getRole()` and `query.getAttribute()` have -1 6 been removed. Use the corresponding exports from `attrs` instead. -1 7 - fix: support `xlink:href` on `<area>` elements -1 8 - fix: consider `text-transform` in `getName()` and `getDescription()` -1 9 -1 10 1 11 0.7.0 (2024-06-22) 2 12 ------------------ 3 13
diff --git a/dist/aria.js b/dist/aria.js
@@ -1,1325 +1,1293 @@1 -1 (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.aria = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){2 -1 var query = require('./lib/query.js');3 -1 var name = require('./lib/name.js');4 -1 var atree = require('./lib/atree.js');5 -16 -1 module.exports = {7 -1 getRole: query.getRole,8 -1 getAttribute: query.getAttribute,9 -1 getName: name.getName,10 -1 getDescription: name.getDescription,11 -112 -1 matches: query.matches,13 -1 querySelector: query.querySelector,14 -1 querySelectorAll: query.querySelectorAll,15 -1 closest: query.closest,16 -117 -1 getParentNode: atree.getParentNode,18 -1 getChildNodes: atree.getChildNodes,19 -1 };20 -121 -1 },{"./lib/atree.js":2,"./lib/name.js":5,"./lib/query.js":6}],2:[function(require,module,exports){22 -1 const attrs = require('./attrs');23 -124 -1 const _getOwner = function(node, owners) {25 -1 if (node.nodeType === node.ELEMENT_NODE && node.id) {26 -1 const selector = '[aria-owns~="' + CSS.escape(node.id) + '"]';27 -1 if (owners) {28 -1 for (const owner of owners) {29 -1 if (owner.matches(selector)) {30 -1 return owner;31 -1 }32 -1 }33 -1 } else {34 -1 return document.querySelector(selector);35 -1 }36 -1 }37 -1 };-1 1 (function (global, factory) { -1 2 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : -1 3 typeof define === 'function' && define.amd ? define(['exports'], factory) : -1 4 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.aria = {})); -1 5 })(this, (function (exports) { 'use strict'; -1 6 -1 7 // https://www.w3.org/TR/wai-aria/#state_prop_def -1 8 const attributes = { -1 9 'activedescendant': 'id', -1 10 'atomic': 'bool', -1 11 'autocomplete': 'token', -1 12 'braillelabel': 'string', -1 13 'brailleroledescription': 'string', -1 14 'busy': 'bool', -1 15 'checked': 'tristate', -1 16 'colcount': 'int', -1 17 'colindex': 'int', -1 18 'colindextext': 'string', -1 19 'colspan': 'int', -1 20 'controls': 'id-list', -1 21 'current': 'token', -1 22 'describedby': 'id-list', -1 23 'description': 'string', -1 24 'details': 'id', -1 25 'disabled': 'bool', -1 26 'dropeffect': 'token-list', -1 27 'errormessage': 'id', -1 28 'expanded': 'bool-undefined', -1 29 'flowto': 'id-list', -1 30 'grabbed': 'bool-undefined', -1 31 'haspopup': 'token', -1 32 'hidden': 'bool-undefined', -1 33 'invalid': 'token', -1 34 'keyshortcuts': 'string', -1 35 'label': 'string', -1 36 'labelledby': 'id-list', -1 37 'level': 'int', -1 38 'live': 'token', -1 39 'modal': 'bool', -1 40 'multiline': 'bool', -1 41 'multiselectable': 'bool', -1 42 'orientation': 'token', -1 43 'owns': 'id-list', -1 44 'placeholder': 'string', -1 45 'posinset': 'int', -1 46 'pressed': 'tristate', -1 47 'readonly': 'bool', -1 48 'relevant': 'token-list', -1 49 'required': 'bool', -1 50 'roledescription': 'string', -1 51 'rowcount': 'int', -1 52 'rowindex': 'int', -1 53 'rowindextext': 'string', -1 54 'rowspan': 'int', -1 55 'selected': 'bool-undefined', -1 56 'setsize': 'int', -1 57 'sort': 'token', -1 58 'valuemax': 'number', -1 59 'valuemin': 'number', -1 60 'valuenow': 'number', -1 61 'valuetext': 'string', -1 62 }; 38 6339 -1 const _getParentNode = function(node, owners) {40 -1 return _getOwner(node, owners) || node.parentNode;41 -1 };-1 64 const attributeStrongMapping = { -1 65 'disabled': 'disabled', -1 66 'placeholder': 'placeholder', -1 67 'readonly': 'readOnly', -1 68 'required': 'required', -1 69 }; 42 7043 -1 const detectLoop = function(node, owners) {44 -1 const seen = [node];45 -1 while ((node = _getParentNode(node, owners))) {46 -1 if (seen.includes(node)) {47 -1 return true;48 -1 }49 -1 seen.push(node);50 -1 }51 -1 };-1 71 const attributeWeakMapping = { -1 72 'checked': 'checked', -1 73 'colspan': 'colSpan', -1 74 'expanded': 'open', -1 75 'multiselectable': 'multiple', -1 76 'rowspan': 'rowSpan', -1 77 'selected': 'selected', -1 78 }; 52 7953 -1 const getOwner = function(node, owners) {54 -1 const owner = _getOwner(node, owners);55 -1 if (owner && !detectLoop(node, owners)) {56 -1 return owner;57 -1 }58 -1 };-1 80 // https://www.w3.org/TR/html/dom.html#sectioning-content-2 -1 81 const scoped = ['article *', 'aside *', 'nav *', 'section *'].join(','); -1 82 -1 83 const svgSelectors = function(selector) { -1 84 return [ -1 85 // `${selector}:has(> title:not(:empty))`, -1 86 // `${selector}:has(> desc:not(:empty))`, -1 87 `${selector}[aria-label]`, -1 88 `${selector}[aria-roledescription]`, -1 89 `${selector}[aria-labelledby]`, -1 90 `${selector}[aria-describedby]`, -1 91 `${selector}[tabindex]`, -1 92 `${selector}[role]`, -1 93 ]; -1 94 }; -1 95 -1 96 // https://www.w3.org/TR/html-aam-1.0/#html-element-role-mappings -1 97 // https://www.w3.org/TR/wai-aria/roles -1 98 const roles = { -1 99 alert: { -1 100 childRoles: ['alertdialog'], -1 101 defaults: { -1 102 'live': 'assertive', -1 103 'atomic': true, -1 104 }, -1 105 }, -1 106 alertdialog: {}, -1 107 application: {}, -1 108 article: { -1 109 selectors: ['article'], -1 110 childRoles: ['comment'], -1 111 }, -1 112 banner: { -1 113 selectors: [`header:not(main *, ${scoped})`], -1 114 }, -1 115 blockquote: { -1 116 selectors: ['blockquote'], -1 117 }, -1 118 button: { -1 119 selectors: [ -1 120 'button', -1 121 'input[type="button"]', -1 122 'input[type="image"]', -1 123 'input[type="reset"]', -1 124 'input[type="submit"]', -1 125 'summary', -1 126 ], -1 127 nameFromContents: true, -1 128 }, -1 129 caption: { -1 130 selectors: ['caption', 'figcaption'], -1 131 }, -1 132 cell: { -1 133 selectors: ['td', 'td ~ th:not([scope])'], -1 134 childRoles: ['columnheader', 'gridcell', 'rowheader'], -1 135 nameFromContents: true, -1 136 }, -1 137 checkbox: { -1 138 selectors: ['input[type="checkbox"]'], -1 139 childRoles: ['switch'], -1 140 nameFromContents: true, -1 141 defaults: { -1 142 'checked': 'false', -1 143 }, -1 144 }, -1 145 code: { -1 146 selectors: ['code'], -1 147 }, -1 148 columnheader: { -1 149 selectors: ['th[scope="col"]'], -1 150 nameFromContents: true, -1 151 }, -1 152 combobox: { -1 153 selectors: [ -1 154 'input:not([type])[list]', -1 155 'input[type="email"][list]', -1 156 'input[type="search"][list]', -1 157 'input[type="tel"][list]', -1 158 'input[type="text"][list]', -1 159 'input[type="url"][list]', -1 160 'select:not([size]):not([multiple])', -1 161 'select[size="0"]:not([multiple])', -1 162 'select[size="1"]:not([multiple])', -1 163 ], -1 164 defaults: { -1 165 'expanded': false, -1 166 'haspopup': 'listbox', -1 167 }, -1 168 }, -1 169 command: { -1 170 abstract: true, -1 171 childRoles: ['button', 'link', 'menuitem'], -1 172 }, -1 173 comment: { -1 174 nameFromContents: true, -1 175 }, -1 176 complementary: { -1 177 selectors: [ -1 178 `aside:not(${scoped})`, -1 179 'aside[aria-label]', -1 180 'aside[aria-labelledby]', -1 181 'aside[title]', -1 182 ], -1 183 }, -1 184 composite: { -1 185 abstract: true, -1 186 childRoles: ['grid', 'select', 'spinbutton', 'tablist'], -1 187 }, -1 188 contentinfo: { -1 189 selectors: [`footer:not(main *, ${scoped})`], -1 190 }, -1 191 definition: { -1 192 selectors: ['dd'], -1 193 }, -1 194 deletion: { -1 195 selectors: ['del', 's'], -1 196 }, -1 197 dialog: { -1 198 selectors: ['dialog'], -1 199 childRoles: ['alertdialog'], -1 200 }, -1 201 'doc-abstract': {}, -1 202 'doc-acknowledgments': {}, -1 203 'doc-afterword': {}, -1 204 'doc-appendix': {}, -1 205 'doc-backlink': { -1 206 nameFromContents: true, -1 207 }, -1 208 'doc-biblioentry': {}, -1 209 'doc-bibliography': {}, -1 210 'doc-biblioref': { -1 211 nameFromContents: true, -1 212 }, -1 213 'doc-chapter': {}, -1 214 'doc-colophon': {}, -1 215 'doc-conclusion': {}, -1 216 'doc-cover': {}, -1 217 'doc-credit': {}, -1 218 'doc-credits': {}, -1 219 'doc-dedication': {}, -1 220 'doc-endnote': {}, -1 221 'doc-endnotes': {}, -1 222 'doc-epilogue': {}, -1 223 'doc-epigraph': {}, -1 224 'doc-errata': {}, -1 225 'doc-example': {}, -1 226 'doc-footnote': {}, -1 227 'doc-foreword': {}, -1 228 'doc-glossary': {}, -1 229 'doc-glossref': { -1 230 nameFromContents: true, -1 231 }, -1 232 'doc-index': {}, -1 233 'doc-introduction': {}, -1 234 'doc-noteref': { -1 235 nameFromContents: true, -1 236 }, -1 237 'doc-notice': {}, -1 238 'doc-pagebreak': { -1 239 nameFromContents: true, -1 240 }, -1 241 'doc-pagefooter': {}, -1 242 'doc-pageheader': {}, -1 243 'doc-pagelist': {}, -1 244 'doc-part': {}, -1 245 'doc-preface': {}, -1 246 'doc-prologue': {}, -1 247 'doc-pullquote': {}, -1 248 'doc-qna': {}, -1 249 'doc-subtitle': { -1 250 nameFromContents: true, -1 251 }, -1 252 'doc-tip': {}, -1 253 'doc-toc': {}, -1 254 document: { -1 255 selectors: ['html'], -1 256 childRoles: ['article', 'graphics-document'], -1 257 }, -1 258 emphasis: { -1 259 selectors: ['em'], -1 260 }, -1 261 feed: {}, -1 262 figure: { -1 263 selectors: ['figure'], -1 264 childRoles: ['doc-example'], -1 265 }, -1 266 form: { -1 267 selectors: ['form[aria-label]', 'form[aria-labelledby]', 'form[title]'], -1 268 }, -1 269 generic: { -1 270 selectors: [ -1 271 'a:not([*|href])', -1 272 'area:not([*|href])', -1 273 `aside:not(${scoped}):not([aria-label]):not([aria-labelledby]):not([title])`, -1 274 'b', -1 275 'bdi', -1 276 'bdo', -1 277 'body', -1 278 'data', -1 279 'div', -1 280 // footer scoped -1 281 // header scoped -1 282 'i', -1 283 'li:not(ul > li):not(ol > li)', -1 284 'pre', -1 285 'q', -1 286 'samp', -1 287 'section:not([aria-label]):not([aria-labelledby]):not([title])', -1 288 'small', -1 289 'span', -1 290 'u', -1 291 ], -1 292 }, -1 293 'graphics-document': { -1 294 selectors: ['svg'], -1 295 }, -1 296 'graphics-object': { -1 297 selectors: [ -1 298 ...svgSelectors('symbol'), -1 299 ...svgSelectors('use'), -1 300 ], -1 301 }, -1 302 'graphics-symbol': { -1 303 selectors: [ -1 304 ...svgSelectors('circle'), -1 305 ...svgSelectors('ellipse'), -1 306 ...svgSelectors('line'), -1 307 ...svgSelectors('path'), -1 308 ...svgSelectors('polygon'), -1 309 ...svgSelectors('polyline'), -1 310 ...svgSelectors('rect'), -1 311 ], -1 312 }, -1 313 grid: { -1 314 childRoles: ['treegrid'], -1 315 }, -1 316 gridcell: { -1 317 childRoles: ['columnheader', 'rowheader'], -1 318 nameFromContents: true, -1 319 }, -1 320 group: { -1 321 selectors: [ -1 322 'address', -1 323 'details', -1 324 'fieldset', -1 325 'hgroup', -1 326 'optgroup', -1 327 ...svgSelectors('foreignObject'), -1 328 ...svgSelectors('g'), -1 329 'text', -1 330 ...svgSelectors('textPath'), -1 331 ...svgSelectors('tspan'), -1 332 ], -1 333 childRoles: ['row', 'select', 'toolbar', 'graphics-object'], -1 334 }, -1 335 heading: { -1 336 selectors: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'], -1 337 nameFromContents: true, -1 338 defaults: { -1 339 'level': 2, -1 340 }, -1 341 }, -1 342 image: { -1 343 selectors: [ -1 344 'img:not([alt=""])', -1 345 'graphics-symbol', -1 346 ...svgSelectors('image'), -1 347 ...svgSelectors('mesh'), -1 348 ], -1 349 childRoles: ['doc-cover'], -1 350 }, -1 351 input: { -1 352 abstract: true, -1 353 childRoles: [ -1 354 'checkbox', -1 355 'combobox', -1 356 'option', -1 357 'radio', -1 358 'slider', -1 359 'spinbutton', -1 360 'textbox', -1 361 ], -1 362 }, -1 363 insertion: { -1 364 selectors: ['ins'], -1 365 }, -1 366 landmark: { -1 367 abstract: true, -1 368 childRoles: [ -1 369 'banner', -1 370 'complementary', -1 371 'contentinfo', -1 372 'doc-acknowledgments', -1 373 'doc-afterword', -1 374 'doc-appendix', -1 375 'doc-bibliography', -1 376 'doc-chapter', -1 377 'doc-conclusion', -1 378 'doc-credits', -1 379 'doc-endnotes', -1 380 'doc-epilogue', -1 381 'doc-errata', -1 382 'doc-foreword', -1 383 'doc-glossary', -1 384 'doc-introduction', -1 385 'doc-part', -1 386 'doc-preface', -1 387 'doc-prologue', -1 388 'form', -1 389 'main', -1 390 'navigation', -1 391 'region', -1 392 'search', -1 393 ], -1 394 }, -1 395 link: { -1 396 selectors: ['a[*|href]', 'area[*|href]'], -1 397 childRoles: ['doc-backlink', 'doc-biblioref', 'doc-glossref', 'doc-noteref'], -1 398 nameFromContents: true, -1 399 }, -1 400 list: { -1 401 selectors: ['dl', 'ol', 'ul', 'menu'], -1 402 childRoles: ['feed'], -1 403 }, -1 404 listbox: { -1 405 selectors: [ -1 406 'datalist', -1 407 'select[multiple]', -1 408 'select[size]:not([size="0"]):not([size="1"])', -1 409 ], -1 410 defaults: { -1 411 'orientation': 'vertical', -1 412 }, -1 413 }, -1 414 listitem: { -1 415 selectors: ['ol > li', 'ul > li'], -1 416 childRoles: ['doc-biblioentry', 'doc-endnote', 'treeitem'], -1 417 }, -1 418 log: { -1 419 defaults: { -1 420 'live': 'polite', -1 421 }, -1 422 }, -1 423 main: { -1 424 selectors: ['main'], -1 425 }, -1 426 mark: { -1 427 selectors: ['mark'], -1 428 }, -1 429 marquee: {}, -1 430 math: { -1 431 selectors: ['math'], -1 432 }, -1 433 meter: { -1 434 selectors: ['meter'], -1 435 defaults: { -1 436 'valuemin': 0, -1 437 'valuemax': 100, -1 438 }, -1 439 }, -1 440 menu: { -1 441 childRoles: ['menubar'], -1 442 defaults: { -1 443 'orientation': 'vertical', -1 444 }, -1 445 }, -1 446 menubar: { -1 447 defaults: { -1 448 'orientation': 'horizontal', -1 449 }, -1 450 }, -1 451 menuitem: { -1 452 childRoles: ['menuitemcheckbox', 'menuitemradio'], -1 453 nameFromContents: true, -1 454 }, -1 455 menuitemcheckbox: { -1 456 nameFromContents: true, -1 457 defaults: { -1 458 'checked': 'false', -1 459 }, -1 460 }, -1 461 menuitemradio: { -1 462 nameFromContents: true, -1 463 defaults: { -1 464 'checked': 'false', -1 465 }, -1 466 }, -1 467 navigation: { -1 468 selectors: ['nav'], -1 469 childRoles: ['doc-index', 'doc-pagelist', 'doc-toc'], -1 470 }, -1 471 none: { -1 472 selectors: ['img[alt=""]'], -1 473 }, -1 474 note: { -1 475 childRoles: ['doc-notice', 'doc-tip'], -1 476 }, -1 477 option: { -1 478 selectors: ['option'], -1 479 childRoles: ['treeitem'], -1 480 nameFromContents: true, -1 481 defaults: { -1 482 'selected': 'false', -1 483 }, -1 484 }, -1 485 paragraph: { -1 486 selectors: ['p'], -1 487 }, -1 488 progressbar: { -1 489 selectors: ['progress'], -1 490 defaults: { -1 491 'valuemin': 0, -1 492 'valuemax': 100, -1 493 }, -1 494 }, -1 495 radio: { -1 496 selectors: ['input[type="radio"]'], -1 497 childRoles: ['menuitemradio'], -1 498 nameFromContents: true, -1 499 defaults: { -1 500 'checked': 'false', -1 501 }, -1 502 }, -1 503 radiogroup: {}, -1 504 range: { -1 505 abstract: true, -1 506 childRoles: ['meter', 'progressbar', 'scrollbar', 'slider', 'spinbutton'], -1 507 }, -1 508 region: { -1 509 selectors: ['section[aria-label]', 'section[aria-labelledby]', 'section[title]'], -1 510 }, -1 511 roletype: { -1 512 abstract: true, -1 513 childRoles: ['structure', 'widget', 'window'], -1 514 }, -1 515 row: { -1 516 selectors: ['tr'], -1 517 nameFromContents: true, -1 518 }, -1 519 rowgroup: { -1 520 selectors: ['tbody', 'thead', 'tfoot'], -1 521 }, -1 522 rowheader: { -1 523 selectors: ['th[scope="row"]', 'th:not([scope]):not(td ~ th)'], -1 524 nameFromContents: true, -1 525 }, -1 526 scrollbar: { -1 527 defaults: { -1 528 'orientation': 'vertical', -1 529 'valuemin': 0, -1 530 'valuemax': 100, -1 531 }, -1 532 }, -1 533 search: { -1 534 selectors: ['search'], -1 535 }, -1 536 searchbox: { -1 537 selectors: ['input[type="search"]:not([list])'], -1 538 }, -1 539 section: { -1 540 abstract: true, -1 541 childRoles: [ -1 542 'alert', -1 543 'blockquote', -1 544 'caption', -1 545 'cell', -1 546 'code', -1 547 'definition', -1 548 'deletion', -1 549 'doc-abstract', -1 550 'doc-colophon', -1 551 'doc-credit', -1 552 'doc-dedication', -1 553 'doc-epigraph', -1 554 'doc-footnote', -1 555 'doc-pagefooter', -1 556 'doc-pageheader', -1 557 'doc-pullquote', -1 558 'doc-qna', -1 559 'emphasis', -1 560 'figure', -1 561 'group', -1 562 'image', -1 563 'insertion', -1 564 'landmark', -1 565 'list', -1 566 'listitem', -1 567 'log', -1 568 'mark', -1 569 'marquee', -1 570 'math', -1 571 'note', -1 572 'paragraph', -1 573 'status', -1 574 'strong', -1 575 'subscript', -1 576 'suggestion', -1 577 'superscript', -1 578 'table', -1 579 'tabpanel', -1 580 'term', -1 581 'time', -1 582 'tooltip', -1 583 ], -1 584 }, -1 585 sectionhead: { -1 586 abstract: true, -1 587 childRoles: [ -1 588 'columnheader', -1 589 'doc-subtitle', -1 590 'heading', -1 591 'rowheader', -1 592 'tab', -1 593 ], -1 594 nameFromContents: true, -1 595 }, -1 596 select: { -1 597 abstract: true, -1 598 childRoles: ['listbox', 'menu', 'radiogroup', 'tree'], -1 599 }, -1 600 separator: { -1 601 // assume not focussable because <hr> is not -1 602 selectors: ['hr'], -1 603 childRoles: ['doc-pagebreak'], -1 604 defaults: { -1 605 'orientation': 'horizontal', -1 606 'valuemin': 0, -1 607 'valuemax': 100, -1 608 }, -1 609 }, -1 610 slider: { -1 611 selectors: ['input[type="range"]'], -1 612 defaults: { -1 613 'orientation': 'horizontal', -1 614 'valuemin': 0, -1 615 'valuemax': 100, -1 616 // FIXME: halfway between actual valuemin and valuemax -1 617 'valuenow': 50, -1 618 }, -1 619 }, -1 620 spinbutton: { -1 621 selectors: ['input[type="number"]'], -1 622 defaults: { -1 623 // FIXME: no valuemin/valuemax/valuenow -1 624 }, -1 625 }, -1 626 status: { -1 627 selectors: ['output'], -1 628 childRoles: ['timer'], -1 629 defaults: { -1 630 'live': 'polite', -1 631 'atomic': true, -1 632 }, -1 633 }, -1 634 strong: { -1 635 selectors: ['strong'], -1 636 }, -1 637 structure: { -1 638 abstract: true, -1 639 childRoles: [ -1 640 'application', -1 641 'document', -1 642 'none', -1 643 'generic', -1 644 'range', -1 645 'rowgroup', -1 646 'section', -1 647 'sectionhead', -1 648 'separator', -1 649 ], -1 650 }, -1 651 suggestion: {}, -1 652 subscript: { -1 653 selectors: ['sub'], -1 654 }, -1 655 superscript: { -1 656 selectors: ['sup'], -1 657 }, -1 658 switch: { -1 659 nameFromContents: true, -1 660 defaults: { -1 661 'checked': false, -1 662 }, -1 663 }, -1 664 tab: { -1 665 nameFromContents: true, -1 666 defaults: { -1 667 'selected': false, -1 668 }, -1 669 }, -1 670 table: { -1 671 selectors: ['table'], -1 672 childRoles: ['grid'], -1 673 }, -1 674 tablist: { -1 675 defaults: { -1 676 'orientation': 'horizontal', -1 677 }, -1 678 }, -1 679 tabpanel: {}, -1 680 term: { -1 681 selectors: ['dfn', 'dt'], -1 682 }, -1 683 textbox: { -1 684 selectors: [ -1 685 'input:not([type]):not([list])', -1 686 'input[type="email"]:not([list])', -1 687 'input[type="tel"]:not([list])', -1 688 'input[type="text"]:not([list])', -1 689 'input[type="url"]:not([list])', -1 690 'textarea', -1 691 ], -1 692 childRoles: ['searchbox'], -1 693 }, -1 694 time: { -1 695 selectors: ['time'], -1 696 }, -1 697 timer: { -1 698 defaults: { -1 699 'live': 'off', -1 700 }, -1 701 }, -1 702 toolbar: { -1 703 defaults: { -1 704 'orientation': 'horizontal', -1 705 }, -1 706 }, -1 707 tooltip: { -1 708 nameFromContents: true, -1 709 }, -1 710 tree: { -1 711 childRoles: ['treegrid'], -1 712 defaults: { -1 713 'orientation': 'vertical', -1 714 }, -1 715 }, -1 716 treegrid: {}, -1 717 treeitem: { -1 718 nameFromContents: true, -1 719 }, -1 720 widget: { -1 721 abstract: true, -1 722 childRoles: [ -1 723 'command', -1 724 'composite', -1 725 'gridcell', -1 726 'input', -1 727 'progressbar', -1 728 'row', -1 729 'scrollbar', -1 730 'separator', -1 731 'tab', -1 732 ], -1 733 }, -1 734 window: { -1 735 abstract: true, -1 736 childRoles: ['dialog'], -1 737 }, -1 738 }; 59 73960 -1 const getParentNode = function(node, owners) {61 -1 return getOwner(node, owners) || node.parentNode;62 -1 };-1 740 const getSubRoles = function(role) { -1 741 const children = (roles[role]).childRoles || []; -1 742 const descendents = children.map(getSubRoles); 63 74364 -1 const isHidden = function(node) {65 -1 return node.nodeType === node.ELEMENT_NODE && attrs.getAttribute(node, 'hidden');66 -1 };-1 744 const result = [role]; 67 74568 -1 const getChildNodes = function(node, owners) {69 -1 const childNodes = [];-1 746 descendents.forEach(list => { -1 747 list.forEach(r => { -1 748 if (!result.includes(r)) { -1 749 result.push(r); -1 750 } -1 751 }); -1 752 }); 70 75371 -1 for (let i = 0; i < node.childNodes.length; i++) {72 -1 const child = node.childNodes[i];73 -1 if (!getOwner(child, owners) && !isHidden(child)) {74 -1 childNodes.push(child);75 -1 }76 -1 }-1 754 return result; -1 755 }; 77 75678 -1 if (node.nodeType === node.ELEMENT_NODE) {79 -1 const owns = attrs.getAttribute(node, 'owns') || [];80 -1 for (let i = 0; i < owns.length; i++) {81 -1 const child = document.getElementById(owns[i]);82 -1 // double check with getOwner for consistency83 -1 if (child && getOwner(child, owners) === node && !isHidden(child)) {84 -1 childNodes.push(child);-1 757 const attrsWithDefaults = []; -1 758 -1 759 for (const role in roles) { -1 760 roles[role].subRoles = getSubRoles(role); -1 761 for (const key in roles[role].defaults) { -1 762 if (!attrsWithDefaults.includes(key)) { -1 763 attrsWithDefaults.push(key); 85 764 } 86 765 } 87 766 } 88 76789 -1 return childNodes;90 -1 };-1 768 const aliases = { -1 769 'presentation': 'none', -1 770 'directory': 'list', -1 771 'img': 'image', -1 772 }; -1 773 -1 774 const nameFromDescendant = { -1 775 'figure': 'figcaption', -1 776 'table': 'caption', -1 777 'fieldset': 'legend', -1 778 }; 91 77992 -1 const walk = function(root, fn) {93 -1 const owners = document.querySelectorAll('[aria-owns]');94 -1 let queue = [root];95 -1 while (queue.length) {96 -1 const item = queue.shift();97 -1 fn(item);98 -1 queue = getChildNodes(item, owners).concat(queue);99 -1 }100 -1 };-1 780 const nameDefaults = { -1 781 'input[type="submit"]': 'Submit', -1 782 'input[type="reset"]': 'Reset', -1 783 'summary': 'Details', -1 784 }; 101 785102 -1 const searchUp = function(node, test) {103 -1 const candidate = getParentNode(node);104 -1 if (candidate) {105 -1 if (test(candidate)) {106 -1 return candidate;-1 786 var unique = function(arr) { -1 787 return arr.filter((a, i) => arr.indexOf(a) === i); -1 788 }; -1 789 -1 790 var flatten = function(arr) { -1 791 return [].concat.apply([], arr); -1 792 }; -1 793 -1 794 var normalizeRoles = function(roles$1, includeAbstract) { -1 795 return unique(roles$1 -1 796 .map(r => aliases[r] || r) -1 797 .filter(r => roles[r]) -1 798 .filter(r => includeAbstract || !roles[r].abstract) -1 799 ); -1 800 }; -1 801 -1 802 // candidates can be passed for performance optimization -1 803 const getRoleRaw = function(el, candidates) { -1 804 // TODO: filter out any invalid roles (e.g. name or context required) -1 805 const roles$1 = normalizeRoles( -1 806 (el.getAttribute('role') || '').toLowerCase().split(/\s+/) -1 807 ); -1 808 -1 809 if (roles$1.length > 1 && candidates) { -1 810 return [roles$1, candidates]; -1 811 } else if (roles$1.length) { -1 812 for (const role of roles$1) { -1 813 if (!candidates || candidates.includes(role)) { -1 814 return role; -1 815 } -1 816 } 107 817 } else {108 -1 return searchUp(candidate, test);-1 818 for (const role of (candidates || Object.keys(roles))) { -1 819 const r = roles[role]; -1 820 if (!r.abstract && r.selectors && el.matches(r.selectors.join(','))) { -1 821 return role; -1 822 } -1 823 } 109 824 }110 -1 }111 -1 };112 -1113 -1 module.exports = {114 -1 'getParentNode': getParentNode,115 -1 'getChildNodes': getChildNodes,116 -1 'walk': walk,117 -1 'searchUp': searchUp,118 -1 };119 -1120 -1 },{"./attrs":3}],3:[function(require,module,exports){121 -1 const constants = require('./constants.js');122 -1123 -1 var unique = function(arr) {124 -1 return arr.filter((a, i) => arr.indexOf(a) === i);125 -1 };126 -1127 -1 var flatten = function(arr) {128 -1 return [].concat.apply([], arr);129 -1 };130 -1131 -1 var normalizeRoles = function(roles, includeAbstract) {132 -1 return unique(roles133 -1 .map(r => constants.aliases[r] || r)134 -1 .filter(r => constants.roles[r])135 -1 .filter(r => includeAbstract || !constants.roles[r].abstract)136 -1 );137 -1 };138 -1139 -1 // candidates can be passed for performance optimization140 -1 const getRole = function(el, candidates) {141 -1 // TODO: filter out any invalid roles (e.g. name or context required)142 -1 const roles = normalizeRoles(143 -1 (el.getAttribute('role') || '').toLowerCase().split(/\s+/)144 -1 );145 -1146 -1 if (roles.length > 1 && candidates) {147 -1 return [roles, candidates];148 -1 } else if (roles.length) {149 -1 for (const role of roles) {150 -1 if (!candidates || candidates.includes(role)) {151 -1 return role;-1 825 }; -1 826 -1 827 const getRole = function(el) { -1 828 return getRoleRaw(el); -1 829 }; -1 830 -1 831 const hasRole = function(el, roles$1) { -1 832 const subRoles = normalizeRoles(roles$1, true).map(role => { -1 833 return roles[role].subRoles || [role]; -1 834 }); -1 835 return !!getRoleRaw(el, unique(flatten(subRoles))); -1 836 }; -1 837 -1 838 const getAttribute = function(el, key) { -1 839 if (attributeStrongMapping.hasOwnProperty(key)) { -1 840 const value = el[attributeStrongMapping[key]]; -1 841 if (value) { -1 842 return value; 152 843 } 153 844 }154 -1 } else {155 -1 for (const role of (candidates || Object.keys(constants.roles))) {156 -1 const r = constants.roles[role];157 -1 if (!r.abstract && r.selectors && el.matches(r.selectors.join(','))) {158 -1 return role;-1 845 if (key === 'readonly' && el.contentEditable) { -1 846 return false; -1 847 } else if (key === 'invalid' && el.checkValidity) { -1 848 return !el.checkValidity(); -1 849 } else if (key === 'hidden') { -1 850 // workaround for chromium -1 851 if (el.matches('noscript')) { -1 852 return true; -1 853 } -1 854 if (el.matches('details:not([open]) > :not(summary)')) { -1 855 return true; -1 856 } -1 857 const style = window.getComputedStyle(el); -1 858 if (style.display === 'none' || style.visibility === 'hidden' || style.visibility === 'collapse') { -1 859 return true; 159 860 } 160 861 }161 -1 }162 -1 };163 -1164 -1 const hasRole = function(el, roles) {165 -1 const subRoles = normalizeRoles(roles, true).map(role => {166 -1 return constants.roles[role].subRoles || [role];167 -1 });168 -1 return !!getRole(el, unique(flatten(subRoles)));169 -1 };170 -1171 -1 const getAttribute = function(el, key) {172 -1 if (constants.attributeStrongMapping.hasOwnProperty(key)) {173 -1 const value = el[constants.attributeStrongMapping[key]];174 -1 if (value) {175 -1 return value;-1 862 -1 863 const type = attributes[key]; -1 864 const raw = el.getAttribute('aria-' + key); -1 865 -1 866 if (raw) { -1 867 if (type === 'bool') { -1 868 return raw === 'true'; -1 869 } else if (type === 'tristate') { -1 870 return raw === 'true' ? true : raw === 'false' ? false : 'mixed'; -1 871 } else if (type === 'bool-undefined') { -1 872 return raw === 'true' ? true : raw === 'false' ? false : undefined; -1 873 } else if (type === 'id-list') { -1 874 return raw.split(/\s+/); -1 875 } else if (type === 'integer') { -1 876 return parseInt(raw, 10); -1 877 } else if (type === 'number') { -1 878 return parseFloat(raw); -1 879 } else if (type === 'token-list') { -1 880 return raw.split(/\s+/); -1 881 } else { -1 882 return raw; -1 883 } 176 884 }177 -1 }178 -1 if (key === 'readonly' && el.contentEditable) {179 -1 return false;180 -1 } else if (key === 'invalid' && el.checkValidity) {181 -1 return !el.checkValidity();182 -1 } else if (key === 'hidden') {183 -1 // workaround for chromium184 -1 if (el.matches('noscript')) {185 -1 return true;-1 885 -1 886 // TODO -1 887 // autocomplete -1 888 // contextmenu -> aria-haspopup -1 889 // indeterminate -> aria-checked="mixed" -1 890 // list -> aria-controls -1 891 -1 892 if (key === 'level') { -1 893 for (let i = 1; i <= 6; i++) { -1 894 if (el.tagName.toLowerCase() === 'h' + i) { -1 895 return i; -1 896 } -1 897 } -1 898 } else if (attributeWeakMapping.hasOwnProperty(key)) { -1 899 return el[attributeWeakMapping[key]]; 186 900 }187 -1 if (el.matches('details:not([open]) > :not(summary)')) {188 -1 return true;-1 901 -1 902 if (key in attrsWithDefaults) { -1 903 const role = getRole(el); -1 904 const defaults = roles[role].defaults; -1 905 if (defaults && defaults.hasOwnProperty(key)) { -1 906 return defaults[key]; -1 907 } 189 908 }190 -1 const style = window.getComputedStyle(el);191 -1 if (style.display === 'none' || style.visibility === 'hidden' || style.visibility === 'collapse') {192 -1 return true;-1 909 -1 910 if (type === 'bool' || type === 'tristate') { -1 911 return false; 193 912 }194 -1 }-1 913 }; 195 914196 -1 const type = constants.attributes[key];197 -1 const raw = el.getAttribute('aria-' + key);198 -1199 -1 if (raw) {200 -1 if (type === 'bool') {201 -1 return raw === 'true';202 -1 } else if (type === 'tristate') {203 -1 return raw === 'true' ? true : raw === 'false' ? false : 'mixed';204 -1 } else if (type === 'bool-undefined') {205 -1 return raw === 'true' ? true : raw === 'false' ? false : undefined;206 -1 } else if (type === 'id-list') {207 -1 return raw.split(/\s+/);208 -1 } else if (type === 'integer') {209 -1 return parseInt(raw, 10);210 -1 } else if (type === 'number') {211 -1 return parseFloat(raw);212 -1 } else if (type === 'token-list') {213 -1 return raw.split(/\s+/);214 -1 } else {215 -1 return raw;-1 915 const _getOwner = function(node, owners) { -1 916 if (node.nodeType === node.ELEMENT_NODE && node.id) { -1 917 const selector = '[aria-owns~="' + CSS.escape(node.id) + '"]'; -1 918 if (owners) { -1 919 for (const owner of owners) { -1 920 if (owner.matches(selector)) { -1 921 return owner; -1 922 } -1 923 } -1 924 } else { -1 925 return document.querySelector(selector); -1 926 } 216 927 }217 -1 }-1 928 }; 218 929219 -1 // TODO220 -1 // autocomplete221 -1 // contextmenu -> aria-haspopup222 -1 // indeterminate -> aria-checked="mixed"223 -1 // list -> aria-controls-1 930 const _getParentNode = function(node, owners) { -1 931 return _getOwner(node, owners) || node.parentNode; -1 932 }; 224 933225 -1 if (key === 'level') {226 -1 for (let i = 1; i <= 6; i++) {227 -1 if (el.tagName.toLowerCase() === 'h' + i) {228 -1 return i;-1 934 const detectLoop = function(node, owners) { -1 935 const seen = [node]; -1 936 while ((node = _getParentNode(node, owners))) { -1 937 if (seen.includes(node)) { -1 938 return true; 229 939 } -1 940 seen.push(node); 230 941 }231 -1 } else if (constants.attributeWeakMapping.hasOwnProperty(key)) {232 -1 return el[constants.attributeWeakMapping[key]];233 -1 }-1 942 }; 234 943235 -1 if (key in constants.attrsWithDefaults) {236 -1 const role = getRole(el);237 -1 const defaults = constants.roles[role].defaults;238 -1 if (defaults && defaults.hasOwnProperty(key)) {239 -1 return defaults[key];-1 944 const getOwner = function(node, owners) { -1 945 const owner = _getOwner(node, owners); -1 946 if (owner && !detectLoop(node, owners)) { -1 947 return owner; 240 948 }241 -1 }-1 949 }; 242 950243 -1 if (type === 'bool' || type === 'tristate') {244 -1 return false;245 -1 }246 -1 };247 -1248 -1 module.exports = {249 -1 getRole: getRole,250 -1 hasRole: hasRole,251 -1 getAttribute: getAttribute,252 -1 };253 -1254 -1 },{"./constants.js":4}],4:[function(require,module,exports){255 -1 // https://www.w3.org/TR/wai-aria/#state_prop_def256 -1 exports.attributes = {257 -1 'activedescendant': 'id',258 -1 'atomic': 'bool',259 -1 'autocomplete': 'token',260 -1 'braillelabel': 'string',261 -1 'brailleroledescription': 'string',262 -1 'busy': 'bool',263 -1 'checked': 'tristate',264 -1 'colcount': 'int',265 -1 'colindex': 'int',266 -1 'colindextext': 'string',267 -1 'colspan': 'int',268 -1 'controls': 'id-list',269 -1 'current': 'token',270 -1 'describedby': 'id-list',271 -1 'description': 'string',272 -1 'details': 'id',273 -1 'disabled': 'bool',274 -1 'dropeffect': 'token-list',275 -1 'errormessage': 'id',276 -1 'expanded': 'bool-undefined',277 -1 'flowto': 'id-list',278 -1 'grabbed': 'bool-undefined',279 -1 'haspopup': 'token',280 -1 'hidden': 'bool-undefined',281 -1 'invalid': 'token',282 -1 'keyshortcuts': 'string',283 -1 'label': 'string',284 -1 'labelledby': 'id-list',285 -1 'level': 'int',286 -1 'live': 'token',287 -1 'modal': 'bool',288 -1 'multiline': 'bool',289 -1 'multiselectable': 'bool',290 -1 'orientation': 'token',291 -1 'owns': 'id-list',292 -1 'placeholder': 'string',293 -1 'posinset': 'int',294 -1 'pressed': 'tristate',295 -1 'readonly': 'bool',296 -1 'relevant': 'token-list',297 -1 'required': 'bool',298 -1 'roledescription': 'string',299 -1 'rowcount': 'int',300 -1 'rowindex': 'int',301 -1 'rowindextext': 'string',302 -1 'rowspan': 'int',303 -1 'selected': 'bool-undefined',304 -1 'setsize': 'int',305 -1 'sort': 'token',306 -1 'valuemax': 'number',307 -1 'valuemin': 'number',308 -1 'valuenow': 'number',309 -1 'valuetext': 'string',310 -1 };311 -1312 -1 exports.attributeStrongMapping = {313 -1 'disabled': 'disabled',314 -1 'placeholder': 'placeholder',315 -1 'readonly': 'readOnly',316 -1 'required': 'required',317 -1 };318 -1319 -1 exports.attributeWeakMapping = {320 -1 'checked': 'checked',321 -1 'colspan': 'colSpan',322 -1 'expanded': 'open',323 -1 'multiselectable': 'multiple',324 -1 'rowspan': 'rowSpan',325 -1 'selected': 'selected',326 -1 };327 -1328 -1 // https://www.w3.org/TR/html/dom.html#sectioning-content-2329 -1 const scoped = ['article *', 'aside *', 'nav *', 'section *'].join(',');330 -1331 -1 const svgSelectors = function(selector) {332 -1 return [333 -1 // `${selector}:has(> title:not(:empty))`,334 -1 // `${selector}:has(> desc:not(:empty))`,335 -1 `${selector}[aria-label]`,336 -1 `${selector}[aria-roledescription]`,337 -1 `${selector}[aria-labelledby]`,338 -1 `${selector}[aria-describedby]`,339 -1 `${selector}[tabindex]`,340 -1 `${selector}[role]`,341 -1 ];342 -1 };343 -1344 -1 // https://www.w3.org/TR/html-aam-1.0/#html-element-role-mappings345 -1 // https://www.w3.org/TR/wai-aria/roles346 -1 exports.roles = {347 -1 alert: {348 -1 childRoles: ['alertdialog'],349 -1 defaults: {350 -1 'live': 'assertive',351 -1 'atomic': true,352 -1 },353 -1 },354 -1 alertdialog: {},355 -1 application: {},356 -1 article: {357 -1 selectors: ['article'],358 -1 childRoles: ['comment'],359 -1 },360 -1 banner: {361 -1 selectors: [`header:not(main *, ${scoped})`],362 -1 },363 -1 blockquote: {364 -1 selectors: ['blockquote'],365 -1 },366 -1 button: {367 -1 selectors: [368 -1 'button',369 -1 'input[type="button"]',370 -1 'input[type="image"]',371 -1 'input[type="reset"]',372 -1 'input[type="submit"]',373 -1 'summary',374 -1 ],375 -1 nameFromContents: true,376 -1 },377 -1 caption: {378 -1 selectors: ['caption', 'figcaption'],379 -1 },380 -1 cell: {381 -1 selectors: ['td', 'td ~ th:not([scope])'],382 -1 childRoles: ['columnheader', 'gridcell', 'rowheader'],383 -1 nameFromContents: true,384 -1 },385 -1 checkbox: {386 -1 selectors: ['input[type="checkbox"]'],387 -1 childRoles: ['switch'],388 -1 nameFromContents: true,389 -1 defaults: {390 -1 'checked': 'false',391 -1 },392 -1 },393 -1 code: {394 -1 selectors: ['code'],395 -1 },396 -1 columnheader: {397 -1 selectors: ['th[scope="col"]'],398 -1 nameFromContents: true,399 -1 },400 -1 combobox: {401 -1 selectors: [402 -1 'input:not([type])[list]',403 -1 'input[type="email"][list]',404 -1 'input[type="search"][list]',405 -1 'input[type="tel"][list]',406 -1 'input[type="text"][list]',407 -1 'input[type="url"][list]',408 -1 'select:not([size]):not([multiple])',409 -1 'select[size="0"]:not([multiple])',410 -1 'select[size="1"]:not([multiple])',411 -1 ],412 -1 defaults: {413 -1 'expanded': false,414 -1 'haspopup': 'listbox',415 -1 },416 -1 },417 -1 command: {418 -1 abstract: true,419 -1 childRoles: ['button', 'link', 'menuitem'],420 -1 },421 -1 comment: {422 -1 nameFromContents: true,423 -1 },424 -1 complementary: {425 -1 selectors: [426 -1 `aside:not(${scoped})`,427 -1 'aside[aria-label]',428 -1 'aside[aria-labelledby]',429 -1 'aside[title]',430 -1 ],431 -1 },432 -1 composite: {433 -1 abstract: true,434 -1 childRoles: ['grid', 'select', 'spinbutton', 'tablist'],435 -1 },436 -1 contentinfo: {437 -1 selectors: [`footer:not(main *, ${scoped})`],438 -1 },439 -1 definition: {440 -1 selectors: ['dd'],441 -1 },442 -1 deletion: {443 -1 selectors: ['del', 's'],444 -1 },445 -1 dialog: {446 -1 selectors: ['dialog'],447 -1 childRoles: ['alertdialog'],448 -1 },449 -1 'doc-abstract': {},450 -1 'doc-acknowledgments': {},451 -1 'doc-afterword': {},452 -1 'doc-appendix': {},453 -1 'doc-backlink': {454 -1 nameFromContents: true,455 -1 },456 -1 'doc-biblioentry': {},457 -1 'doc-bibliography': {},458 -1 'doc-biblioref': {459 -1 nameFromContents: true,460 -1 },461 -1 'doc-chapter': {},462 -1 'doc-colophon': {},463 -1 'doc-conclusion': {},464 -1 'doc-cover': {},465 -1 'doc-credit': {},466 -1 'doc-credits': {},467 -1 'doc-dedication': {},468 -1 'doc-endnote': {},469 -1 'doc-endnotes': {},470 -1 'doc-epilogue': {},471 -1 'doc-epigraph': {},472 -1 'doc-errata': {},473 -1 'doc-example': {},474 -1 'doc-footnote': {},475 -1 'doc-foreword': {},476 -1 'doc-glossary': {},477 -1 'doc-glossref': {478 -1 nameFromContents: true,479 -1 },480 -1 'doc-index': {},481 -1 'doc-introduction': {},482 -1 'doc-noteref': {483 -1 nameFromContents: true,484 -1 },485 -1 'doc-notice': {},486 -1 'doc-pagebreak': {487 -1 nameFromContents: true,488 -1 },489 -1 'doc-pagefooter': {},490 -1 'doc-pageheader': {},491 -1 'doc-pagelist': {},492 -1 'doc-part': {},493 -1 'doc-preface': {},494 -1 'doc-prologue': {},495 -1 'doc-pullquote': {},496 -1 'doc-qna': {},497 -1 'doc-subtitle': {498 -1 nameFromContents: true,499 -1 },500 -1 'doc-tip': {},501 -1 'doc-toc': {},502 -1 document: {503 -1 selectors: ['html'],504 -1 childRoles: ['article', 'graphics-document'],505 -1 },506 -1 emphasis: {507 -1 selectors: ['em'],508 -1 },509 -1 feed: {},510 -1 figure: {511 -1 selectors: ['figure'],512 -1 childRoles: ['doc-example'],513 -1 },514 -1 form: {515 -1 selectors: ['form[aria-label]', 'form[aria-labelledby]', 'form[title]'],516 -1 },517 -1 generic: {518 -1 selectors: [519 -1 'a:not([*|href])',520 -1 'area:not([*|href])',521 -1 `aside:not(${scoped}):not([aria-label]):not([aria-labelledby]):not([title])`,522 -1 'b',523 -1 'bdi',524 -1 'bdo',525 -1 'body',526 -1 'data',527 -1 'div',528 -1 // footer scoped529 -1 // header scoped530 -1 'i',531 -1 'li:not(ul > li):not(ol > li)',532 -1 'pre',533 -1 'q',534 -1 'samp',535 -1 'section:not([aria-label]):not([aria-labelledby]):not([title])',536 -1 'small',537 -1 'span',538 -1 'u',539 -1 ],540 -1 },541 -1 'graphics-document': {542 -1 selectors: ['svg'],543 -1 },544 -1 'graphics-object': {545 -1 selectors: [546 -1 ...svgSelectors('symbol'),547 -1 ...svgSelectors('use'),548 -1 ],549 -1 },550 -1 'graphics-symbol': {551 -1 selectors: [552 -1 ...svgSelectors('circle'),553 -1 ...svgSelectors('ellipse'),554 -1 ...svgSelectors('line'),555 -1 ...svgSelectors('path'),556 -1 ...svgSelectors('polygon'),557 -1 ...svgSelectors('polyline'),558 -1 ...svgSelectors('rect'),559 -1 ],560 -1 },561 -1 grid: {562 -1 childRoles: ['treegrid'],563 -1 },564 -1 gridcell: {565 -1 childRoles: ['columnheader', 'rowheader'],566 -1 nameFromContents: true,567 -1 },568 -1 group: {569 -1 selectors: [570 -1 'address',571 -1 'details',572 -1 'fieldset',573 -1 'hgroup',574 -1 'optgroup',575 -1 ...svgSelectors('foreignObject'),576 -1 ...svgSelectors('g'),577 -1 'text',578 -1 ...svgSelectors('textPath'),579 -1 ...svgSelectors('tspan'),580 -1 ],581 -1 childRoles: ['row', 'select', 'toolbar', 'graphics-object'],582 -1 },583 -1 heading: {584 -1 selectors: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'],585 -1 nameFromContents: true,586 -1 defaults: {587 -1 'level': 2,588 -1 },589 -1 },590 -1 image: {591 -1 selectors: [592 -1 'img:not([alt=""])',593 -1 'graphics-symbol',594 -1 ...svgSelectors('image'),595 -1 ...svgSelectors('mesh'),596 -1 ],597 -1 childRoles: ['doc-cover'],598 -1 },599 -1 input: {600 -1 abstract: true,601 -1 childRoles: [602 -1 'checkbox',603 -1 'combobox',604 -1 'option',605 -1 'radio',606 -1 'slider',607 -1 'spinbutton',608 -1 'textbox',609 -1 ],610 -1 },611 -1 insertion: {612 -1 selectors: ['ins'],613 -1 },614 -1 landmark: {615 -1 abstract: true,616 -1 childRoles: [617 -1 'banner',618 -1 'complementary',619 -1 'contentinfo',620 -1 'doc-acknowledgments',621 -1 'doc-afterword',622 -1 'doc-appendix',623 -1 'doc-bibliography',624 -1 'doc-chapter',625 -1 'doc-conclusion',626 -1 'doc-credits',627 -1 'doc-endnotes',628 -1 'doc-epilogue',629 -1 'doc-errata',630 -1 'doc-foreword',631 -1 'doc-glossary',632 -1 'doc-introduction',633 -1 'doc-part',634 -1 'doc-preface',635 -1 'doc-prologue',636 -1 'form',637 -1 'main',638 -1 'navigation',639 -1 'region',640 -1 'search',641 -1 ],642 -1 },643 -1 link: {644 -1 selectors: ['a[*|href]', 'area[href]'],645 -1 childRoles: ['doc-backlink', 'doc-biblioref', 'doc-glossref', 'doc-noteref'],646 -1 nameFromContents: true,647 -1 },648 -1 list: {649 -1 selectors: ['dl', 'ol', 'ul', 'menu'],650 -1 childRoles: ['feed'],651 -1 },652 -1 listbox: {653 -1 selectors: [654 -1 'datalist',655 -1 'select[multiple]',656 -1 'select[size]:not([size="0"]):not([size="1"])',657 -1 ],658 -1 defaults: {659 -1 'orientation': 'vertical',660 -1 },661 -1 },662 -1 listitem: {663 -1 selectors: ['ol > li', 'ul > li'],664 -1 childRoles: ['doc-biblioentry', 'doc-endnote', 'treeitem'],665 -1 },666 -1 log: {667 -1 defaults: {668 -1 'live': 'polite',669 -1 },670 -1 },671 -1 main: {672 -1 selectors: ['main'],673 -1 },674 -1 mark: {675 -1 selectors: ['mark'],676 -1 },677 -1 marquee: {},678 -1 math: {679 -1 selectors: ['math'],680 -1 },681 -1 meter: {682 -1 selectors: ['meter'],683 -1 defaults: {684 -1 'valuemin': 0,685 -1 'valuemax': 100,686 -1 },687 -1 },688 -1 menu: {689 -1 childRoles: ['menubar'],690 -1 defaults: {691 -1 'orientation': 'vertical',692 -1 },693 -1 },694 -1 menubar: {695 -1 defaults: {696 -1 'orientation': 'horizontal',697 -1 },698 -1 },699 -1 menuitem: {700 -1 childRoles: ['menuitemcheckbox', 'menuitemradio'],701 -1 nameFromContents: true,702 -1 },703 -1 menuitemcheckbox: {704 -1 nameFromContents: true,705 -1 defaults: {706 -1 'checked': 'false',707 -1 },708 -1 },709 -1 menuitemradio: {710 -1 nameFromContents: true,711 -1 defaults: {712 -1 'checked': 'false',713 -1 },714 -1 },715 -1 navigation: {716 -1 selectors: ['nav'],717 -1 childRoles: ['doc-index', 'doc-pagelist', 'doc-toc'],718 -1 },719 -1 none: {720 -1 selectors: ['img[alt=""]'],721 -1 },722 -1 note: {723 -1 childRoles: ['doc-notice', 'doc-tip'],724 -1 },725 -1 option: {726 -1 selectors: ['option'],727 -1 childRoles: ['treeitem'],728 -1 nameFromContents: true,729 -1 defaults: {730 -1 'selected': 'false',731 -1 },732 -1 },733 -1 paragraph: {734 -1 selectors: ['p'],735 -1 },736 -1 progressbar: {737 -1 selectors: ['progress'],738 -1 defaults: {739 -1 'valuemin': 0,740 -1 'valuemax': 100,741 -1 },742 -1 },743 -1 radio: {744 -1 selectors: ['input[type="radio"]'],745 -1 childRoles: ['menuitemradio'],746 -1 nameFromContents: true,747 -1 defaults: {748 -1 'checked': 'false',749 -1 },750 -1 },751 -1 radiogroup: {},752 -1 range: {753 -1 abstract: true,754 -1 childRoles: ['meter', 'progressbar', 'scrollbar', 'slider', 'spinbutton'],755 -1 },756 -1 region: {757 -1 selectors: ['section[aria-label]', 'section[aria-labelledby]', 'section[title]'],758 -1 },759 -1 roletype: {760 -1 abstract: true,761 -1 childRoles: ['structure', 'widget', 'window'],762 -1 },763 -1 row: {764 -1 selectors: ['tr'],765 -1 nameFromContents: true,766 -1 },767 -1 rowgroup: {768 -1 selectors: ['tbody', 'thead', 'tfoot'],769 -1 },770 -1 rowheader: {771 -1 selectors: ['th[scope="row"]', 'th:not([scope]):not(td ~ th)'],772 -1 nameFromContents: true,773 -1 },774 -1 scrollbar: {775 -1 defaults: {776 -1 'orientation': 'vertical',777 -1 'valuemin': 0,778 -1 'valuemax': 100,779 -1 },780 -1 },781 -1 search: {782 -1 selectors: ['search'],783 -1 },784 -1 searchbox: {785 -1 selectors: ['input[type="search"]:not([list])'],786 -1 },787 -1 section: {788 -1 abstract: true,789 -1 childRoles: [790 -1 'alert',791 -1 'blockquote',792 -1 'caption',793 -1 'cell',794 -1 'code',795 -1 'definition',796 -1 'deletion',797 -1 'doc-abstract',798 -1 'doc-colophon',799 -1 'doc-credit',800 -1 'doc-dedication',801 -1 'doc-epigraph',802 -1 'doc-footnote',803 -1 'doc-pagefooter',804 -1 'doc-pageheader',805 -1 'doc-pullquote',806 -1 'doc-qna',807 -1 'emphasis',808 -1 'figure',809 -1 'group',810 -1 'image',811 -1 'insertion',812 -1 'landmark',813 -1 'list',814 -1 'listitem',815 -1 'log',816 -1 'mark',817 -1 'marquee',818 -1 'math',819 -1 'note',820 -1 'paragraph',821 -1 'status',822 -1 'strong',823 -1 'subscript',824 -1 'suggestion',825 -1 'superscript',826 -1 'table',827 -1 'tabpanel',828 -1 'term',829 -1 'time',830 -1 'tooltip',831 -1 ],832 -1 },833 -1 sectionhead: {834 -1 abstract: true,835 -1 childRoles: [836 -1 'columnheader',837 -1 'doc-subtitle',838 -1 'heading',839 -1 'rowheader',840 -1 'tab',841 -1 ],842 -1 nameFromContents: true,843 -1 },844 -1 select: {845 -1 abstract: true,846 -1 childRoles: ['listbox', 'menu', 'radiogroup', 'tree'],847 -1 },848 -1 separator: {849 -1 // assume not focussable because <hr> is not850 -1 selectors: ['hr'],851 -1 childRoles: ['doc-pagebreak'],852 -1 defaults: {853 -1 'orientation': 'horizontal',854 -1 'valuemin': 0,855 -1 'valuemax': 100,856 -1 },857 -1 },858 -1 slider: {859 -1 selectors: ['input[type="range"]'],860 -1 defaults: {861 -1 'orientation': 'horizontal',862 -1 'valuemin': 0,863 -1 'valuemax': 100,864 -1 // FIXME: halfway between actual valuemin and valuemax865 -1 'valuenow': 50,866 -1 },867 -1 },868 -1 spinbutton: {869 -1 selectors: ['input[type="number"]'],870 -1 defaults: {871 -1 // FIXME: no valuemin/valuemax/valuenow872 -1 },873 -1 },874 -1 status: {875 -1 selectors: ['output'],876 -1 childRoles: ['timer'],877 -1 defaults: {878 -1 'live': 'polite',879 -1 'atomic': true,880 -1 },881 -1 },882 -1 strong: {883 -1 selectors: ['strong'],884 -1 },885 -1 structure: {886 -1 abstract: true,887 -1 childRoles: [888 -1 'application',889 -1 'document',890 -1 'none',891 -1 'generic',892 -1 'range',893 -1 'rowgroup',894 -1 'section',895 -1 'sectionhead',896 -1 'separator',897 -1 ],898 -1 },899 -1 suggestion: {},900 -1 subscript: {901 -1 selectors: ['sub'],902 -1 },903 -1 superscript: {904 -1 selectors: ['sup'],905 -1 },906 -1 switch: {907 -1 nameFromContents: true,908 -1 defaults: {909 -1 'checked': false,910 -1 },911 -1 },912 -1 tab: {913 -1 nameFromContents: true,914 -1 defaults: {915 -1 'selected': false,916 -1 },917 -1 },918 -1 table: {919 -1 selectors: ['table'],920 -1 childRoles: ['grid'],921 -1 },922 -1 tablist: {923 -1 defaults: {924 -1 'orientation': 'horizontal',925 -1 },926 -1 },927 -1 tabpanel: {},928 -1 term: {929 -1 selectors: ['dfn', 'dt'],930 -1 },931 -1 textbox: {932 -1 selectors: [933 -1 'input:not([type]):not([list])',934 -1 'input[type="email"]:not([list])',935 -1 'input[type="tel"]:not([list])',936 -1 'input[type="text"]:not([list])',937 -1 'input[type="url"]:not([list])',938 -1 'textarea',939 -1 ],940 -1 childRoles: ['searchbox'],941 -1 },942 -1 time: {943 -1 selectors: ['time'],944 -1 },945 -1 timer: {946 -1 defaults: {947 -1 'live': 'off',948 -1 },949 -1 },950 -1 toolbar: {951 -1 defaults: {952 -1 'orientation': 'horizontal',953 -1 },954 -1 },955 -1 tooltip: {956 -1 nameFromContents: true,957 -1 },958 -1 tree: {959 -1 childRoles: ['treegrid'],960 -1 defaults: {961 -1 'orientation': 'vertical',962 -1 },963 -1 },964 -1 treegrid: {},965 -1 treeitem: {966 -1 nameFromContents: true,967 -1 },968 -1 widget: {969 -1 abstract: true,970 -1 childRoles: [971 -1 'command',972 -1 'composite',973 -1 'gridcell',974 -1 'input',975 -1 'progressbar',976 -1 'row',977 -1 'scrollbar',978 -1 'separator',979 -1 'tab',980 -1 ],981 -1 },982 -1 window: {983 -1 abstract: true,984 -1 childRoles: ['dialog'],985 -1 },986 -1 };987 -1988 -1 const getSubRoles = function(role) {989 -1 const children = (exports.roles[role]).childRoles || [];990 -1 const descendents = children.map(getSubRoles);991 -1992 -1 const result = [role];993 -1994 -1 descendents.forEach(list => {995 -1 list.forEach(r => {996 -1 if (!result.includes(r)) {997 -1 result.push(r);998 -1 }999 -1 });1000 -1 });-1 951 const getParentNode = function(node, owners) { -1 952 return getOwner(node, owners) || node.parentNode; -1 953 }; 1001 9541002 -1 return result;1003 -1 };-1 955 const isHidden = function(node) { -1 956 return node.nodeType === node.ELEMENT_NODE && getAttribute(node, 'hidden'); -1 957 }; 1004 9581005 -1 exports.attrsWithDefaults = [];-1 959 const getChildNodes = function(node, owners) { -1 960 const childNodes = []; 1006 9611007 -1 for (const role in exports.roles) {1008 -1 exports.roles[role].subRoles = getSubRoles(role);1009 -1 for (const key in exports.roles[role].defaults) {1010 -1 if (!exports.attrsWithDefaults.includes(key)) {1011 -1 exports.attrsWithDefaults.push(key);-1 962 for (let i = 0; i < node.childNodes.length; i++) { -1 963 const child = node.childNodes[i]; -1 964 if (!getOwner(child, owners) && !isHidden(child)) { -1 965 childNodes.push(child); -1 966 } 1012 967 }1013 -1 }1014 -1 }1015 -11016 -1 exports.aliases = {1017 -1 'presentation': 'none',1018 -1 'directory': 'list',1019 -1 'img': 'image',1020 -1 };1021 -11022 -1 exports.nameFromDescendant = {1023 -1 'figure': 'figcaption',1024 -1 'table': 'caption',1025 -1 'fieldset': 'legend',1026 -1 };1027 -11028 -1 exports.nameDefaults = {1029 -1 'input[type="submit"]': 'Submit',1030 -1 'input[type="reset"]': 'Reset',1031 -1 'summary': 'Details',1032 -1 };1033 -11034 -1 },{}],5:[function(require,module,exports){1035 -1 const constants = require('./constants.js');1036 -1 const atree = require('./atree.js');1037 -1 const query = require('./query.js');1038 -11039 -1 const addSpaces = function(text, el, pseudoSelector) {1040 -1 // https://github.com/w3c/accname/issues/31041 -1 const styles = window.getComputedStyle(el, pseudoSelector);1042 -1 const inline = styles.display === 'inline';1043 -1 return inline ? text : ` ${text} `;1044 -1 };1045 -11046 -1 const getPseudoContent = function(el, pseudoSelector) {1047 -1 const styles = window.getComputedStyle(el, pseudoSelector);1048 -1 let tail = styles.getPropertyValue('content').trim();1049 -1 let ret = [];1050 -11051 -1 let match;1052 -1 while (tail.length) {1053 -1 if (match = tail.match(/^"([^"]*)"/)) {1054 -1 ret.push(match[1]);1055 -1 } else if (match = tail.match(/^([a-z-]+)\(([^)]*)\)/)) {1056 -1 if (match[1] === 'attr') {1057 -1 ret.push(el.getAttribute(match[2]) || '');-1 968 -1 969 if (node.nodeType === node.ELEMENT_NODE) { -1 970 const owns = getAttribute(node, 'owns') || []; -1 971 for (let i = 0; i < owns.length; i++) { -1 972 const child = document.getElementById(owns[i]); -1 973 // double check with getOwner for consistency -1 974 if (child && getOwner(child, owners) === node && !isHidden(child)) { -1 975 childNodes.push(child); -1 976 } 1058 977 }1059 -1 } else if (match = tail.match(/^([a-z-]+)/)) {1060 -1 if (match[1] === 'open-quote' || match[1] === 'close-quote') {1061 -1 ret.push('"');-1 978 } -1 979 -1 980 return childNodes; -1 981 }; -1 982 -1 983 const walk = function(root, fn) { -1 984 const owners = document.querySelectorAll('[aria-owns]'); -1 985 let queue = [root]; -1 986 while (queue.length) { -1 987 const item = queue.shift(); -1 988 fn(item); -1 989 queue = getChildNodes(item, owners).concat(queue); -1 990 } -1 991 }; -1 992 -1 993 const searchUp = function(node, test) { -1 994 const candidate = getParentNode(node); -1 995 if (candidate) { -1 996 if (test(candidate)) { -1 997 return candidate; -1 998 } else { -1 999 return searchUp(candidate, test); 1062 1000 }1063 -1 } else if (match = tail.match(/^\//)) {1064 -1 ret = [];-1 1001 } -1 1002 }; -1 1003 -1 1004 const matches = function(el, selector) { -1 1005 if (selector.substr(0, 1) === ':') { -1 1006 const attr = selector.substr(1); -1 1007 return getAttribute(el, attr); -1 1008 } else if (selector.substr(0, 1) === '[') { -1 1009 const match = /\[([a-z]+)="(.*)"\]/.exec(selector); -1 1010 const actual = getAttribute(el, match[1]); -1 1011 const rawValue = match[2]; -1 1012 return actual.toString() === rawValue; 1065 1013 } else {1066 -1 // invalid content, ignore1067 -1 return '';-1 1014 return hasRole(el, selector.split(',')); 1068 1015 }1069 -1 tail = tail.slice(match[0].length).trim();1070 -1 }-1 1016 }; 1071 10171072 -1 return addSpaces(ret.join(''), el, pseudoSelector);1073 -1 };-1 1018 const _querySelector = function(all) { -1 1019 return function(root, selector) { -1 1020 const results = []; -1 1021 try { -1 1022 walk(root, node => { -1 1023 if (node.nodeType === node.ELEMENT_NODE) { -1 1024 // FIXME: skip hidden elements -1 1025 if (matches(node, selector)) { -1 1026 results.push(node); -1 1027 if (!all) { -1 1028 throw 'StopIteration'; -1 1029 } -1 1030 } -1 1031 } -1 1032 }); -1 1033 } catch (e) { -1 1034 if (e !== 'StopIteration') { -1 1035 throw e; -1 1036 } -1 1037 } -1 1038 return all ? results : results[0]; -1 1039 }; -1 1040 }; -1 1041 -1 1042 const closest = function(el, selector) { -1 1043 return searchUp(el, candidate => { -1 1044 if (candidate.nodeType === candidate.ELEMENT_NODE) { -1 1045 return matches(candidate, selector); -1 1046 } -1 1047 }); -1 1048 }; 1074 10491075 -1 const getContent = function(root, ongoingLabelledBy, visited) {1076 -1 const children = atree.getChildNodes(root);-1 1050 const querySelector = _querySelector(); -1 1051 const querySelectorAll = _querySelector(true); -1 1052 -1 1053 const addSpaces = function(text, el, pseudoSelector) { -1 1054 // https://github.com/w3c/accname/issues/3 -1 1055 const styles = window.getComputedStyle(el, pseudoSelector); -1 1056 const inline = styles.display === 'inline'; -1 1057 return inline ? text : ` ${text} `; -1 1058 }; 1077 10591078 -1 let ret = '';1079 -1 for (let i = 0; i < children.length; i++) {1080 -1 const node = children[i];1081 -1 if (node.nodeType === node.TEXT_NODE) {1082 -1 ret += node.textContent;1083 -1 } else if (node.nodeType === node.ELEMENT_NODE) {1084 -1 if (node.tagName.toLowerCase() === 'br') {1085 -1 ret += '\n';-1 1060 const getPseudoContent = function(el, pseudoSelector) { -1 1061 const styles = window.getComputedStyle(el, pseudoSelector); -1 1062 let tail = styles.getPropertyValue('content').trim(); -1 1063 let ret = []; -1 1064 -1 1065 let match; -1 1066 while (tail.length) { -1 1067 if ((match = tail.match(/^"([^"]*)"/))) { -1 1068 ret.push(match[1]); -1 1069 } else if ((match = tail.match(/^([a-z-]+)\(([^)]*)\)/))) { -1 1070 if (match[1] === 'attr') { -1 1071 ret.push(el.getAttribute(match[2]) || ''); -1 1072 } -1 1073 } else if ((match = tail.match(/^([a-z-]+)/))) { -1 1074 if (match[1] === 'open-quote' || match[1] === 'close-quote') { -1 1075 ret.push('"'); -1 1076 } -1 1077 } else if ((match = tail.match(/^\//))) { -1 1078 ret = []; 1086 1079 } else {1087 -1 ret += getName(node, true, ongoingLabelledBy, visited);-1 1080 // invalid content, ignore -1 1081 return ''; 1088 1082 } -1 1083 tail = tail.slice(match[0].length).trim(); 1089 1084 }1090 -1 }1091 10851092 -1 return ret;1093 -1 };-1 1086 return addSpaces(ret.join(''), el, pseudoSelector); -1 1087 }; 1094 10881095 -1 const allowNameFromContent = function(el) {1096 -1 const role = query.getRole(el);1097 -1 if (role) {1098 -1 return constants.roles[role].nameFromContents;1099 -1 }1100 -1 };-1 1089 const getContent = function(root, ongoingLabelledBy, visited) { -1 1090 const children = getChildNodes(root); -1 1091 -1 1092 let ret = ''; -1 1093 for (let i = 0; i < children.length; i++) { -1 1094 const node = children[i]; -1 1095 if (node.nodeType === node.TEXT_NODE) { -1 1096 const styles = window.getComputedStyle(node.parentElement); -1 1097 if (styles.textTransform === 'uppercase') { -1 1098 ret += node.textContent.toUpperCase(); -1 1099 } else if (styles.textTransform === 'lowercase') { -1 1100 ret += node.textContent.toLowerCase(); -1 1101 } else if (styles.textTransform === 'capitalize') { -1 1102 ret += node.textContent.replace(/\b\w/g, c => c.toUpperCase()); -1 1103 } else { -1 1104 ret += node.textContent; -1 1105 } -1 1106 } else if (node.nodeType === node.ELEMENT_NODE) { -1 1107 if (node.tagName.toLowerCase() === 'br') { -1 1108 ret += '\n'; -1 1109 } else { -1 1110 ret += getNameRaw(node, true, ongoingLabelledBy, visited); -1 1111 } -1 1112 } -1 1113 } 1101 11141102 -1 const getName = function(el, recursive, ongoingLabelledBy, visited, directReference) {1103 -1 let ret = '';-1 1115 return ret; -1 1116 }; 1104 11171105 -1 visited = visited || [];1106 -1 if (visited.includes(el)) {1107 -1 if (!directReference) {1108 -1 return '';-1 1118 const allowNameFromContent = function(el) { -1 1119 const role = getRole(el); -1 1120 if (role) { -1 1121 return roles[role].nameFromContents; 1109 1122 }1110 -1 } else {1111 -1 visited.push(el);1112 -1 }-1 1123 }; 1113 11241114 -1 // A1115 -1 // handled in atree-1 1125 const getNameRaw = function(el, recursive, ongoingLabelledBy, visited, directReference) { -1 1126 let ret = ''; 1116 11271117 -1 // B1118 -1 if (!ongoingLabelledBy && el.matches('[aria-labelledby]')) {1119 -1 const ids = el.getAttribute('aria-labelledby').split(/\s+/);1120 -1 const strings = ids.map(id => {1121 -1 const label = document.getElementById(id);1122 -1 return label ? getName(label, true, true, visited, true) : '';1123 -1 });1124 -1 ret = strings.join(' ');1125 -1 }-1 1128 visited = visited || []; -1 1129 if (visited.includes(el)) { -1 1130 if (!directReference) { -1 1131 return ''; -1 1132 } -1 1133 } else { -1 1134 visited.push(el); -1 1135 } 1126 11361127 -1 // E (the current draft has this at this high priority)1128 -1 if (!ret.trim() && recursive) {1129 -1 if (query.matches(el, 'textbox')) {1130 -1 ret = el.value || el.textContent;1131 -1 } else if (query.matches(el, 'combobox,listbox')) {1132 -1 const selected = query.querySelector(el, ':selected') || query.querySelector(el, 'option');1133 -1 if (selected) {1134 -1 ret = getName(selected, recursive, ongoingLabelledBy, visited);1135 -1 } else {1136 -1 ret = el.value || '';-1 1137 // A -1 1138 // handled in atree -1 1139 -1 1140 // B -1 1141 if (!ongoingLabelledBy && el.matches('[aria-labelledby]')) { -1 1142 const ids = el.getAttribute('aria-labelledby').split(/\s+/); -1 1143 const strings = ids.map(id => { -1 1144 const label = document.getElementById(id); -1 1145 return label ? getNameRaw(label, true, true, visited, true) : ''; -1 1146 }); -1 1147 ret = strings.join(' '); -1 1148 } -1 1149 -1 1150 // E (the current draft has this at this high priority) -1 1151 if (!ret.trim() && recursive) { -1 1152 if (matches(el, 'textbox')) { -1 1153 ret = el.value || el.textContent; -1 1154 } else if (matches(el, 'combobox,listbox')) { -1 1155 const selected = querySelector(el, ':selected') || querySelector(el, 'option'); -1 1156 if (selected) { -1 1157 ret = getNameRaw(selected, recursive, ongoingLabelledBy, visited); -1 1158 } else { -1 1159 ret = el.value || ''; -1 1160 } -1 1161 } else if (matches(el, 'range')) { -1 1162 ret = '' + (getAttribute(el, 'valuetext') || getAttribute(el, 'valuenow') || el.value); 1137 1163 }1138 -1 } else if (query.matches(el, 'range')) {1139 -1 ret = '' + (query.getAttribute(el, 'valuetext') || query.getAttribute(el, 'valuenow') || el.value);1140 1164 }1141 -1 }1142 11651143 -1 // C1144 -1 if (!ret.trim() && el.matches('[aria-label]')) {1145 -1 // FIXME: may skip to 2E1146 -1 ret = el.getAttribute('aria-label');1147 -1 }-1 1166 // C -1 1167 if (!ret.trim() && el.matches('[aria-label]')) { -1 1168 // FIXME: may skip to 2E -1 1169 ret = el.getAttribute('aria-label'); -1 1170 } 1148 11711149 -1 // D1150 -1 if (!ret.trim() && !recursive && el.labels) {1151 -1 const strings = Array.prototype.map.call(el.labels, label => {1152 -1 return getName(label, true, ongoingLabelledBy, visited);1153 -1 });1154 -1 ret = strings.join(' ');1155 -1 }1156 -1 if (!ret.trim()) {1157 -1 ret = el.alt || '';1158 -1 }1159 -1 if (!ret.trim() && el.matches('abbr,acronym') && el.title) {1160 -1 ret = el.title;1161 -1 }1162 -1 if (!ret.trim()) {1163 -1 for (const selector in constants.nameFromDescendant) {1164 -1 if (el.matches(selector)) {1165 -1 const descendant = el.querySelector(constants.nameFromDescendant[selector]);1166 -1 if (descendant) {1167 -1 ret = getName(descendant, true, ongoingLabelledBy, visited);-1 1172 // D -1 1173 if (!ret.trim() && !recursive && el.labels) { -1 1174 const strings = Array.prototype.map.call(el.labels, label => { -1 1175 return getNameRaw(label, true, ongoingLabelledBy, visited); -1 1176 }); -1 1177 ret = strings.join(' '); -1 1178 } -1 1179 if (!ret.trim()) { -1 1180 ret = el.alt || ''; -1 1181 } -1 1182 if (!ret.trim() && el.matches('abbr,acronym') && el.title) { -1 1183 ret = el.title; -1 1184 } -1 1185 if (!ret.trim()) { -1 1186 for (const selector in nameFromDescendant) { -1 1187 if (el.matches(selector)) { -1 1188 const descendant = el.querySelector(nameFromDescendant[selector]); -1 1189 if (descendant) { -1 1190 ret = getNameRaw(descendant, true, ongoingLabelledBy, visited); -1 1191 } 1168 1192 } 1169 1193 } 1170 1194 }1171 -1 }1172 -1 if (!ret.trim() && el.matches('svg *')) {1173 -1 const svgTitle = el.querySelector('title');1174 -1 if (svgTitle && svgTitle.parentElement === el) {1175 -1 ret = svgTitle.textContent;-1 1195 if (!ret.trim() && el.matches('svg *')) { -1 1196 const svgTitle = el.querySelector('title'); -1 1197 if (svgTitle && svgTitle.parentElement === el) { -1 1198 ret = svgTitle.textContent; -1 1199 } -1 1200 } -1 1201 if (!ret.trim() && el.matches('a')) { -1 1202 ret = el.getAttribute('xlink:title') || ''; 1176 1203 }1177 -1 }1178 -1 if (!ret.trim() && el.matches('a')) {1179 -1 ret = el.getAttribute('xlink:title') || '';1180 -1 }1181 12041182 -1 // F1183 -1 // FIXME: menu is not mentioned in the spec1184 -1 if (!ret.trim() && (recursive || allowNameFromContent(el) || el.closest('label')) && !query.matches(el, 'menu')) {1185 -1 ret = getContent(el, ongoingLabelledBy, visited);1186 -1 }-1 1205 // F -1 1206 // FIXME: menu is not mentioned in the spec -1 1207 if (!ret.trim() && (recursive || allowNameFromContent(el) || el.closest('label')) && !matches(el, 'menu')) { -1 1208 ret = getContent(el, ongoingLabelledBy, visited); -1 1209 } 1187 12101188 -1 if (!ret.trim() && query.matches(el, 'button')) {1189 -1 ret = el.value || '';1190 -1 }-1 1211 if (!ret.trim() && matches(el, 'button')) { -1 1212 ret = el.value || ''; -1 1213 } 1191 12141192 -1 if (!ret.trim()) {1193 -1 for (const selector in constants.nameDefaults) {1194 -1 if (el.matches(selector)) {1195 -1 ret = constants.nameDefaults[selector];-1 1215 if (!ret.trim()) { -1 1216 for (const selector in nameDefaults) { -1 1217 if (el.matches(selector)) { -1 1218 ret = nameDefaults[selector]; -1 1219 } 1196 1220 } 1197 1221 }1198 -1 }1199 12221200 -1 // G/H1201 -1 // handled in getContent-1 1223 // G/H -1 1224 // handled in getContent 1202 12251203 -1 // I1204 -1 if (!ret.trim()) {1205 -1 ret = el.title || el.placeholder || '';1206 -1 }1207 -11208 -1 // FIXME: not exactly sure about this, but it reduces the number of failing1209 -1 // WPT tests. Whitespace is hard.1210 -1 if (!ret.trim()) {1211 -1 ret = ' ';1212 -1 }-1 1226 // I -1 1227 if (!ret.trim()) { -1 1228 ret = el.title || el.placeholder || ''; -1 1229 } 1213 12301214 -1 const before = getPseudoContent(el, ':before');1215 -1 const after = getPseudoContent(el, ':after');1216 -1 return addSpaces(before + ret + after, el);1217 -1 };1218 -11219 -1 const getNameTrimmed = function(el) {1220 -1 return getName(el)1221 -1 .replace(/[ \n\r\t\f]+/g, ' ')1222 -1 .replace(/^ /, '')1223 -1 .replace(/ $/, '');1224 -1 };1225 -11226 -1 const getDescription = function(el) {1227 -1 let ret = '';1228 -11229 -1 if (el.matches('[aria-describedby]')) {1230 -1 const ids = el.getAttribute('aria-describedby').split(/\s+/);1231 -1 const strings = ids.map(id => {1232 -1 const label = document.getElementById(id);1233 -1 return label ? getName(label, true, true) : '';1234 -1 });1235 -1 ret = strings.join(' ');1236 -1 } else if (el.matches('[aria-description]')) {1237 -1 ret = el.getAttribute('aria-description');1238 -1 } else if (el.matches('svg *')) {1239 -1 const svgDesc = el.querySelector('desc');1240 -1 if (svgDesc && svgDesc.parentElement === el) {1241 -1 ret = svgDesc.textContent;-1 1231 // FIXME: not exactly sure about this, but it reduces the number of failing -1 1232 // WPT tests. Whitespace is hard. -1 1233 if (!ret.trim()) { -1 1234 ret = ' '; 1242 1235 }1243 -1 } else if (el.title) {1244 -1 ret = el.title;1245 -1 }1246 -1 if (!ret.trim() && el.matches('a')) {1247 -1 ret = el.getAttribute('xlink:title') || '';1248 -1 }1249 12361250 -1 ret = (ret || '').trim().replace(/\s+/g, ' ');-1 1237 const before = getPseudoContent(el, ':before'); -1 1238 const after = getPseudoContent(el, ':after'); -1 1239 return addSpaces(before + ret + after, el); -1 1240 }; 1251 12411252 -1 if (ret === getNameTrimmed(el)) {1253 -1 ret = '';1254 -1 }-1 1242 const getName = function(el) { -1 1243 return getNameRaw(el) -1 1244 .replace(/[ \n\r\t\f]+/g, ' ') -1 1245 .replace(/^ /, '') -1 1246 .replace(/ $/, ''); -1 1247 }; 1255 12481256 -1 return ret;1257 -1 };1258 -11259 -1 module.exports = {1260 -1 getName: getNameTrimmed,1261 -1 getDescription: getDescription,1262 -1 };1263 -11264 -1 },{"./atree.js":2,"./constants.js":4,"./query.js":6}],6:[function(require,module,exports){1265 -1 const attrs = require('./attrs.js');1266 -1 const atree = require('./atree.js');1267 -11268 -11269 -1 const matches = function(el, selector) {1270 -1 if (selector.substr(0, 1) === ':') {1271 -1 const attr = selector.substr(1);1272 -1 return attrs.getAttribute(el, attr);1273 -1 } else if (selector.substr(0, 1) === '[') {1274 -1 const match = /\[([a-z]+)="(.*)"\]/.exec(selector);1275 -1 const actual = attrs.getAttribute(el, match[1]);1276 -1 const rawValue = match[2];1277 -1 return actual.toString() === rawValue;1278 -1 } else {1279 -1 return attrs.hasRole(el, selector.split(','));1280 -1 }1281 -1 };1282 -11283 -1 const _querySelector = function(all) {1284 -1 return function(root, selector) {1285 -1 const results = [];1286 -1 try {1287 -1 atree.walk(root, node => {1288 -1 if (node.nodeType === node.ELEMENT_NODE) {1289 -1 // FIXME: skip hidden elements1290 -1 if (matches(node, selector)) {1291 -1 results.push(node);1292 -1 if (!all) {1293 -1 throw 'StopIteration';1294 -1 }1295 -1 }1296 -1 }-1 1249 const getDescription = function(el) { -1 1250 let ret = ''; -1 1251 -1 1252 if (el.matches('[aria-describedby]')) { -1 1253 const ids = el.getAttribute('aria-describedby').split(/\s+/); -1 1254 const strings = ids.map(id => { -1 1255 const label = document.getElementById(id); -1 1256 return label ? getNameRaw(label, true, true) : ''; 1297 1257 });1298 -1 } catch (e) {1299 -1 if (e !== 'StopIteration') {1300 -1 throw e;-1 1258 ret = strings.join(' '); -1 1259 } else if (el.matches('[aria-description]')) { -1 1260 ret = el.getAttribute('aria-description'); -1 1261 } else if (el.matches('svg *')) { -1 1262 const svgDesc = el.querySelector('desc'); -1 1263 if (svgDesc && svgDesc.parentElement === el) { -1 1264 ret = svgDesc.textContent; 1301 1265 } -1 1266 } else if (el.title) { -1 1267 ret = el.title; -1 1268 } -1 1269 if (!ret.trim() && el.matches('a')) { -1 1270 ret = el.getAttribute('xlink:title') || ''; 1302 1271 }1303 -1 return all ? results : results[0];1304 -1 };1305 -1 };1306 12721307 -1 const closest = function(el, selector) {1308 -1 return atree.searchUp(el, candidate => {1309 -1 if (candidate.nodeType === candidate.ELEMENT_NODE) {1310 -1 return matches(candidate, selector);-1 1273 ret = (ret || '').trim().replace(/\s+/g, ' '); -1 1274 -1 1275 if (ret === getName(el)) { -1 1276 ret = ''; 1311 1277 }1312 -1 });1313 -1 };1314 -11315 -1 module.exports = {1316 -1 getRole: el => attrs.getRole(el),1317 -1 getAttribute: attrs.getAttribute,1318 -1 matches: matches,1319 -1 querySelector: _querySelector(),1320 -1 querySelectorAll: _querySelector(true),1321 -1 closest: closest,1322 -1 };1323 -11324 -1 },{"./atree.js":2,"./attrs.js":3}]},{},[1])(1)1325 -1 });-1 1278 -1 1279 return ret; -1 1280 }; -1 1281 -1 1282 exports.closest = closest; -1 1283 exports.getAttribute = getAttribute; -1 1284 exports.getChildNodes = getChildNodes; -1 1285 exports.getDescription = getDescription; -1 1286 exports.getName = getName; -1 1287 exports.getParentNode = getParentNode; -1 1288 exports.getRole = getRole; -1 1289 exports.matches = matches; -1 1290 exports.querySelector = querySelector; -1 1291 exports.querySelectorAll = querySelectorAll; -1 1292 -1 1293 }));
diff --git a/package.json b/package.json
@@ -1,6 +1,6 @@ 1 1 { 2 2 "name": "aria-api",3 -1 "version": "0.7.0",-1 3 "version": "0.8.0", 4 4 "description": "Access ARIA information from JavaScript", 5 5 "module": "index.js", 6 6 "keywords": [