get-scope.js 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. import toGrid from './to-grid';
  2. import getCellPosition from './get-cell-position';
  3. import findUp from '../dom/find-up';
  4. /**
  5. * Determine if a `HTMLTableCellElement` is a column header, if so get the scope of the header
  6. * @method getScope
  7. * @memberof axe.commons.table
  8. * @instance
  9. * @param {HTMLTableCellElement} cell The table cell to test
  10. * @return {Boolean|String} Returns `false` if not a column header, or the scope of the column header element
  11. */
  12. function getScope(cell) {
  13. var scope = cell.getAttribute('scope');
  14. var role = cell.getAttribute('role');
  15. if (
  16. cell instanceof window.Element === false ||
  17. ['TD', 'TH'].indexOf(cell.nodeName.toUpperCase()) === -1
  18. ) {
  19. throw new TypeError('Expected TD or TH element');
  20. }
  21. if (role === 'columnheader') {
  22. return 'col';
  23. } else if (role === 'rowheader') {
  24. return 'row';
  25. } else if (scope === 'col' || scope === 'row') {
  26. return scope;
  27. } else if (cell.nodeName.toUpperCase() !== 'TH') {
  28. return false;
  29. }
  30. var tableGrid = toGrid(findUp(cell, 'table'));
  31. var pos = getCellPosition(cell, tableGrid);
  32. // The element is in a row with all th elements, that makes it a column header
  33. var headerRow = tableGrid[pos.y].reduce((headerRow, cell) => {
  34. return headerRow && cell.nodeName.toUpperCase() === 'TH';
  35. }, true);
  36. if (headerRow) {
  37. return 'col';
  38. }
  39. // The element is in a column with all th elements, that makes it a row header
  40. var headerCol = tableGrid
  41. .map(col => col[pos.x])
  42. .reduce((headerCol, cell) => {
  43. return headerCol && cell && cell.nodeName.toUpperCase() === 'TH';
  44. }, true);
  45. if (headerCol) {
  46. return 'row';
  47. }
  48. return 'auto';
  49. }
  50. export default getScope;