aboutsummaryrefslogtreecommitdiffstats
path: root/vanilla/coverage/sorter.js
diff options
context:
space:
mode:
authorAdam Mathes <adam@adammathes.com>2026-02-13 21:34:48 -0800
committerAdam Mathes <adam@adammathes.com>2026-02-13 21:34:48 -0800
commit76cb9c2a39d477a64824a985ade40507e3bbade1 (patch)
tree41e997aa9c6f538d3a136af61dae9424db2005a9 /vanilla/coverage/sorter.js
parent819a39a21ac992b1393244a4c283bbb125208c69 (diff)
downloadneko-76cb9c2a39d477a64824a985ade40507e3bbade1.tar.gz
neko-76cb9c2a39d477a64824a985ade40507e3bbade1.tar.bz2
neko-76cb9c2a39d477a64824a985ade40507e3bbade1.zip
feat(vanilla): add testing infrastructure and tests (NK-wjnczv)
Diffstat (limited to 'vanilla/coverage/sorter.js')
-rw-r--r--vanilla/coverage/sorter.js210
1 files changed, 210 insertions, 0 deletions
diff --git a/vanilla/coverage/sorter.js b/vanilla/coverage/sorter.js
new file mode 100644
index 0000000..4ed70ae
--- /dev/null
+++ b/vanilla/coverage/sorter.js
@@ -0,0 +1,210 @@
+/* eslint-disable */
+var addSorting = (function() {
+ 'use strict';
+ var cols,
+ currentSort = {
+ index: 0,
+ desc: false
+ };
+
+ // returns the summary table element
+ function getTable() {
+ return document.querySelector('.coverage-summary');
+ }
+ // returns the thead element of the summary table
+ function getTableHeader() {
+ return getTable().querySelector('thead tr');
+ }
+ // returns the tbody element of the summary table
+ function getTableBody() {
+ return getTable().querySelector('tbody');
+ }
+ // returns the th element for nth column
+ function getNthColumn(n) {
+ return getTableHeader().querySelectorAll('th')[n];
+ }
+
+ function onFilterInput() {
+ const searchValue = document.getElementById('fileSearch').value;
+ const rows = document.getElementsByTagName('tbody')[0].children;
+
+ // Try to create a RegExp from the searchValue. If it fails (invalid regex),
+ // it will be treated as a plain text search
+ let searchRegex;
+ try {
+ searchRegex = new RegExp(searchValue, 'i'); // 'i' for case-insensitive
+ } catch (error) {
+ searchRegex = null;
+ }
+
+ for (let i = 0; i < rows.length; i++) {
+ const row = rows[i];
+ let isMatch = false;
+
+ if (searchRegex) {
+ // If a valid regex was created, use it for matching
+ isMatch = searchRegex.test(row.textContent);
+ } else {
+ // Otherwise, fall back to the original plain text search
+ isMatch = row.textContent
+ .toLowerCase()
+ .includes(searchValue.toLowerCase());
+ }
+
+ row.style.display = isMatch ? '' : 'none';
+ }
+ }
+
+ // loads the search box
+ function addSearchBox() {
+ var template = document.getElementById('filterTemplate');
+ var templateClone = template.content.cloneNode(true);
+ templateClone.getElementById('fileSearch').oninput = onFilterInput;
+ template.parentElement.appendChild(templateClone);
+ }
+
+ // loads all columns
+ function loadColumns() {
+ var colNodes = getTableHeader().querySelectorAll('th'),
+ colNode,
+ cols = [],
+ col,
+ i;
+
+ for (i = 0; i < colNodes.length; i += 1) {
+ colNode = colNodes[i];
+ col = {
+ key: colNode.getAttribute('data-col'),
+ sortable: !colNode.getAttribute('data-nosort'),
+ type: colNode.getAttribute('data-type') || 'string'
+ };
+ cols.push(col);
+ if (col.sortable) {
+ col.defaultDescSort = col.type === 'number';
+ colNode.innerHTML =
+ colNode.innerHTML + '<span class="sorter"></span>';
+ }
+ }
+ return cols;
+ }
+ // attaches a data attribute to every tr element with an object
+ // of data values keyed by column name
+ function loadRowData(tableRow) {
+ var tableCols = tableRow.querySelectorAll('td'),
+ colNode,
+ col,
+ data = {},
+ i,
+ val;
+ for (i = 0; i < tableCols.length; i += 1) {
+ colNode = tableCols[i];
+ col = cols[i];
+ val = colNode.getAttribute('data-value');
+ if (col.type === 'number') {
+ val = Number(val);
+ }
+ data[col.key] = val;
+ }
+ return data;
+ }
+ // loads all row data
+ function loadData() {
+ var rows = getTableBody().querySelectorAll('tr'),
+ i;
+
+ for (i = 0; i < rows.length; i += 1) {
+ rows[i].data = loadRowData(rows[i]);
+ }
+ }
+ // sorts the table using the data for the ith column
+ function sortByIndex(index, desc) {
+ var key = cols[index].key,
+ sorter = function(a, b) {
+ a = a.data[key];
+ b = b.data[key];
+ return a < b ? -1 : a > b ? 1 : 0;
+ },
+ finalSorter = sorter,
+ tableBody = document.querySelector('.coverage-summary tbody'),
+ rowNodes = tableBody.querySelectorAll('tr'),
+ rows = [],
+ i;
+
+ if (desc) {
+ finalSorter = function(a, b) {
+ return -1 * sorter(a, b);
+ };
+ }
+
+ for (i = 0; i < rowNodes.length; i += 1) {
+ rows.push(rowNodes[i]);
+ tableBody.removeChild(rowNodes[i]);
+ }
+
+ rows.sort(finalSorter);
+
+ for (i = 0; i < rows.length; i += 1) {
+ tableBody.appendChild(rows[i]);
+ }
+ }
+ // removes sort indicators for current column being sorted
+ function removeSortIndicators() {
+ var col = getNthColumn(currentSort.index),
+ cls = col.className;
+
+ cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, '');
+ col.className = cls;
+ }
+ // adds sort indicators for current column being sorted
+ function addSortIndicators() {
+ getNthColumn(currentSort.index).className += currentSort.desc
+ ? ' sorted-desc'
+ : ' sorted';
+ }
+ // adds event listeners for all sorter widgets
+ function enableUI() {
+ var i,
+ el,
+ ithSorter = function ithSorter(i) {
+ var col = cols[i];
+
+ return function() {
+ var desc = col.defaultDescSort;
+
+ if (currentSort.index === i) {
+ desc = !currentSort.desc;
+ }
+ sortByIndex(i, desc);
+ removeSortIndicators();
+ currentSort.index = i;
+ currentSort.desc = desc;
+ addSortIndicators();
+ };
+ };
+ for (i = 0; i < cols.length; i += 1) {
+ if (cols[i].sortable) {
+ // add the click event handler on the th so users
+ // dont have to click on those tiny arrows
+ el = getNthColumn(i).querySelector('.sorter').parentElement;
+ if (el.addEventListener) {
+ el.addEventListener('click', ithSorter(i));
+ } else {
+ el.attachEvent('onclick', ithSorter(i));
+ }
+ }
+ }
+ }
+ // adds sorting functionality to the UI
+ return function() {
+ if (!getTable()) {
+ return;
+ }
+ cols = loadColumns();
+ loadData();
+ addSearchBox();
+ addSortIndicators();
+ enableUI();
+ };
+})();
+
+window.addEventListener('load', addSorting);