th-has-data-cells-evaluate.js 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import * as tableUtils from '../../commons/table';
  2. import { sanitize } from '../../commons/text';
  3. function thHasDataCellsEvaluate(node) {
  4. const cells = tableUtils.getAllCells(node);
  5. const checkResult = this;
  6. // Get a list of all headers reffed to in this rule
  7. let reffedHeaders = [];
  8. cells.forEach(cell => {
  9. const headers = cell.getAttribute('headers');
  10. if (headers) {
  11. reffedHeaders = reffedHeaders.concat(headers.split(/\s+/));
  12. }
  13. const ariaLabel = cell.getAttribute('aria-labelledby');
  14. if (ariaLabel) {
  15. reffedHeaders = reffedHeaders.concat(ariaLabel.split(/\s+/));
  16. }
  17. });
  18. // Get all the headers
  19. const headers = cells.filter(cell => {
  20. if (sanitize(cell.textContent) === '') {
  21. return false;
  22. }
  23. return (
  24. cell.nodeName.toUpperCase() === 'TH' ||
  25. ['rowheader', 'columnheader'].indexOf(cell.getAttribute('role')) !== -1
  26. );
  27. });
  28. const tableGrid = tableUtils.toGrid(node);
  29. let out = true;
  30. headers.forEach(header => {
  31. if (
  32. header.getAttribute('id') &&
  33. reffedHeaders.includes(header.getAttribute('id'))
  34. ) {
  35. return;
  36. }
  37. const pos = tableUtils.getCellPosition(header, tableGrid);
  38. // ensure column header has at least 1 non-header cell and that the cell is
  39. // not pointing to a different header
  40. let hasCell = false;
  41. if (tableUtils.isColumnHeader(header)) {
  42. hasCell = tableUtils
  43. .traverse('down', pos, tableGrid)
  44. .find(
  45. cell =>
  46. !tableUtils.isColumnHeader(cell) &&
  47. tableUtils.getHeaders(cell, tableGrid).includes(header)
  48. );
  49. }
  50. // ensure row header has at least 1 non-header cell and that the cell is not
  51. // pointing to a different header
  52. if (!hasCell && tableUtils.isRowHeader(header)) {
  53. hasCell = tableUtils
  54. .traverse('right', pos, tableGrid)
  55. .find(
  56. cell =>
  57. !tableUtils.isRowHeader(cell) &&
  58. tableUtils.getHeaders(cell, tableGrid).includes(header)
  59. );
  60. }
  61. // report the node as having failed
  62. if (!hasCell) {
  63. checkResult.relatedNodes(header);
  64. }
  65. out = out && hasCell;
  66. });
  67. return out ? true : undefined;
  68. }
  69. export default thHasDataCellsEvaluate;