// Make the class reference table sortable in ascending or descending order // when a header is clicked. // Helper function to return the content from the idx-th cell of row tr const getCellValue = (tr, idx) => tr.children[idx].textContent; // Array sorting functions for different columns used by the comparer // Compares the Desc. and Brief Desc. columns // "MISSING" comes first in ascending order const descriptionComparer = function(v1, v2) { if(v1 == v2) return 0 if(v1 == "OK") return 1 return -1 } // Compares the Name and Docs URL columns using a basic string sort const stringComparer = (new Intl.Collator()).compare // Compares the Overall column by completion percentage const overallComparer = function(v1, v2) { return Number(v1.replace("%", "")) - Number(v2.replace("%", "")) } // Compares the other columns (constructors, methods, members, etc.) // by the percentage they're finished. // If two have the same percentage, they're compared by denominator size. const fractionComparer = (asc) => function(v1, v2) { if(v1 == v2) return 0 // Always send 0/0 values to the bottom // The "asc" parameter is needed for that purpose. if(v1 == "0/0") { return asc ? 1 : -1 } if(v2 == "0/0") { return asc ? -1 : 1 } var v1fraction = v1.split("/") var v2fraction = v2.split("/") var v1decimal = Number(v1fraction[0]) / Number(v1fraction[1]) var v2decimal = Number(v2fraction[0]) / Number(v2fraction[1]) if(v1decimal == v2decimal) return v1fraction[1] - v2fraction[1] return v1decimal - v2decimal } // Returns a function responsible for sorting a specific table column // (column = column object, asc = ascending order?). const comparer = function(column, asc) { // This is used by the array.sort() function... return function(a, b) { const colIdx = Array.from(column.parentNode.children).indexOf(column) const colName = column.textContent // Select a function based on which column is being called. var columnComparer switch(colName) { case "Brief Desc.": case "Desc.": columnComparer = descriptionComparer break case "Name": case "Docs URL": columnComparer = stringComparer break case "Overall": columnComparer = overallComparer break default: columnComparer = fractionComparer(column.asc) break } // Switch the order of the values depending on whether it's an ascending or descending sort. return columnComparer(getCellValue(asc ? a : b, colIdx), getCellValue(asc ? b : a, colIdx)); } }; const SKIP_END_ROWS = 5 // The number of footer rows generated by doc_status.py // Set up event listeners that will sort the table when headers are clicked. window.onload = function() { document.querySelectorAll('th') .forEach(th => th.addEventListener('click', (() => { const table = th.closest('table'); const tbody = table.querySelector('tbody') const trows = Array.from(tbody.querySelectorAll('tr')) trows.slice(0, -SKIP_END_ROWS) .sort(comparer(th, th.asc = !th.asc)) // Give each column an individual sort direction .concat(trows.splice(-SKIP_END_ROWS)) // Don't sort the last rows, as they are not class reference entries. .forEach(tr => tbody.appendChild(tr) ); }))); }