sorter.js 4.4 KB

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