sorter.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /* eslint-disable */
  2. var addSorting = (function() {
  3. 'use strict';
  4. var cols,
  5. currentSort = {
  6. index: 0,
  7. desc: false
  8. };
  9. // returns the summary table element
  10. function getTable() {
  11. return document.querySelector('.coverage-summary');
  12. }
  13. // returns the thead element of the summary table
  14. function getTableHeader() {
  15. return getTable().querySelector('thead tr');
  16. }
  17. // returns the tbody element of the summary table
  18. function getTableBody() {
  19. return getTable().querySelector('tbody');
  20. }
  21. // returns the th element for nth column
  22. function getNthColumn(n) {
  23. return getTableHeader().querySelectorAll('th')[n];
  24. }
  25. // loads all columns
  26. function loadColumns() {
  27. var colNodes = getTableHeader().querySelectorAll('th'),
  28. colNode,
  29. cols = [],
  30. col,
  31. i;
  32. for (i = 0; i < colNodes.length; i += 1) {
  33. colNode = colNodes[i];
  34. col = {
  35. key: colNode.getAttribute('data-col'),
  36. sortable: !colNode.getAttribute('data-nosort'),
  37. type: colNode.getAttribute('data-type') || 'string'
  38. };
  39. cols.push(col);
  40. if (col.sortable) {
  41. col.defaultDescSort = col.type === 'number';
  42. colNode.innerHTML =
  43. colNode.innerHTML + '<span class="sorter"></span>';
  44. }
  45. }
  46. return cols;
  47. }
  48. // attaches a data attribute to every tr element with an object
  49. // of data values keyed by column name
  50. function loadRowData(tableRow) {
  51. var tableCols = tableRow.querySelectorAll('td'),
  52. colNode,
  53. col,
  54. data = {},
  55. i,
  56. val;
  57. for (i = 0; i < tableCols.length; i += 1) {
  58. colNode = tableCols[i];
  59. col = cols[i];
  60. val = colNode.getAttribute('data-value');
  61. if (col.type === 'number') {
  62. val = Number(val);
  63. }
  64. data[col.key] = val;
  65. }
  66. return data;
  67. }
  68. // loads all row data
  69. function loadData() {
  70. var rows = getTableBody().querySelectorAll('tr'),
  71. i;
  72. for (i = 0; i < rows.length; i += 1) {
  73. rows[i].data = loadRowData(rows[i]);
  74. }
  75. }
  76. // sorts the table using the data for the ith column
  77. function sortByIndex(index, desc) {
  78. var key = cols[index].key,
  79. sorter = function(a, b) {
  80. a = a.data[key];
  81. b = b.data[key];
  82. return a < b ? -1 : a > b ? 1 : 0;
  83. },
  84. finalSorter = sorter,
  85. tableBody = document.querySelector('.coverage-summary tbody'),
  86. rowNodes = tableBody.querySelectorAll('tr'),
  87. rows = [],
  88. i;
  89. if (desc) {
  90. finalSorter = function(a, b) {
  91. return -1 * sorter(a, b);
  92. };
  93. }
  94. for (i = 0; i < rowNodes.length; i += 1) {
  95. rows.push(rowNodes[i]);
  96. tableBody.removeChild(rowNodes[i]);
  97. }
  98. rows.sort(finalSorter);
  99. for (i = 0; i < rows.length; i += 1) {
  100. tableBody.appendChild(rows[i]);
  101. }
  102. }
  103. // removes sort indicators for current column being sorted
  104. function removeSortIndicators() {
  105. var col = getNthColumn(currentSort.index),
  106. cls = col.className;
  107. cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, '');
  108. col.className = cls;
  109. }
  110. // adds sort indicators for current column being sorted
  111. function addSortIndicators() {
  112. getNthColumn(currentSort.index).className += currentSort.desc
  113. ? ' sorted-desc'
  114. : ' sorted';
  115. }
  116. // adds event listeners for all sorter widgets
  117. function enableUI() {
  118. var i,
  119. el,
  120. ithSorter = function ithSorter(i) {
  121. var col = cols[i];
  122. return function() {
  123. var desc = col.defaultDescSort;
  124. if (currentSort.index === i) {
  125. desc = !currentSort.desc;
  126. }
  127. sortByIndex(i, desc);
  128. removeSortIndicators();
  129. currentSort.index = i;
  130. currentSort.desc = desc;
  131. addSortIndicators();
  132. };
  133. };
  134. for (i = 0; i < cols.length; i += 1) {
  135. if (cols[i].sortable) {
  136. // add the click event handler on the th so users
  137. // dont have to click on those tiny arrows
  138. el = getNthColumn(i).querySelector('.sorter').parentElement;
  139. if (el.addEventListener) {
  140. el.addEventListener('click', ithSorter(i));
  141. } else {
  142. el.attachEvent('onclick', ithSorter(i));
  143. }
  144. }
  145. }
  146. }
  147. // adds sorting functionality to the UI
  148. return function() {
  149. if (!getTable()) {
  150. return;
  151. }
  152. cols = loadColumns();
  153. loadData();
  154. addSortIndicators();
  155. enableUI();
  156. };
  157. })();
  158. window.addEventListener('load', addSorting);