1function initializeSortableTable(table, index) { 2 var tableId = table.getAttribute('id') || 'sortable-table-' + index; 3 var headers = table.querySelectorAll('th'); 4 5 function bindEvents() { 6 headers.forEach(function (header, idx) { 7 if (header.hasAttribute('data-table-sortable-ignore')) { 8 return; 9 } 10 11 header.addEventListener('click', function () { 12 var isDescending = isDescendingSort(idx); 13 sortColumn(idx, !isDescending); 14 }); 15 }); 16 } 17 18 function isDescendingSort(headerIndex) { 19 return headers[headerIndex].classList.contains('sorting_desc'); 20 } 21 22 function compare(rowA, rowB, columnIndex, descending) { 23 var cellA = getValue(rowA, columnIndex); 24 var cellB = getValue(rowB, columnIndex); 25 26 var valueA = parseValue(cellA); 27 var valueB = parseValue(cellB); 28 29 // Adjusted handling for empty or whitespace-only values 30 var isEmptyA = !cellA.trim(); 31 var isEmptyB = !cellB.trim(); 32 if (isEmptyA && !isEmptyB) return 1; // Always move A to the end if it's empty 33 if (!isEmptyA && isEmptyB) return -1; // Always move B to the end if it's empty 34 if (isEmptyA && isEmptyB) return 0; // If both are empty, consider them equal 35 36 // Direct comparison for numbers 37 if (!isNaN(valueA) && !isNaN(valueB)) { 38 return descending ? valueB - valueA : valueA - valueB; 39 } 40 41 // Ensuring both values are strings for localeCompare 42 var strA = String(valueA); 43 var strB = String(valueB); 44 return strA.localeCompare(strB, undefined, { numeric: true, sensitivity: 'base' }) * (descending ? -1 : 1); 45 } 46 47 function parseValue(value) { 48 var number = value.replace(/,/g, ''); 49 return isNaN(number) ? value : parseFloat(number); 50 } 51 52 function getValue(row, columnIndex) { 53 var cell = row.cells[columnIndex]; 54 var sortableValue = cell.querySelector('[data-table-sortable-value]'); 55 return sortableValue ? sortableValue.textContent.trim() : cell.textContent.trim(); 56 } 57 58 function sortColumn(columnIndex, descending) { 59 if (headers[columnIndex].hasAttribute('data-table-sortable-ignore')) { 60 return; 61 } 62 63 var rowsArray = Array.from(table.tBodies[0].rows); 64 rowsArray.sort(function (rowA, rowB) { 65 return compare(rowA, rowB, columnIndex, descending); 66 }); 67 68 rowsArray.forEach(function (row) { 69 table.tBodies[0].appendChild(row); 70 }); 71 72 updateHeaderClasses(columnIndex, descending); 73 saveSortingState(columnIndex, descending); 74 } 75 76 function updateHeaderClasses(sortedColumnIndex, descending) { 77 headers.forEach(function (header, idx) { 78 if (!header.hasAttribute('data-table-sortable-ignore')) { 79 header.classList.remove('sorting_asc', 'sorting_desc'); 80 if (idx === sortedColumnIndex) { 81 header.classList.add(descending ? 'sorting_desc' : 'sorting_asc'); 82 } 83 } 84 }); 85 } 86 87 function saveSortingState(columnIndex, descending) { 88 var sortingState = { 89 index: columnIndex, 90 direction: descending ? 'desc' : 'asc' 91 }; 92 sessionStorage.setItem('sortingState-' + tableId, JSON.stringify(sortingState)); 93 } 94 95 function loadSortingState() { 96 var savedState = sessionStorage.getItem('sortingState-' + tableId); 97 if (savedState) { 98 savedState = JSON.parse(savedState); 99 sortColumn(savedState.index, savedState.direction === 'desc'); 100 return; 101 } 102 103 headers.forEach(function (header, index) { 104 if (!header.hasAttribute('data-table-sortable-ignore')) { 105 if (header.classList.contains('sorting_asc')) { 106 sortColumn(index, false); 107 } else if (header.classList.contains('sorting_desc')) { 108 sortColumn(index, true); 109 } 110 } 111 }); 112 } 113 114 loadSortingState(); 115 bindEvents(); 116} 117 118document.addEventListener('DOMContentLoaded', function () { 119 var tables = document.querySelectorAll('table[data-table-sortable]');
120 tables.forEach(function (table, index) { 121 initializeSortableTable(table, index); 122 }); 123});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.