mirror of
https://github.com/godotengine/doc-status.git
synced 2025-12-31 13:48:23 +03:00
The main table's headers are now clickable to sort columns in ascending or descending order. String columns are sorted alphabetically, description columns are sorted by MISSING vs. OK, and numeric columns are sorted by relative percentages. A custom JS sorting implementation is used, both to avoid a large dependency and to handle the unique format of these table entries. The cursor when hovering over table headers indicates that they can be interacted with.
103 lines
3.5 KiB
JavaScript
103 lines
3.5 KiB
JavaScript
// 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) );
|
|
})));
|
|
}
|