Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor and optimize #86

Merged
merged 9 commits into from
May 14, 2023
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@

## TABLE-SORT-JS.

- Description: A JavaScript client-side HTML table sorting library with no dependencies required.
- Description: HTML table sorting library with sort type inference builtin and browser extension available. [#VanillaJS](http://vanilla-js.com/)

- [Demo](https://leewannacott.github.io/Portfolio/#/GitHub)
- [Documentation.](https://leewannacott.github.io/table-sort-js/docs/about.html)
(work in progress)
- [npm package.](https://www.npmjs.com/package/table-sort-js)
- [firefox browser extension](https://addons.mozilla.org/en-US/firefox/addon/table-sort-js/)
- [firefox browser extension](https://addons.mozilla.org/en-US/firefox/addon/table-sort-js/): Tables of any website you visit become sortable!

## Install instructions.

Expand Down
4 changes: 2 additions & 2 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ <h1>Manual testing of table sort js</h1>
<tr>
<td>da Vinci</td>
<td>Zarlo</td>
<td>1452-4-15</td>
<td>1452/4/15</td>
<td>13000</td>
<td></td>
<td>1m 45s</td>
Expand All @@ -43,7 +43,7 @@ <h1>Manual testing of table sort js</h1>
<tr>
<td>Statham</td>
<td>Jason</td>
<td>1967-7-26</td>
<td>1967/7/26</td>
<td></td>
<td>HR</td>
<td>11m 40s</td>
Expand Down
102 changes: 43 additions & 59 deletions public/table-sort.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,64 +59,48 @@ function tableSortJs(testingTableSortJS = false, domDocumentWindow = document) {
}
}

function addInferredClass(th, columnLength, currentCount, classToAdd) {
const threshold = columnLength / 2;
if (currentCount >= threshold) {
th.classList.add(classToAdd);
}
}

function inferSortClasses(tableRows, tableHeadHeaders) {
for (let [columnIndex, th] of tableHeadHeaders.entries()) {
const regexMinutesAndSeconds = /^(\d+h)?\s?(\d+m)?\s?(\d+s)?$/i;
const regexFileSizeSort = /^([.0-9]+)\s?(B|KB|KiB|MB|MiB|GB|GiB|TB|TiB)/i;
// Doesn't infer dates with delimiter "."; as could capture semantic version numbers.
const datesRegex = /^(\d\d?)[/-](\d\d?)[/-]((\d\d)?\d\d)/;
const regexISODates = /^(\d\d\d\d)[/-](\d\d?)[/-](\d\d?)/;
let runtimeCounter = 0,
fileSizeCounter = 0,
datesCounter = 0,
isoDatesCounter = 0;
let tableColumnLength = th.parentElement.childElementCount;
for (let tr of tableRows) {
let runtimeSortMatch, fileSizeSortMatch, datesMatch, isoDatesMatch;
const tableColumn = tr.querySelectorAll("td").item(columnIndex);
function inferSortClasses(tableRows, columnIndex, th) {
const runtimeRegex = /^(\d+h)?\s?(\d+m)?\s?(\d+s)?$/i;
const fileSizeRegex = /^([.0-9]+)\s?(B|KB|KiB|MB|MiB|GB|GiB|TB|TiB)/i;
// Doesn't infer dates with delimiter "."; as could capture semantic version numbers.
const dmyRegex = /^(\d\d?)[/-](\d\d?)[/-]((\d\d)?\d\d)/;
const ymdRegex = /^(\d\d\d\d)[/-](\d\d?)[/-](\d\d?)/;
const inferableClasses = {
runtime: { regexp: runtimeRegex, class: "runtime-sort", count: 0 },
filesize: { regexp: fileSizeRegex, class: "file-size-sort", count: 0 },
dmyDates: { regexp: dmyRegex, class: "dates-dmy-sort", count: 0 },
ymdDates: { regexp: ymdRegex, class: "dates-ymd-sort", count: 0 },
};
let classNameAdded = false;
let regexNotFoundCount = 0;
const threshold = Math.ceil(tableRows.length / 2);
for (let tr of tableRows) {
if (regexNotFoundCount >= threshold) {
break;
}
const tableColumn = tr.querySelectorAll("td").item(columnIndex);
let foundMatch = false;
for (let key of Object.keys(inferableClasses)) {
let classRegexp = inferableClasses[key].regexp;
if (tableColumn.innerText) {
runtimeSortMatch = tableColumn.innerText.match(
regexMinutesAndSeconds
);
fileSizeSortMatch = tableColumn.innerText.match(regexFileSizeSort);
datesMatch = tableColumn.innerText.match(datesRegex);
isoDatesMatch = tableColumn.innerText.match(regexISODates);
}
if (runtimeSortMatch) {
runtimeCounter++;
}
if (fileSizeSortMatch) {
fileSizeCounter++;
}
if (datesMatch) {
datesCounter++;
if (tableColumn.innerText.match(classRegexp) !== null) {
foundMatch = true;
inferableClasses[key].count++;
}
}
if (isoDatesMatch) {
isoDatesCounter++;
if (inferableClasses[key].count >= threshold) {
th.classList.add(inferableClasses[key].class);
classNameAdded = true;
break;
}
}
// TODO: refactor this into one function called addInferredClasses that loops over sort classes and counters
addInferredClass(th, tableColumnLength, runtimeCounter, "runtime-sort");
addInferredClass(
th,
tableColumnLength,
fileSizeCounter,
"file-size-sort"
);
addInferredClass(th, tableColumnLength, datesCounter, "dates-dmy-sort");
addInferredClass(
th,
tableColumnLength,
isoDatesCounter,
"dates-ymd-sort"
);
if (classNameAdded) {
break;
}
if (!foundMatch) {
regexNotFoundCount++;
continue;
}
}
}

Expand All @@ -128,13 +112,13 @@ function tableSortJs(testingTableSortJS = false, domDocumentWindow = document) {

const isNoSortClassInference =
sortableTable.classList.contains("no-class-infer");
if (!isNoSortClassInference) {
inferSortClasses(tableRows, tableHeadHeaders);
}

for (let [columnIndex, th] of tableHeadHeaders.entries()) {
if (!th.classList.contains("disable-sort")) {
th.style.cursor = "pointer";
if (!isNoSortClassInference) {
inferSortClasses(tableRows, columnIndex, th);
}
makeEachColumnSortable(th, columnIndex, tableBody, sortableTable);
}
}
Expand Down Expand Up @@ -504,8 +488,8 @@ function tableSortJs(testingTableSortJS = false, domDocumentWindow = document) {
getTableData(tableProperties);
updateTable(tableProperties);
});
let isOnloadSort = th.classList.contains("onload-sort");
if (isOnloadSort) {

if (th.classList.contains("onload-sort")) {
th.click();
}
}
Expand Down