159 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			159 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| var addSorting = (function () {
 | |
|     "use strict";
 | |
|     var cols,
 | |
|         currentSort = {
 | |
|             index: 0,
 | |
|             desc: false
 | |
|         };
 | |
| 
 | |
|     // returns the summary table element
 | |
|     function getTable() { return document.querySelector('.coverage-summary'); }
 | |
|     // returns the thead element of the summary table
 | |
|     function getTableHeader() { return getTable().querySelector('thead tr'); }
 | |
|     // returns the tbody element of the summary table
 | |
|     function getTableBody() { return getTable().querySelector('tbody'); }
 | |
|     // returns the th element for nth column
 | |
|     function getNthColumn(n) { return getTableHeader().querySelectorAll('th')[n]; }
 | |
| 
 | |
|     // loads all columns
 | |
|     function loadColumns() {
 | |
|         var colNodes = getTableHeader().querySelectorAll('th'),
 | |
|             colNode,
 | |
|             cols = [],
 | |
|             col,
 | |
|             i;
 | |
| 
 | |
|         for (i = 0; i < colNodes.length; i += 1) {
 | |
|             colNode = colNodes[i];
 | |
|             col = {
 | |
|                 key: colNode.getAttribute('data-col'),
 | |
|                 sortable: !colNode.getAttribute('data-nosort'),
 | |
|                 type: colNode.getAttribute('data-type') || 'string'
 | |
|             };
 | |
|             cols.push(col);
 | |
|             if (col.sortable) {
 | |
|                 col.defaultDescSort = col.type === 'number';
 | |
|                 colNode.innerHTML = colNode.innerHTML + '<span class="sorter"></span>';
 | |
|             }
 | |
|         }
 | |
|         return cols;
 | |
|     }
 | |
|     // attaches a data attribute to every tr element with an object
 | |
|     // of data values keyed by column name
 | |
|     function loadRowData(tableRow) {
 | |
|         var tableCols = tableRow.querySelectorAll('td'),
 | |
|             colNode,
 | |
|             col,
 | |
|             data = {},
 | |
|             i,
 | |
|             val;
 | |
|         for (i = 0; i < tableCols.length; i += 1) {
 | |
|             colNode = tableCols[i];
 | |
|             col = cols[i];
 | |
|             val = colNode.getAttribute('data-value');
 | |
|             if (col.type === 'number') {
 | |
|                 val = Number(val);
 | |
|             }
 | |
|             data[col.key] = val;
 | |
|         }
 | |
|         return data;
 | |
|     }
 | |
|     // loads all row data
 | |
|     function loadData() {
 | |
|         var rows = getTableBody().querySelectorAll('tr'),
 | |
|             i;
 | |
| 
 | |
|         for (i = 0; i < rows.length; i += 1) {
 | |
|             rows[i].data = loadRowData(rows[i]);
 | |
|         }
 | |
|     }
 | |
|     // sorts the table using the data for the ith column
 | |
|     function sortByIndex(index, desc) {
 | |
|         var key = cols[index].key,
 | |
|             sorter = function (a, b) {
 | |
|                 a = a.data[key];
 | |
|                 b = b.data[key];
 | |
|                 return a < b ? -1 : a > b ? 1 : 0;
 | |
|             },
 | |
|             finalSorter = sorter,
 | |
|             tableBody = document.querySelector('.coverage-summary tbody'),
 | |
|             rowNodes = tableBody.querySelectorAll('tr'),
 | |
|             rows = [],
 | |
|             i;
 | |
| 
 | |
|         if (desc) {
 | |
|             finalSorter = function (a, b) {
 | |
|                 return -1 * sorter(a, b);
 | |
|             };
 | |
|         }
 | |
| 
 | |
|         for (i = 0; i < rowNodes.length; i += 1) {
 | |
|             rows.push(rowNodes[i]);
 | |
|             tableBody.removeChild(rowNodes[i]);
 | |
|         }
 | |
| 
 | |
|         rows.sort(finalSorter);
 | |
| 
 | |
|         for (i = 0; i < rows.length; i += 1) {
 | |
|             tableBody.appendChild(rows[i]);
 | |
|         }
 | |
|     }
 | |
|     // removes sort indicators for current column being sorted
 | |
|     function removeSortIndicators() {
 | |
|         var col = getNthColumn(currentSort.index),
 | |
|             cls = col.className;
 | |
| 
 | |
|         cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, '');
 | |
|         col.className = cls;
 | |
|     }
 | |
|     // adds sort indicators for current column being sorted
 | |
|     function addSortIndicators() {
 | |
|         getNthColumn(currentSort.index).className += currentSort.desc ? ' sorted-desc' : ' sorted';
 | |
|     }
 | |
|     // adds event listeners for all sorter widgets
 | |
|     function enableUI() {
 | |
|         var i,
 | |
|             el,
 | |
|             ithSorter = function ithSorter(i) {
 | |
|                 var col = cols[i];
 | |
| 
 | |
|                 return function () {
 | |
|                     var desc = col.defaultDescSort;
 | |
| 
 | |
|                     if (currentSort.index === i) {
 | |
|                         desc = !currentSort.desc;
 | |
|                     }
 | |
|                     sortByIndex(i, desc);
 | |
|                     removeSortIndicators();
 | |
|                     currentSort.index = i;
 | |
|                     currentSort.desc = desc;
 | |
|                     addSortIndicators();
 | |
|                 };
 | |
|             };
 | |
|         for (i =0 ; i < cols.length; i += 1) {
 | |
|             if (cols[i].sortable) {
 | |
|                 // add the click event handler on the th so users
 | |
|                 // dont have to click on those tiny arrows
 | |
|                 el = getNthColumn(i).querySelector('.sorter').parentElement;
 | |
|                 if (el.addEventListener) {
 | |
|                     el.addEventListener('click', ithSorter(i));
 | |
|                 } else {
 | |
|                     el.attachEvent('onclick', ithSorter(i));
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     // adds sorting functionality to the UI
 | |
|     return function () {
 | |
|         if (!getTable()) {
 | |
|             return;
 | |
|         }
 | |
|         cols = loadColumns();
 | |
|         loadData(cols);
 | |
|         addSortIndicators();
 | |
|         enableUI();
 | |
|     };
 | |
| })();
 | |
| 
 | |
| window.addEventListener('load', addSorting);
 |