aria-api 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/aria.js CHANGED
@@ -19,13 +19,13 @@ module.exports = {
19
19
  };
20
20
 
21
21
  },{"./lib/atree.js":2,"./lib/name.js":5,"./lib/query.js":6}],2:[function(require,module,exports){
22
- var attrs = require('./attrs');
22
+ const attrs = require('./attrs');
23
23
 
24
- var _getOwner = function(node, owners) {
24
+ const _getOwner = function(node, owners) {
25
25
  if (node.nodeType === node.ELEMENT_NODE && node.id) {
26
- var selector = '[aria-owns~="' + CSS.escape(node.id) + '"]';
26
+ const selector = '[aria-owns~="' + CSS.escape(node.id) + '"]';
27
27
  if (owners) {
28
- for (var owner of owners) {
28
+ for (const owner of owners) {
29
29
  if (owner.matches(selector)) {
30
30
  return owner;
31
31
  }
@@ -36,12 +36,12 @@ var _getOwner = function(node, owners) {
36
36
  }
37
37
  };
38
38
 
39
- var _getParentNode = function(node, owners) {
39
+ const _getParentNode = function(node, owners) {
40
40
  return _getOwner(node, owners) || node.parentNode;
41
41
  };
42
42
 
43
- var detectLoop = function(node, owners) {
44
- var seen = [node];
43
+ const detectLoop = function(node, owners) {
44
+ const seen = [node];
45
45
  while ((node = _getParentNode(node, owners))) {
46
46
  if (seen.includes(node)) {
47
47
  return true;
@@ -50,35 +50,35 @@ var detectLoop = function(node, owners) {
50
50
  }
51
51
  };
52
52
 
53
- var getOwner = function(node, owners) {
54
- var owner = _getOwner(node, owners);
53
+ const getOwner = function(node, owners) {
54
+ const owner = _getOwner(node, owners);
55
55
  if (owner && !detectLoop(node, owners)) {
56
56
  return owner;
57
57
  }
58
58
  };
59
59
 
60
- var getParentNode = function(node, owners) {
60
+ const getParentNode = function(node, owners) {
61
61
  return getOwner(node, owners) || node.parentNode;
62
62
  };
63
63
 
64
- var isHidden = function(node) {
64
+ const isHidden = function(node) {
65
65
  return node.nodeType === node.ELEMENT_NODE && attrs.getAttribute(node, 'hidden');
66
66
  };
67
67
 
68
- var getChildNodes = function(node, owners) {
69
- var childNodes = [];
68
+ const getChildNodes = function(node, owners) {
69
+ const childNodes = [];
70
70
 
71
- for (var i = 0; i < node.childNodes.length; i++) {
72
- var child = node.childNodes[i];
71
+ for (let i = 0; i < node.childNodes.length; i++) {
72
+ const child = node.childNodes[i];
73
73
  if (!getOwner(child, owners) && !isHidden(child)) {
74
74
  childNodes.push(child);
75
75
  }
76
76
  }
77
77
 
78
78
  if (node.nodeType === node.ELEMENT_NODE) {
79
- var owns = attrs.getAttribute(node, 'owns') || [];
80
- for (var i = 0; i < owns.length; i++) {
81
- var child = document.getElementById(owns[i]);
79
+ const owns = attrs.getAttribute(node, 'owns') || [];
80
+ for (let i = 0; i < owns.length; i++) {
81
+ const child = document.getElementById(owns[i]);
82
82
  // double check with getOwner for consistency
83
83
  if (child && getOwner(child, owners) === node && !isHidden(child)) {
84
84
  childNodes.push(child);
@@ -89,18 +89,18 @@ var getChildNodes = function(node, owners) {
89
89
  return childNodes;
90
90
  };
91
91
 
92
- var walk = function(root, fn) {
93
- var owners = document.querySelectorAll('[aria-owns]');
94
- var queue = [root];
92
+ const walk = function(root, fn) {
93
+ const owners = document.querySelectorAll('[aria-owns]');
94
+ let queue = [root];
95
95
  while (queue.length) {
96
- var item = queue.shift();
96
+ const item = queue.shift();
97
97
  fn(item);
98
98
  queue = getChildNodes(item, owners).concat(queue);
99
99
  }
100
100
  };
101
101
 
102
- var searchUp = function(node, test) {
103
- var candidate = getParentNode(node);
102
+ const searchUp = function(node, test) {
103
+ const candidate = getParentNode(node);
104
104
  if (candidate) {
105
105
  if (test(candidate)) {
106
106
  return candidate;
@@ -118,44 +118,59 @@ module.exports = {
118
118
  };
119
119
 
120
120
  },{"./attrs":3}],3:[function(require,module,exports){
121
- var constants = require('./constants.js');
121
+ const constants = require('./constants.js');
122
+
123
+ var unique = function(arr) {
124
+ return arr.filter((a, i) => arr.indexOf(a) === i);
125
+ };
126
+
127
+ var flatten = function(arr) {
128
+ return [].concat.apply([], arr);
129
+ };
130
+
131
+ var normalizeRoles = function(roles, includeAbstract) {
132
+ return unique(roles
133
+ .map(r => constants.aliases[r] || r)
134
+ .filter(r => constants.roles[r])
135
+ .filter(r => includeAbstract || !constants.roles[r].abstract)
136
+ );
137
+ };
122
138
 
123
139
  // candidates can be passed for performance optimization
124
- var getRole = function(el, candidates) {
125
- if (el.hasAttribute('role')) {
126
- var roles = el.getAttribute('role').toLowerCase().split(/\s+/);
127
- if (roles.length > 1 && candidates) {
128
- return [roles, candidates];
129
- }
130
- for (var role of roles) {
140
+ const getRole = function(el, candidates) {
141
+ // TODO: filter out any invalid roles (e.g. name or context required)
142
+ const roles = normalizeRoles(
143
+ (el.getAttribute('role') || '').toLowerCase().split(/\s+/)
144
+ );
145
+
146
+ if (roles.length > 1 && candidates) {
147
+ return [roles, candidates];
148
+ } else if (roles.length) {
149
+ for (const role of roles) {
131
150
  if (!candidates || candidates.includes(role)) {
132
151
  return role;
133
152
  }
134
153
  }
135
154
  } else {
136
- var roles = candidates ? candidates : Object.keys(constants.roles);
137
- for (var role of roles) {
138
- var r = constants.roles[role];
139
- if (r) {
140
- var selector = (r.selectors || []).join(',');
141
- if (selector && el.matches(selector)) {
142
- return role;
143
- }
155
+ for (const role of (candidates || Object.keys(constants.roles))) {
156
+ const r = constants.roles[role];
157
+ if (!r.abstract && r.selectors && el.matches(r.selectors.join(','))) {
158
+ return role;
144
159
  }
145
160
  }
146
161
  }
147
162
  };
148
163
 
149
- var hasRole = function(el, roles) {
150
- var candidates = [].concat.apply([], roles.map(role => {
151
- return (constants.roles[role] || {}).subRoles || [role];
152
- }));
153
- return !!getRole(el, candidates);
164
+ const hasRole = function(el, roles) {
165
+ const subRoles = normalizeRoles(roles, true).map(role => {
166
+ return constants.roles[role].subRoles || [role];
167
+ });
168
+ return !!getRole(el, unique(flatten(subRoles)));
154
169
  };
155
170
 
156
- var getAttribute = function(el, key) {
171
+ const getAttribute = function(el, key) {
157
172
  if (constants.attributeStrongMapping.hasOwnProperty(key)) {
158
- var value = el[constants.attributeStrongMapping[key]];
173
+ const value = el[constants.attributeStrongMapping[key]];
159
174
  if (value) {
160
175
  return value;
161
176
  }
@@ -172,14 +187,14 @@ var getAttribute = function(el, key) {
172
187
  if (el.matches('details:not([open]) > :not(summary)')) {
173
188
  return true;
174
189
  }
175
- var style = window.getComputedStyle(el);
190
+ const style = window.getComputedStyle(el);
176
191
  if (style.display === 'none' || style.visibility === 'hidden') {
177
192
  return true;
178
193
  }
179
194
  }
180
195
 
181
- var type = constants.attributes[key];
182
- var raw = el.getAttribute('aria-' + key);
196
+ const type = constants.attributes[key];
197
+ const raw = el.getAttribute('aria-' + key);
183
198
 
184
199
  if (raw) {
185
200
  if (type === 'bool') {
@@ -208,7 +223,7 @@ var getAttribute = function(el, key) {
208
223
  // list -> aria-controls
209
224
 
210
225
  if (key === 'level') {
211
- for (var i = 1; i <= 6; i++) {
226
+ for (let i = 1; i <= 6; i++) {
212
227
  if (el.tagName.toLowerCase() === 'h' + i) {
213
228
  return i;
214
229
  }
@@ -218,8 +233,8 @@ var getAttribute = function(el, key) {
218
233
  }
219
234
 
220
235
  if (key in constants.attrsWithDefaults) {
221
- var role = getRole(el);
222
- var defaults = (constants.roles[role] || {}).defaults;
236
+ const role = getRole(el);
237
+ const defaults = constants.roles[role].defaults;
223
238
  if (defaults && defaults.hasOwnProperty(key)) {
224
239
  return defaults[key];
225
240
  }
@@ -306,7 +321,7 @@ exports.attributeWeakMapping = {
306
321
  };
307
322
 
308
323
  // https://www.w3.org/TR/html/dom.html#sectioning-content-2
309
- var scoped = ['article *', 'aside *', 'nav *', 'section *'].join(',');
324
+ const scoped = ['article *', 'aside *', 'nav *', 'section *'].join(',');
310
325
 
311
326
  // https://www.w3.org/TR/html-aam-1.0/#html-element-role-mappings
312
327
  // https://www.w3.org/TR/wai-aria/roles
@@ -318,6 +333,8 @@ exports.roles = {
318
333
  'atomic': true,
319
334
  },
320
335
  },
336
+ alertdialog: {},
337
+ application: {},
321
338
  article: {
322
339
  selectors: ['article'],
323
340
  },
@@ -342,7 +359,7 @@ exports.roles = {
342
359
  selectors: ['caption', 'figcaption'],
343
360
  },
344
361
  cell: {
345
- selectors: ['td', 'th:not([scope])'],
362
+ selectors: ['td', 'td ~ th:not([scope])'],
346
363
  childRoles: ['columnheader', 'gridcell', 'rowheader'],
347
364
  nameFromContents: true,
348
365
  },
@@ -379,6 +396,7 @@ exports.roles = {
379
396
  },
380
397
  },
381
398
  command: {
399
+ abstract: true,
382
400
  childRoles: ['button', 'link', 'menuitem'],
383
401
  },
384
402
  complementary: {
@@ -390,6 +408,7 @@ exports.roles = {
390
408
  ],
391
409
  },
392
410
  composite: {
411
+ abstract: true,
393
412
  childRoles: ['grid', 'select', 'spinbutton', 'tablist'],
394
413
  },
395
414
  contentinfo: {
@@ -405,24 +424,59 @@ exports.roles = {
405
424
  selectors: ['dialog'],
406
425
  childRoles: ['alertdialog'],
407
426
  },
427
+ 'doc-abstract': {},
428
+ 'doc-acknowledgments': {},
429
+ 'doc-afterword': {},
430
+ 'doc-appendix': {},
408
431
  'doc-backlink': {
409
432
  nameFromContents: true,
410
433
  },
434
+ 'doc-biblioentry': {},
435
+ 'doc-bibliography': {},
411
436
  'doc-biblioref': {
412
437
  nameFromContents: true,
413
438
  },
439
+ 'doc-chapter': {},
440
+ 'doc-colophon': {},
441
+ 'doc-conclusion': {},
442
+ 'doc-cover': {},
443
+ 'doc-credit': {},
444
+ 'doc-credits': {},
445
+ 'doc-dedication': {},
446
+ 'doc-endnote': {},
447
+ 'doc-endnotes': {},
448
+ 'doc-epilogue': {},
449
+ 'doc-epigraph': {},
450
+ 'doc-errata': {},
451
+ 'doc-example': {},
452
+ 'doc-footnote': {},
453
+ 'doc-foreword': {},
454
+ 'doc-glossary': {},
414
455
  'doc-glossref': {
415
456
  nameFromContents: true,
416
457
  },
458
+ 'doc-index': {},
459
+ 'doc-introduction': {},
417
460
  'doc-noteref': {
418
461
  nameFromContents: true,
419
462
  },
463
+ 'doc-notice': {},
420
464
  'doc-pagebreak': {
421
465
  nameFromContents: true,
422
466
  },
467
+ 'doc-pagefooter': {},
468
+ 'doc-pageheader': {},
469
+ 'doc-pagelist': {},
470
+ 'doc-part': {},
471
+ 'doc-preface': {},
472
+ 'doc-prologue': {},
473
+ 'doc-pullquote': {},
474
+ 'doc-qna': {},
423
475
  'doc-subtitle': {
424
476
  nameFromContents: true,
425
477
  },
478
+ 'doc-tip': {},
479
+ 'doc-toc': {},
426
480
  document: {
427
481
  selectors: ['html'],
428
482
  childRoles: ['article', 'graphics-document'],
@@ -430,6 +484,7 @@ exports.roles = {
430
484
  emphasis: {
431
485
  selectors: ['em'],
432
486
  },
487
+ feed: {},
433
488
  figure: {
434
489
  selectors: ['figure'],
435
490
  childRoles: ['doc-example'],
@@ -438,11 +493,34 @@ exports.roles = {
438
493
  selectors: ['form[aria-label]', 'form[aria-labelledby]', 'form[title]'],
439
494
  },
440
495
  generic: {
441
- // too many selectors to list
496
+ selectors: [
497
+ 'a:not([href])',
498
+ 'area:not([href])',
499
+ `aside:not(${scoped}):not([aria-label]):not([aria-labelledby]):not([title])`,
500
+ 'b',
501
+ 'bdi',
502
+ 'bdo',
503
+ 'body',
504
+ 'data',
505
+ 'div',
506
+ // footer scoped
507
+ // header scoped
508
+ 'i',
509
+ 'li:not(ul > li):not(ol > li)',
510
+ 'pre',
511
+ 'q',
512
+ 'samp',
513
+ 'section:not([aria-label]):not([aria-labelledby]):not([title])',
514
+ 'small',
515
+ 'span',
516
+ 'u',
517
+ ],
442
518
  },
443
519
  'graphics-document': {
444
520
  selectors: ['svg'],
445
521
  },
522
+ 'graphics-object': {},
523
+ 'graphics-symbol': {},
446
524
  grid: {
447
525
  childRoles: ['treegrid'],
448
526
  },
@@ -473,6 +551,7 @@ exports.roles = {
473
551
  childRoles: ['doc-cover'],
474
552
  },
475
553
  input: {
554
+ abstract: true,
476
555
  childRoles: [
477
556
  'checkbox',
478
557
  'combobox',
@@ -487,6 +566,7 @@ exports.roles = {
487
566
  selectors: ['ins'],
488
567
  },
489
568
  landmark: {
569
+ abstract: true,
490
570
  childRoles: [
491
571
  'banner',
492
572
  'complementary',
@@ -521,7 +601,7 @@ exports.roles = {
521
601
  },
522
602
  list: {
523
603
  selectors: ['dl', 'ol', 'ul', 'menu'],
524
- childRoles: ['directory', 'feed'],
604
+ childRoles: ['feed'],
525
605
  },
526
606
  listbox: {
527
607
  selectors: [
@@ -534,7 +614,7 @@ exports.roles = {
534
614
  },
535
615
  },
536
616
  listitem: {
537
- selectors: ['li'],
617
+ selectors: ['ol > li', 'ul > li'],
538
618
  childRoles: ['doc-biblioentry', 'doc-endnote', 'treeitem'],
539
619
  },
540
620
  log: {
@@ -545,6 +625,7 @@ exports.roles = {
545
625
  main: {
546
626
  selectors: ['main'],
547
627
  },
628
+ marquee: {},
548
629
  math: {
549
630
  selectors: ['math'],
550
631
  },
@@ -587,6 +668,9 @@ exports.roles = {
587
668
  selectors: ['nav'],
588
669
  childRoles: ['doc-index', 'doc-pagelist', 'doc-toc'],
589
670
  },
671
+ none: {
672
+ selectors: ['img[alt=""]'],
673
+ },
590
674
  note: {
591
675
  childRoles: ['doc-notice', 'doc-tip'],
592
676
  },
@@ -601,9 +685,6 @@ exports.roles = {
601
685
  paragraph: {
602
686
  selectors: ['p'],
603
687
  },
604
- presentation: {
605
- selectors: ['img[alt=""]'],
606
- },
607
688
  progressbar: {
608
689
  selectors: ['progress'],
609
690
  defaults: {
@@ -619,13 +700,16 @@ exports.roles = {
619
700
  'checked': 'false',
620
701
  },
621
702
  },
703
+ radiogroup: {},
622
704
  range: {
705
+ abstract: true,
623
706
  childRoles: ['meter', 'progressbar', 'scrollbar', 'slider', 'spinbutton'],
624
707
  },
625
708
  region: {
626
709
  selectors: ['section[aria-label]', 'section[aria-labelledby]', 'section[title]'],
627
710
  },
628
711
  roletype: {
712
+ abstract: true,
629
713
  childRoles: ['structure', 'widget', 'window'],
630
714
  },
631
715
  row: {
@@ -636,7 +720,7 @@ exports.roles = {
636
720
  selectors: ['tbody', 'thead', 'tfoot'],
637
721
  },
638
722
  rowheader: {
639
- selectors: ['th[scope="row"]'],
723
+ selectors: ['th[scope="row"]', 'th:not([scope]):not(td ~ th)'],
640
724
  nameFromContents: true,
641
725
  },
642
726
  scrollbar: {
@@ -653,6 +737,7 @@ exports.roles = {
653
737
  selectors: ['input[type="search"]:not([list])'],
654
738
  },
655
739
  section: {
740
+ abstract: true,
656
741
  childRoles: [
657
742
  'alert',
658
743
  'blockquote',
@@ -696,6 +781,7 @@ exports.roles = {
696
781
  ],
697
782
  },
698
783
  sectionhead: {
784
+ abstract: true,
699
785
  childRoles: [
700
786
  'columnheader',
701
787
  'doc-subtitle',
@@ -706,6 +792,7 @@ exports.roles = {
706
792
  nameFromContents: true,
707
793
  },
708
794
  select: {
795
+ abstract: true,
709
796
  childRoles: ['listbox', 'menu', 'radiogroup', 'tree'],
710
797
  },
711
798
  separator: {
@@ -746,12 +833,12 @@ exports.roles = {
746
833
  selectors: ['strong'],
747
834
  },
748
835
  structure: {
836
+ abstract: true,
749
837
  childRoles: [
750
838
  'application',
751
839
  'document',
752
840
  'none',
753
841
  'generic',
754
- 'presentation',
755
842
  'range',
756
843
  'rowgroup',
757
844
  'section',
@@ -759,6 +846,7 @@ exports.roles = {
759
846
  'separator',
760
847
  ],
761
848
  },
849
+ suggestion: {},
762
850
  subscript: {
763
851
  selectors: ['sub'],
764
852
  },
@@ -786,6 +874,7 @@ exports.roles = {
786
874
  'orientation': 'horizontal',
787
875
  },
788
876
  },
877
+ tabpanel: {},
789
878
  term: {
790
879
  selectors: ['dfn', 'dt'],
791
880
  },
@@ -822,10 +911,12 @@ exports.roles = {
822
911
  'orientation': 'vertical',
823
912
  },
824
913
  },
914
+ treegrid: {},
825
915
  treeitem: {
826
916
  nameFromContents: true,
827
917
  },
828
918
  widget: {
919
+ abstract: true,
829
920
  childRoles: [
830
921
  'command',
831
922
  'composite',
@@ -839,15 +930,16 @@ exports.roles = {
839
930
  ],
840
931
  },
841
932
  window: {
933
+ abstract: true,
842
934
  childRoles: ['dialog'],
843
935
  },
844
936
  };
845
937
 
846
- var getSubRoles = function(role) {
847
- var children = (exports.roles[role] || {}).childRoles || [];
848
- var descendents = children.map(getSubRoles);
938
+ const getSubRoles = function(role) {
939
+ const children = (exports.roles[role]).childRoles || [];
940
+ const descendents = children.map(getSubRoles);
849
941
 
850
- var result = [role];
942
+ const result = [role];
851
943
 
852
944
  descendents.forEach(list => {
853
945
  list.forEach(r => {
@@ -862,18 +954,19 @@ var getSubRoles = function(role) {
862
954
 
863
955
  exports.attrsWithDefaults = [];
864
956
 
865
- for (var role in exports.roles) {
957
+ for (const role in exports.roles) {
866
958
  exports.roles[role].subRoles = getSubRoles(role);
867
- for (var key in exports.roles[role].defaults) {
959
+ for (const key in exports.roles[role].defaults) {
868
960
  if (!exports.attrsWithDefaults.includes(key)) {
869
961
  exports.attrsWithDefaults.push(key);
870
962
  }
871
963
  }
872
964
  }
873
- exports.roles['none'] = exports.roles['none'] || {};
874
- exports.roles['none'].subRoles = ['none', 'presentation'];
875
- exports.roles['presentation'] = exports.roles['presentation'] || {};
876
- exports.roles['presentation'].subRoles = ['presentation', 'none'];
965
+
966
+ exports.aliases = {
967
+ 'presentation': 'none',
968
+ 'directory': 'list',
969
+ };
877
970
 
878
971
  exports.nameFromDescendant = {
879
972
  'figure': 'figcaption',
@@ -888,14 +981,14 @@ exports.nameDefaults = {
888
981
  };
889
982
 
890
983
  },{}],5:[function(require,module,exports){
891
- var constants = require('./constants.js');
892
- var atree = require('./atree.js');
893
- var query = require('./query.js');
894
-
895
- var getPseudoContent = function(node, selector) {
896
- var styles = window.getComputedStyle(node, selector);
897
- var ret = styles.getPropertyValue('content');
898
- var inline = styles.display.substr(0, 6) === 'inline';
984
+ const constants = require('./constants.js');
985
+ const atree = require('./atree.js');
986
+ const query = require('./query.js');
987
+
988
+ const getPseudoContent = function(node, selector) {
989
+ const styles = window.getComputedStyle(node, selector);
990
+ const ret = styles.getPropertyValue('content');
991
+ const inline = styles.display.substr(0, 6) === 'inline';
899
992
  if (!ret) {
900
993
  return '';
901
994
  }
@@ -910,12 +1003,12 @@ var getPseudoContent = function(node, selector) {
910
1003
  }
911
1004
  };
912
1005
 
913
- var getContent = function(root, visited) {
914
- var children = atree.getChildNodes(root);
1006
+ const getContent = function(root, visited) {
1007
+ const children = atree.getChildNodes(root);
915
1008
 
916
- var ret = '';
917
- for (var i = 0; i < children.length; i++) {
918
- var node = children[i];
1009
+ let ret = '';
1010
+ for (let i = 0; i < children.length; i++) {
1011
+ const node = children[i];
919
1012
  if (node.nodeType === node.TEXT_NODE) {
920
1013
  ret += node.textContent;
921
1014
  } else if (node.nodeType === node.ELEMENT_NODE) {
@@ -934,18 +1027,15 @@ var getContent = function(root, visited) {
934
1027
  return ret;
935
1028
  };
936
1029
 
937
- var allowNameFromContent = function(el) {
938
- var role = query.getRole(el);
939
- return (constants.roles[role] || {}).nameFromContents;
940
- };
941
-
942
- var isInLabelForOtherWidget = function(el) {
943
- var label = el.parentElement.closest('label');
944
- return label && (!el.labels || !Array.prototype.includes.call(el.labels, label));
1030
+ const allowNameFromContent = function(el) {
1031
+ const role = query.getRole(el);
1032
+ if (role) {
1033
+ return constants.roles[role].nameFromContents;
1034
+ }
945
1035
  };
946
1036
 
947
- var getName = function(el, recursive, visited, directReference) {
948
- var ret = '';
1037
+ const getName = function(el, recursive, visited, directReference) {
1038
+ let ret = '';
949
1039
 
950
1040
  visited = visited || [];
951
1041
  if (visited.includes(el)) {
@@ -961,14 +1051,30 @@ var getName = function(el, recursive, visited, directReference) {
961
1051
 
962
1052
  // B
963
1053
  if (!recursive && el.matches('[aria-labelledby]')) {
964
- var ids = el.getAttribute('aria-labelledby').split(/\s+/);
965
- var strings = ids.map(id => {
966
- var label = document.getElementById(id);
1054
+ const ids = el.getAttribute('aria-labelledby').split(/\s+/);
1055
+ const strings = ids.map(id => {
1056
+ const label = document.getElementById(id);
967
1057
  return label ? getName(label, true, visited, true) : '';
968
1058
  });
969
1059
  ret = strings.join(' ');
970
1060
  }
971
1061
 
1062
+ // E (the current draft has this at this high priority)
1063
+ if (!ret.trim() && recursive) {
1064
+ if (query.matches(el, 'textbox,button')) {
1065
+ ret = el.value || el.textContent;
1066
+ } else if (query.matches(el, 'combobox,listbox')) {
1067
+ const selected = query.querySelector(el, ':selected') || query.querySelector(el, 'option');
1068
+ if (selected) {
1069
+ ret = getName(selected, recursive, visited);
1070
+ } else {
1071
+ ret = el.value || '';
1072
+ }
1073
+ } else if (query.matches(el, 'range')) {
1074
+ ret = '' + (query.getAttribute(el, 'valuetext') || query.getAttribute(el, 'valuenow') || el.value);
1075
+ }
1076
+ }
1077
+
972
1078
  // C
973
1079
  if (!ret.trim() && el.matches('[aria-label]')) {
974
1080
  // FIXME: may skip to 2E
@@ -977,7 +1083,7 @@ var getName = function(el, recursive, visited, directReference) {
977
1083
 
978
1084
  // D
979
1085
  if (!ret.trim() && !recursive && el.labels) {
980
- var strings = Array.prototype.map.call(el.labels, label => {
1086
+ const strings = Array.prototype.map.call(el.labels, label => {
981
1087
  return getName(label, true, visited);
982
1088
  });
983
1089
  ret = strings.join(' ');
@@ -992,9 +1098,9 @@ var getName = function(el, recursive, visited, directReference) {
992
1098
  ret = el.title;
993
1099
  }
994
1100
  if (!ret.trim()) {
995
- for (var selector in constants.nameFromDescendant) {
1101
+ for (const selector in constants.nameFromDescendant) {
996
1102
  if (el.matches(selector)) {
997
- var descendant = el.querySelector(constants.nameFromDescendant[selector]);
1103
+ const descendant = el.querySelector(constants.nameFromDescendant[selector]);
998
1104
  if (descendant) {
999
1105
  ret = getName(descendant, true, visited);
1000
1106
  }
@@ -1002,38 +1108,24 @@ var getName = function(el, recursive, visited, directReference) {
1002
1108
  }
1003
1109
  }
1004
1110
  if (!ret.trim() && el.matches('svg *')) {
1005
- var svgTitle = el.querySelector('title');
1111
+ const svgTitle = el.querySelector('title');
1006
1112
  if (svgTitle && svgTitle.parentElement === el) {
1007
1113
  ret = svgTitle.textContent;
1008
1114
  }
1009
1115
  }
1010
1116
 
1011
- // E
1012
- if (!ret.trim() && (recursive || isInLabelForOtherWidget(el) || query.matches(el, 'button'))) {
1013
- if (query.matches(el, 'textbox,button,combobox,listbox,range')) {
1014
- if (query.matches(el, 'textbox,button')) {
1015
- ret = el.value || el.textContent;
1016
- } else if (query.matches(el, 'combobox,listbox')) {
1017
- var selected = query.querySelector(el, ':selected') || query.querySelector(el, 'option');
1018
- if (selected) {
1019
- ret = getName(selected, recursive, visited);
1020
- } else {
1021
- ret = el.value || '';
1022
- }
1023
- } else if (query.matches(el, 'range')) {
1024
- ret = '' + (query.getAttribute(el, 'valuetext') || query.getAttribute(el, 'valuenow') || el.value);
1025
- }
1026
- }
1027
- }
1028
-
1029
1117
  // F
1030
1118
  // FIXME: menu is not mentioned in the spec
1031
1119
  if (!ret.trim() && (recursive || allowNameFromContent(el) || el.closest('label')) && !query.matches(el, 'menu')) {
1032
1120
  ret = getContent(el, visited);
1033
1121
  }
1034
1122
 
1123
+ if (!ret.trim() && query.matches(el, 'button')) {
1124
+ ret = el.value || '';
1125
+ }
1126
+
1035
1127
  if (!ret.trim()) {
1036
- for (var selector in constants.nameDefaults) {
1128
+ for (const selector in constants.nameDefaults) {
1037
1129
  if (el.matches(selector)) {
1038
1130
  ret = constants.nameDefaults[selector];
1039
1131
  }
@@ -1055,29 +1147,29 @@ var getName = function(el, recursive, visited, directReference) {
1055
1147
  ret = ' ';
1056
1148
  }
1057
1149
 
1058
- var before = getPseudoContent(el, ':before');
1059
- var after = getPseudoContent(el, ':after');
1150
+ const before = getPseudoContent(el, ':before');
1151
+ const after = getPseudoContent(el, ':after');
1060
1152
  return before + ret + after;
1061
1153
  };
1062
1154
 
1063
- var getNameTrimmed = function(el) {
1155
+ const getNameTrimmed = function(el) {
1064
1156
  return getName(el).replace(/\s+/g, ' ').trim();
1065
1157
  };
1066
1158
 
1067
- var getDescription = function(el) {
1068
- var ret = '';
1159
+ const getDescription = function(el) {
1160
+ let ret = '';
1069
1161
 
1070
1162
  if (el.matches('[aria-describedby]')) {
1071
- var ids = el.getAttribute('aria-describedby').split(/\s+/);
1072
- var strings = ids.map(id => {
1073
- var label = document.getElementById(id);
1163
+ const ids = el.getAttribute('aria-describedby').split(/\s+/);
1164
+ const strings = ids.map(id => {
1165
+ const label = document.getElementById(id);
1074
1166
  return label ? getName(label, true) : '';
1075
1167
  });
1076
1168
  ret = strings.join(' ');
1077
1169
  } else if (el.matches('[aria-description]')) {
1078
1170
  ret = el.getAttribute('aria-description');
1079
1171
  } else if (el.matches('svg *')) {
1080
- var svgDesc = el.querySelector('desc');
1172
+ const svgDesc = el.querySelector('desc');
1081
1173
  if (svgDesc && svgDesc.parentElement === el) {
1082
1174
  ret = svgDesc.textContent;
1083
1175
  }
@@ -1100,34 +1192,32 @@ module.exports = {
1100
1192
  };
1101
1193
 
1102
1194
  },{"./atree.js":2,"./constants.js":4,"./query.js":6}],6:[function(require,module,exports){
1103
- var attrs = require('./attrs.js');
1104
- var atree = require('./atree.js');
1105
-
1195
+ const attrs = require('./attrs.js');
1196
+ const atree = require('./atree.js');
1106
1197
 
1107
- var matches = function(el, selector) {
1108
- var actual;
1109
1198
 
1199
+ const matches = function(el, selector) {
1110
1200
  if (selector.substr(0, 1) === ':') {
1111
- var attr = selector.substr(1);
1201
+ const attr = selector.substr(1);
1112
1202
  return attrs.getAttribute(el, attr);
1113
1203
  } else if (selector.substr(0, 1) === '[') {
1114
- var match = /\[([a-z]+)="(.*)"\]/.exec(selector);
1115
- actual = attrs.getAttribute(el, match[1]);
1116
- var rawValue = match[2];
1204
+ const match = /\[([a-z]+)="(.*)"\]/.exec(selector);
1205
+ const actual = attrs.getAttribute(el, match[1]);
1206
+ const rawValue = match[2];
1117
1207
  return actual.toString() === rawValue;
1118
1208
  } else {
1119
1209
  return attrs.hasRole(el, selector.split(','));
1120
1210
  }
1121
1211
  };
1122
1212
 
1123
- var _querySelector = function(all) {
1124
- return function(root, role) {
1125
- var results = [];
1213
+ const _querySelector = function(all) {
1214
+ return function(root, selector) {
1215
+ const results = [];
1126
1216
  try {
1127
1217
  atree.walk(root, node => {
1128
1218
  if (node.nodeType === node.ELEMENT_NODE) {
1129
1219
  // FIXME: skip hidden elements
1130
- if (matches(node, role)) {
1220
+ if (matches(node, selector)) {
1131
1221
  results.push(node);
1132
1222
  if (!all) {
1133
1223
  throw 'StopIteration';
@@ -1144,7 +1234,7 @@ var _querySelector = function(all) {
1144
1234
  };
1145
1235
  };
1146
1236
 
1147
- var closest = function(el, selector) {
1237
+ const closest = function(el, selector) {
1148
1238
  return atree.searchUp(el, candidate => {
1149
1239
  if (candidate.nodeType === candidate.ELEMENT_NODE) {
1150
1240
  return matches(candidate, selector);