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