| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 | 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);
 |