UNPKG

5.17 kBJavaScriptView Raw
1var addSorting = (function () {
2 "use strict";
3 var cols,
4 currentSort = {
5 index: 0,
6 desc: false
7 };
8
9 // returns the summary table element
10 function getTable() { return document.querySelector('.coverage-summary'); }
11 // returns the thead element of the summary table
12 function getTableHeader() { return getTable().querySelector('thead tr'); }
13 // returns the tbody element of the summary table
14 function getTableBody() { return getTable().querySelector('tbody'); }
15 // returns the th element for nth column
16 function getNthColumn(n) { return getTableHeader().querySelectorAll('th')[n]; }
17
18 // loads all columns
19 function loadColumns() {
20 var colNodes = getTableHeader().querySelectorAll('th'),
21 colNode,
22 cols = [],
23 col,
24 i;
25
26 for (i = 0; i < colNodes.length; i += 1) {
27 colNode = colNodes[i];
28 col = {
29 key: colNode.getAttribute('data-col'),
30 sortable: !colNode.getAttribute('data-nosort'),
31 type: colNode.getAttribute('data-type') || 'string'
32 };
33 cols.push(col);
34 if (col.sortable) {
35 col.defaultDescSort = col.type === 'number';
36 colNode.innerHTML = colNode.innerHTML + '<span class="sorter"></span>';
37 }
38 }
39 return cols;
40 }
41 // attaches a data attribute to every tr element with an object
42 // of data values keyed by column name
43 function loadRowData(tableRow) {
44 var tableCols = tableRow.querySelectorAll('td'),
45 colNode,
46 col,
47 data = {},
48 i,
49 val;
50 for (i = 0; i < tableCols.length; i += 1) {
51 colNode = tableCols[i];
52 col = cols[i];
53 val = colNode.getAttribute('data-value');
54 if (col.type === 'number') {
55 val = Number(val);
56 }
57 data[col.key] = val;
58 }
59 return data;
60 }
61 // loads all row data
62 function loadData() {
63 var rows = getTableBody().querySelectorAll('tr'),
64 i;
65
66 for (i = 0; i < rows.length; i += 1) {
67 rows[i].data = loadRowData(rows[i]);
68 }
69 }
70 // sorts the table using the data for the ith column
71 function sortByIndex(index, desc) {
72 var key = cols[index].key,
73 sorter = function (a, b) {
74 a = a.data[key];
75 b = b.data[key];
76 return a < b ? -1 : a > b ? 1 : 0;
77 },
78 finalSorter = sorter,
79 tableBody = document.querySelector('.coverage-summary tbody'),
80 rowNodes = tableBody.querySelectorAll('tr'),
81 rows = [],
82 i;
83
84 if (desc) {
85 finalSorter = function (a, b) {
86 return -1 * sorter(a, b);
87 };
88 }
89
90 for (i = 0; i < rowNodes.length; i += 1) {
91 rows.push(rowNodes[i]);
92 tableBody.removeChild(rowNodes[i]);
93 }
94
95 rows.sort(finalSorter);
96
97 for (i = 0; i < rows.length; i += 1) {
98 tableBody.appendChild(rows[i]);
99 }
100 }
101 // removes sort indicators for current column being sorted
102 function removeSortIndicators() {
103 var col = getNthColumn(currentSort.index),
104 cls = col.className;
105
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 ? ' sorted-desc' : ' sorted';
112 }
113 // adds event listeners for all sorter widgets
114 function enableUI() {
115 var i,
116 el,
117 ithSorter = function ithSorter(i) {
118 var col = cols[i];
119
120 return function () {
121 var desc = col.defaultDescSort;
122
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(cols);
153 addSortIndicators();
154 enableUI();
155 };
156})();
157
158window.addEventListener('load', addSorting);