feat(sitemap): add XML styling (#221)

This commit is contained in:
Óscar Fernández
2023-11-14 23:26:44 +01:00
committed by GitHub
parent 741a7e7c6f
commit 1df3f7f89c
9 changed files with 190 additions and 4 deletions

113
static/js/sortTable.js Normal file
View File

@@ -0,0 +1,113 @@
// Select the table and table headers.
var table = document.querySelector("#sitemapTable");
var headers = Array.from(table.querySelectorAll("th"));
// Create and append the live region for accessibility announcements.
var liveRegion = document.createElement('div');
liveRegion.setAttribute('aria-live', 'polite');
liveRegion.setAttribute('aria-atomic', 'true');
liveRegion.classList.add('visually-hidden');
document.body.appendChild(liveRegion);
// Initialise headers with click and keyboard listeners.
initializeHeaders();
addSortText(); // Add text for screen readers for initial sort direction.
updateSortIndicators(headers[0], 'asc'); // Set initial sort indicators.
function updateSortIndicators(header, direction) {
removeSortArrows(header);
var arrow = document.createElement('span');
arrow.classList.add('sort-arrow');
arrow.textContent = direction === 'asc' ? ' ▲' : ' ▼';
arrow.setAttribute('aria-hidden', 'true');
header.appendChild(arrow);
}
function removeSortArrows(header) {
var arrows = header.querySelectorAll('.sort-arrow');
arrows.forEach(function (arrow) {
arrow.remove();
});
}
function initializeHeaders() {
headers.forEach(function (header, index) {
header.classList.add('sortable');
header.setAttribute('tabindex', '0');
header.sortDirection = 'asc'; // Default sort direction.
var sortAttribute = index === 0 ? 'ascending' : 'none';
header.setAttribute('aria-sort', sortAttribute);
header.addEventListener("click", function () {
sortTable(index);
});
header.addEventListener("keydown", function (e) {
if (e.key === "Enter" || e.key === " ") {
e.preventDefault();
sortTable(index);
}
});
});
}
function announceSort(header, direction) {
var columnTitle = header.querySelector('.columntitle').textContent;
liveRegion.textContent = 'Column ' + columnTitle + ' is now sorted in ' + direction + ' order';
}
function sortTable(index) {
var header = headers[index];
var direction = header.sortDirection === 'asc' ? 'desc' : 'asc';
var tbody = table.querySelector("tbody");
var rows = Array.from(tbody.querySelectorAll("tr"));
sortRows(rows, index, direction);
refreshTableBody(tbody, rows);
updateHeaderAttributes(header, direction);
announceSort(header, direction === 'asc' ? 'ascending' : 'descending');
}
function sortRows(rows, index, direction) {
rows.sort(function (rowA, rowB) {
var cellA = rowA.querySelectorAll("td")[index].textContent;
var cellB = rowB.querySelectorAll("td")[index].textContent;
return direction === 'asc' ? cellA.localeCompare(cellB) : cellB.localeCompare(cellA);
});
}
function refreshTableBody(tbody, rows) {
tbody.innerHTML = ''; // Clear existing rows.
rows.forEach(function (row) {
tbody.appendChild(row);
});
}
function updateHeaderAttributes(header, direction) {
headers.forEach(function (otherHeader) {
if (otherHeader !== header) {
otherHeader.setAttribute('aria-sort', 'none');
removeSortArrows(otherHeader);
}
});
header.setAttribute('aria-sort', direction === 'asc' ? 'ascending' : 'descending');
header.sortDirection = direction;
updateSortIndicators(header, direction);
updateAnnounceText(header);
}
// Update screen reader text for sorting.
function updateAnnounceText(header) {
var span = header.querySelector('.visually-hidden');
span.textContent = 'Click to sort in ' + (header.sortDirection === 'asc' ? 'descending' : 'ascending') + ' order';
}
// Add text for screen readers regarding sort order.
function addSortText() {
headers.forEach(function (header) {
var span = document.createElement('span');
span.classList.add('visually-hidden');
span.textContent = 'Click to sort in descending order';
header.appendChild(span);
});
}
headers[0].sortDirection = 'asc';
headers[0].setAttribute('aria-sort', 'ascending');

1
static/js/sortTable.min.js vendored Normal file
View File

@@ -0,0 +1 @@
var table=document.querySelector("#sitemapTable"),headers=Array.from(table.querySelectorAll("th")),liveRegion=document.createElement("div");function updateSortIndicators(e,t){removeSortArrows(e);var r=document.createElement("span");r.classList.add("sort-arrow"),r.textContent="asc"===t?" ▲":" ▼",r.setAttribute("aria-hidden","true"),e.appendChild(r)}function removeSortArrows(e){e.querySelectorAll(".sort-arrow").forEach(function(e){e.remove()})}function initializeHeaders(){headers.forEach(function(e,t){e.classList.add("sortable"),e.setAttribute("tabindex","0"),e.sortDirection="asc",e.setAttribute("aria-sort",0===t?"ascending":"none"),e.addEventListener("click",function(){sortTable(t)}),e.addEventListener("keydown",function(e){"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),sortTable(t))})})}function announceSort(e,t){e=e.querySelector(".columntitle").textContent;liveRegion.textContent="Column "+e+" is now sorted in "+t+" order"}function sortTable(e){var t=headers[e],r="asc"===t.sortDirection?"desc":"asc",n=table.querySelector("tbody"),o=Array.from(n.querySelectorAll("tr"));sortRows(o,e,r),refreshTableBody(n,o),updateHeaderAttributes(t,r),announceSort(t,"asc"==r?"ascending":"descending")}function sortRows(e,r,n){e.sort(function(e,t){e=e.querySelectorAll("td")[r].textContent,t=t.querySelectorAll("td")[r].textContent;return"asc"===n?e.localeCompare(t):t.localeCompare(e)})}function refreshTableBody(t,e){t.innerHTML="",e.forEach(function(e){t.appendChild(e)})}function updateHeaderAttributes(t,e){headers.forEach(function(e){e!==t&&(e.setAttribute("aria-sort","none"),removeSortArrows(e))}),t.setAttribute("aria-sort","asc"===e?"ascending":"descending"),t.sortDirection=e,updateSortIndicators(t,e),updateAnnounceText(t)}function updateAnnounceText(e){e.querySelector(".visually-hidden").textContent="Click to sort in "+("asc"===e.sortDirection?"descending":"ascending")+" order"}function addSortText(){headers.forEach(function(e){var t=document.createElement("span");t.classList.add("visually-hidden"),t.textContent="Click to sort in descending order",e.appendChild(t)})}liveRegion.setAttribute("aria-live","polite"),liveRegion.setAttribute("aria-atomic","true"),liveRegion.classList.add("visually-hidden"),document.body.appendChild(liveRegion),initializeHeaders(),addSortText(),updateSortIndicators(headers[0],"asc"),headers[0].sortDirection="asc",headers[0].setAttribute("aria-sort","ascending");