Skip to content

Commit aac07fc

Browse files
NPM version 1.15.0; Optimized sort type class inference
1 parent efba045 commit aac07fc

File tree

7 files changed

+94
-126
lines changed

7 files changed

+94
-126
lines changed

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
## TABLE-SORT-JS.
88

9-
- Description: HTML table sorting library with sort type inference builtin and browser extension available. [#VanillaJS](http://vanilla-js.com/)
9+
- Description: HTML table sorting library with sort type inference builtin and browser extension available. [#VanillaJS](http://vanilla-js.com/)
1010

1111
- [Demo](https://leewannacott.github.io/Portfolio/#/GitHub)
1212
- [Documentation.](https://leewannacott.github.io/table-sort-js/docs/about.html)
@@ -60,7 +60,7 @@ Refer to the documenation for examples on how to use table-sort-js with [HTML](h
6060
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
6161
| "dates-dmy-sort" | Sorts dates in dd/mm/yyyy format. e.g (18/10/1995). Can use "/" or "-" as separator. |
6262
| "dates-ymd-sort" | Sorts dates in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) yyyy/mm/dd format. e.g (2021/10/28). Use "/" or "-" as separator. |
63-
| "file-size-sort" | Sorts file sizes(B->TiB) uses the binary prefix. (e.g KiB). Input data ideally in Bytes e.g (10b or 10B) |
63+
| "file-size-sort" | Sorts file sizes(B->TiB) uses the binary prefix. (e.g 10 B, 100 KiB, 1 MiB); optional space between number and prefix. |
6464
| "runtime-sort" | Sorts runtime in hours minutes and seconds e.g (10h 1m 20s). Useful for sorting the GitHub actions Run time column... |
6565

6666
| <th> Classes that change defaults. | Description |

browser-extension/manifest.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"manifest_version": 2,
33
"author": "Lee Wannacott",
44
"name": "table-sort-js",
5-
"version": "1.14.0",
5+
"version": "1.15.0",
66
"description": "Makes tables sortable using table-sort-js: https://github.com/LeeWannacott/table-sort-js",
77
"icons": { "48": "icons/t.png" },
88
"browser_action": {
@@ -11,7 +11,7 @@
1111
},
1212
"content_scripts": [
1313
{
14-
"matches": ["<all_urls>", "https://github.com/*/*/actions/runs/*/usage"],
14+
"matches": ["<all_urls>"],
1515
"js": ["addTableSortClass.js", "table-sort.js"]
1616
}
1717
]

browser-extension/table-sort-js.zip

-86 Bytes
Binary file not shown.

browser-extension/table-sort.js

+43-59
Original file line numberDiff line numberDiff line change
@@ -59,64 +59,48 @@ function tableSortJs(testingTableSortJS = false, domDocumentWindow = document) {
5959
}
6060
}
6161

62-
function addInferredClass(th, columnLength, currentCount, classToAdd) {
63-
const threshold = columnLength / 2;
64-
if (currentCount >= threshold) {
65-
th.classList.add(classToAdd);
66-
}
67-
}
68-
69-
function inferSortClasses(tableRows, tableHeadHeaders) {
70-
for (let [columnIndex, th] of tableHeadHeaders.entries()) {
71-
const regexMinutesAndSeconds = /^(\d+h)?\s?(\d+m)?\s?(\d+s)?$/i;
72-
const regexFileSizeSort = /^([.0-9]+)\s?(B|KB|KiB|MB|MiB|GB|GiB|TB|TiB)/i;
73-
// Doesn't infer dates with delimiter "."; as could capture semantic version numbers.
74-
const datesRegex = /^(\d\d?)[/-](\d\d?)[/-]((\d\d)?\d\d)/;
75-
const regexISODates = /^(\d\d\d\d)[/-](\d\d?)[/-](\d\d?)/;
76-
let runtimeCounter = 0,
77-
fileSizeCounter = 0,
78-
datesCounter = 0,
79-
isoDatesCounter = 0;
80-
let tableColumnLength = th.parentElement.childElementCount;
81-
for (let tr of tableRows) {
82-
let runtimeSortMatch, fileSizeSortMatch, datesMatch, isoDatesMatch;
83-
const tableColumn = tr.querySelectorAll("td").item(columnIndex);
62+
function inferSortClasses(tableRows, columnIndex, th) {
63+
const runtimeRegex = /^(\d+h)?\s?(\d+m)?\s?(\d+s)?$/i;
64+
const fileSizeRegex = /^([.0-9]+)\s?(B|KB|KiB|MB|MiB|GB|GiB|TB|TiB)/i;
65+
// Doesn't infer dates with delimiter "."; as could capture semantic version numbers.
66+
const dmyRegex = /^(\d\d?)[/-](\d\d?)[/-]((\d\d)?\d\d)/;
67+
const ymdRegex = /^(\d\d\d\d)[/-](\d\d?)[/-](\d\d?)/;
68+
const inferableClasses = {
69+
runtime: { regexp: runtimeRegex, class: "runtime-sort", count: 0 },
70+
filesize: { regexp: fileSizeRegex, class: "file-size-sort", count: 0 },
71+
dmyDates: { regexp: dmyRegex, class: "dates-dmy-sort", count: 0 },
72+
ymdDates: { regexp: ymdRegex, class: "dates-ymd-sort", count: 0 },
73+
};
74+
let classNameAdded = false;
75+
let regexNotFoundCount = 0;
76+
const threshold = Math.ceil(tableRows.length / 2);
77+
for (let tr of tableRows) {
78+
if (regexNotFoundCount >= threshold) {
79+
break;
80+
}
81+
const tableColumn = tr.querySelectorAll("td").item(columnIndex);
82+
let foundMatch = false;
83+
for (let key of Object.keys(inferableClasses)) {
84+
let classRegexp = inferableClasses[key].regexp;
8485
if (tableColumn.innerText) {
85-
runtimeSortMatch = tableColumn.innerText.match(
86-
regexMinutesAndSeconds
87-
);
88-
fileSizeSortMatch = tableColumn.innerText.match(regexFileSizeSort);
89-
datesMatch = tableColumn.innerText.match(datesRegex);
90-
isoDatesMatch = tableColumn.innerText.match(regexISODates);
91-
}
92-
if (runtimeSortMatch) {
93-
runtimeCounter++;
94-
}
95-
if (fileSizeSortMatch) {
96-
fileSizeCounter++;
97-
}
98-
if (datesMatch) {
99-
datesCounter++;
86+
if (tableColumn.innerText.match(classRegexp) !== null) {
87+
foundMatch = true;
88+
inferableClasses[key].count++;
89+
}
10090
}
101-
if (isoDatesMatch) {
102-
isoDatesCounter++;
91+
if (inferableClasses[key].count >= threshold) {
92+
th.classList.add(inferableClasses[key].class);
93+
classNameAdded = true;
94+
break;
10395
}
10496
}
105-
// TODO: refactor this into one function called addInferredClasses that loops over sort classes and counters
106-
addInferredClass(th, tableColumnLength, runtimeCounter, "runtime-sort");
107-
addInferredClass(
108-
th,
109-
tableColumnLength,
110-
fileSizeCounter,
111-
"file-size-sort"
112-
);
113-
addInferredClass(th, tableColumnLength, datesCounter, "dates-dmy-sort");
114-
addInferredClass(
115-
th,
116-
tableColumnLength,
117-
isoDatesCounter,
118-
"dates-ymd-sort"
119-
);
97+
if (classNameAdded) {
98+
break;
99+
}
100+
if (!foundMatch) {
101+
regexNotFoundCount++;
102+
continue;
103+
}
120104
}
121105
}
122106

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

129113
const isNoSortClassInference =
130114
sortableTable.classList.contains("no-class-infer");
131-
if (!isNoSortClassInference) {
132-
inferSortClasses(tableRows, tableHeadHeaders);
133-
}
134115

135116
for (let [columnIndex, th] of tableHeadHeaders.entries()) {
136117
if (!th.classList.contains("disable-sort")) {
137118
th.style.cursor = "pointer";
119+
if (!isNoSortClassInference) {
120+
inferSortClasses(tableRows, columnIndex, th);
121+
}
138122
makeEachColumnSortable(th, columnIndex, tableBody, sortableTable);
139123
}
140124
}
@@ -504,8 +488,8 @@ function tableSortJs(testingTableSortJS = false, domDocumentWindow = document) {
504488
getTableData(tableProperties);
505489
updateTable(tableProperties);
506490
});
507-
let isOnloadSort = th.classList.contains("onload-sort");
508-
if (isOnloadSort) {
491+
492+
if (th.classList.contains("onload-sort")) {
509493
th.click();
510494
}
511495
}

npm/README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@
66

77
## TABLE-SORT-JS.
88

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

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

1717
## Install instructions.
1818

@@ -60,7 +60,7 @@ Refer to the documenation for examples on how to use table-sort-js with [HTML](h
6060
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
6161
| "dates-dmy-sort" | Sorts dates in dd/mm/yyyy format. e.g (18/10/1995). Can use "/" or "-" as separator. |
6262
| "dates-ymd-sort" | Sorts dates in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) yyyy/mm/dd format. e.g (2021/10/28). Use "/" or "-" as separator. |
63-
| "file-size-sort" | Sorts file sizes(B->TiB) uses the binary prefix. (e.g KiB). Input data ideally in Bytes e.g (10b or 10B) |
63+
| "file-size-sort" | Sorts file sizes(B->TiB) uses the binary prefix. (e.g 10 B, 100 KiB, 1 MiB); optional space between number and prefix. |
6464
| "runtime-sort" | Sorts runtime in hours minutes and seconds e.g (10h 1m 20s). Useful for sorting the GitHub actions Run time column... |
6565

6666
| &lt;th&gt; Classes that change defaults. | Description |

npm/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "table-sort-js",
3-
"version": "1.14.0",
3+
"version": "1.15.0",
44
"description": "A JavaScript client-side HTML table sorting library with no dependencies required.",
55
"license": "MIT",
66
"repository": "LeeWannacott/table-sort-js",

npm/table-sort.js

+43-59
Original file line numberDiff line numberDiff line change
@@ -59,64 +59,48 @@ function tableSortJs(testingTableSortJS = false, domDocumentWindow = document) {
5959
}
6060
}
6161

62-
function addInferredClass(th, columnLength, currentCount, classToAdd) {
63-
const threshold = columnLength / 2;
64-
if (currentCount >= threshold) {
65-
th.classList.add(classToAdd);
66-
}
67-
}
68-
69-
function inferSortClasses(tableRows, tableHeadHeaders) {
70-
for (let [columnIndex, th] of tableHeadHeaders.entries()) {
71-
const regexMinutesAndSeconds = /^(\d+h)?\s?(\d+m)?\s?(\d+s)?$/i;
72-
const regexFileSizeSort = /^([.0-9]+)\s?(B|KB|KiB|MB|MiB|GB|GiB|TB|TiB)/i;
73-
// Doesn't infer dates with delimiter "."; as could capture semantic version numbers.
74-
const datesRegex = /^(\d\d?)[/-](\d\d?)[/-]((\d\d)?\d\d)/;
75-
const regexISODates = /^(\d\d\d\d)[/-](\d\d?)[/-](\d\d?)/;
76-
let runtimeCounter = 0,
77-
fileSizeCounter = 0,
78-
datesCounter = 0,
79-
isoDatesCounter = 0;
80-
let tableColumnLength = th.parentElement.childElementCount;
81-
for (let tr of tableRows) {
82-
let runtimeSortMatch, fileSizeSortMatch, datesMatch, isoDatesMatch;
83-
const tableColumn = tr.querySelectorAll("td").item(columnIndex);
62+
function inferSortClasses(tableRows, columnIndex, th) {
63+
const runtimeRegex = /^(\d+h)?\s?(\d+m)?\s?(\d+s)?$/i;
64+
const fileSizeRegex = /^([.0-9]+)\s?(B|KB|KiB|MB|MiB|GB|GiB|TB|TiB)/i;
65+
// Doesn't infer dates with delimiter "."; as could capture semantic version numbers.
66+
const dmyRegex = /^(\d\d?)[/-](\d\d?)[/-]((\d\d)?\d\d)/;
67+
const ymdRegex = /^(\d\d\d\d)[/-](\d\d?)[/-](\d\d?)/;
68+
const inferableClasses = {
69+
runtime: { regexp: runtimeRegex, class: "runtime-sort", count: 0 },
70+
filesize: { regexp: fileSizeRegex, class: "file-size-sort", count: 0 },
71+
dmyDates: { regexp: dmyRegex, class: "dates-dmy-sort", count: 0 },
72+
ymdDates: { regexp: ymdRegex, class: "dates-ymd-sort", count: 0 },
73+
};
74+
let classNameAdded = false;
75+
let regexNotFoundCount = 0;
76+
const threshold = Math.ceil(tableRows.length / 2);
77+
for (let tr of tableRows) {
78+
if (regexNotFoundCount >= threshold) {
79+
break;
80+
}
81+
const tableColumn = tr.querySelectorAll("td").item(columnIndex);
82+
let foundMatch = false;
83+
for (let key of Object.keys(inferableClasses)) {
84+
let classRegexp = inferableClasses[key].regexp;
8485
if (tableColumn.innerText) {
85-
runtimeSortMatch = tableColumn.innerText.match(
86-
regexMinutesAndSeconds
87-
);
88-
fileSizeSortMatch = tableColumn.innerText.match(regexFileSizeSort);
89-
datesMatch = tableColumn.innerText.match(datesRegex);
90-
isoDatesMatch = tableColumn.innerText.match(regexISODates);
91-
}
92-
if (runtimeSortMatch) {
93-
runtimeCounter++;
94-
}
95-
if (fileSizeSortMatch) {
96-
fileSizeCounter++;
97-
}
98-
if (datesMatch) {
99-
datesCounter++;
86+
if (tableColumn.innerText.match(classRegexp) !== null) {
87+
foundMatch = true;
88+
inferableClasses[key].count++;
89+
}
10090
}
101-
if (isoDatesMatch) {
102-
isoDatesCounter++;
91+
if (inferableClasses[key].count >= threshold) {
92+
th.classList.add(inferableClasses[key].class);
93+
classNameAdded = true;
94+
break;
10395
}
10496
}
105-
// TODO: refactor this into one function called addInferredClasses that loops over sort classes and counters
106-
addInferredClass(th, tableColumnLength, runtimeCounter, "runtime-sort");
107-
addInferredClass(
108-
th,
109-
tableColumnLength,
110-
fileSizeCounter,
111-
"file-size-sort"
112-
);
113-
addInferredClass(th, tableColumnLength, datesCounter, "dates-dmy-sort");
114-
addInferredClass(
115-
th,
116-
tableColumnLength,
117-
isoDatesCounter,
118-
"dates-ymd-sort"
119-
);
97+
if (classNameAdded) {
98+
break;
99+
}
100+
if (!foundMatch) {
101+
regexNotFoundCount++;
102+
continue;
103+
}
120104
}
121105
}
122106

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

129113
const isNoSortClassInference =
130114
sortableTable.classList.contains("no-class-infer");
131-
if (!isNoSortClassInference) {
132-
inferSortClasses(tableRows, tableHeadHeaders);
133-
}
134115

135116
for (let [columnIndex, th] of tableHeadHeaders.entries()) {
136117
if (!th.classList.contains("disable-sort")) {
137118
th.style.cursor = "pointer";
119+
if (!isNoSortClassInference) {
120+
inferSortClasses(tableRows, columnIndex, th);
121+
}
138122
makeEachColumnSortable(th, columnIndex, tableBody, sortableTable);
139123
}
140124
}
@@ -504,8 +488,8 @@ function tableSortJs(testingTableSortJS = false, domDocumentWindow = document) {
504488
getTableData(tableProperties);
505489
updateTable(tableProperties);
506490
});
507-
let isOnloadSort = th.classList.contains("onload-sort");
508-
if (isOnloadSort) {
491+
492+
if (th.classList.contains("onload-sort")) {
509493
th.click();
510494
}
511495
}

0 commit comments

Comments
 (0)