label-virtual.js 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. import ariaLabelVirtual from '../aria/label-virtual';
  2. import visible from './visible';
  3. import visibleVirtual from './visible-virtual';
  4. import getRootNode from '../dom/get-root-node';
  5. import { closest, escapeSelector } from '../../core/utils';
  6. /**
  7. * Gets the visible text of a label for a given input
  8. * @see http://www.w3.org/WAI/PF/aria/roles#namecalculation
  9. * @method labelVirtual
  10. * @memberof axe.commons.text
  11. * @instance
  12. * @param {VirtualNode} node The virtual node mapping to the input to test
  13. * @return {Mixed} String of visible text, or `null` if no label is found
  14. */
  15. function labelVirtual(virtualNode) {
  16. var ref, candidate, doc;
  17. candidate = ariaLabelVirtual(virtualNode);
  18. if (candidate) {
  19. return candidate;
  20. }
  21. // explicit label
  22. if (virtualNode.attr('id')) {
  23. if (!virtualNode.actualNode) {
  24. throw new TypeError(
  25. 'Cannot resolve explicit label reference for non-DOM nodes'
  26. );
  27. }
  28. const id = escapeSelector(virtualNode.attr('id'));
  29. doc = getRootNode(virtualNode.actualNode);
  30. ref = doc.querySelector('label[for="' + id + '"]');
  31. candidate = ref && visible(ref, true);
  32. if (candidate) {
  33. return candidate;
  34. }
  35. }
  36. ref = closest(virtualNode, 'label');
  37. candidate = ref && visibleVirtual(ref, true);
  38. if (candidate) {
  39. return candidate;
  40. }
  41. return null;
  42. }
  43. export default labelVirtual;