1document.addEventListener("DOMContentLoaded", function () { 2 const tables = document.querySelectorAll(".document-table"); 3 4 tables.forEach((table) => { 5 if (!table.classList.contains("tabs-enabled")) { 6 return; 7 } 8 9 // Add a tabindex to make the table focusable 10 table.setAttribute("tabindex", "0"); 11 12 const tabs = document.createElement("div"); 13 tabs.id = "table-nav"; 14 tabs.setAttribute("role", "radiogroup"); 15 tabs.setAttribute("aria-label", "Table Navigation"); 16 tabs.setAttribute("aria-orientation", "horizontal"); 17 tabs.setAttribute("aria-controls", table.id); 18 table.parentNode.insertBefore(tabs, table); 19 20 const years = new Set( 21 Array.from(table.querySelectorAll("tr[data-year]")).map((year) => 22 year.getAttribute("data-year") 23 ) 24 ); 25 26 years.forEach((year) => { 27 const tab = document.createElement("div"); 28 tab.setAttribute("rel", year); 29 tab.setAttribute("aria-controls", table.id); 30 tab.setAttribute("aria-selected", "false"); 31 tab.setAttribute("role", "radio"); 32 33 // Add tabindex to make the tab focusable 34 tab.setAttribute("tabindex", "0"); 35 36 tab.textContent = year; 37 tabs.appendChild(tab); 38 }); 39 40 tabs.querySelector("div:first-of-type").setAttribute("aria-selected", "true"); 41 42 const latestYear = table.querySelector("tbody tr:first-of-type").getAttribute("data-year"); 43 44 filterYears(table, latestYear); 45 46 // Change tabs 47 tabs.addEventListener("click", handleTabClick); 48 tabs.addEventListener("keydown", handleTabKeyDown); 49 50 function handleTabClick(e) { 51 const target = e.target; 52 53 if (target.getAttribute("role") !== "radio") { 54 return; 55 } 56 57 switchTab(target); 58 e.preventDefault(); 59 } 60 61 function handleTabKeyDown(e) { 62 const target = e.target; 63 64 if (target.getAttribute("role") !== "radio") { 65 return; 66 } 67 68 if (e.key === "Enter" || e.key === "Space") { 69 switchTab(target); 70 e.preventDefault(); 71 } 72 } 73 74 function switchTab(target) { 75 const active = tabs.querySelector("div[aria-selected='true']"); 76 const year = target.getAttribute("rel"); 77 78 active.setAttribute("aria-selected", "false"); 79 target.setAttribute("aria-selected", "true"); 80 filterYears(table, year); 81 } 82 83 function filterYears(table, selectedYear) { 84 const rows = table.querySelectorAll("tr"); 85 86 rows.forEach((row) => { 87 const year = row.getAttribute("data-year"); 88 89 if (year) { 90 row.style.display = year === selectedYear ? "" : "none"; 91 } 92 }); 93 } 94 }); 95});
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.