From 38e9c547e381f057e5ea9f03c0751b19087c9a26 Mon Sep 17 00:00:00 2001 From: LeeWannacott Date: Wed, 12 Jul 2023 20:11:28 +1200 Subject: [PATCH] npm release 1.18.1; fix optional chaining being used that breaks babel loader. --- README.md | 12 +-- browser-extensions/chrome/manifest.json | 2 +- browser-extensions/chrome/table-sort-js.zip | Bin 8073 -> 8069 bytes browser-extensions/chrome/table-sort.js | 96 ++++++++++--------- browser-extensions/firefox/manifest.json | 2 +- browser-extensions/firefox/table-sort-js.zip | Bin 8073 -> 8069 bytes browser-extensions/firefox/table-sort.js | 96 ++++++++++--------- npm/README.md | 12 +-- npm/package.json | 2 +- npm/table-sort.js | 96 ++++++++++--------- 10 files changed, 165 insertions(+), 153 deletions(-) diff --git a/README.md b/README.md index 4f08254..0acc86a 100644 --- a/README.md +++ b/README.md @@ -61,12 +61,12 @@ Examples on using table-sort-js with frontend frameworks such as [React.js](http
-| <th> classes | Description | -| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- | -| "data-sort" | Sort by [data attributes](https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes), e.g <td data-sort="42">. Useful for doing custom sorts. | -| "dates-mdy-sort" | Sorts dates in US style mm/dd/yyyy format;. e.g (12/28/2023). Can use "/" or "-" as separator. Overides inferred "dates-dmy-sort" class. | -| "onload-sort" | Sort column on loading of the page. Simulates a click from the user. (can only sort onload for one column) | -| "disable-sort" | Disallow sorting the table by this specific column. | +| <th> classes | Description | +| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| "data-sort" | Sort by [data attributes](https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes), e.g <td data-sort="42">. Useful for doing custom sorts. | +| "dates-mdy-sort" | Sorts dates in US style mm/dd/yyyy format;. e.g (12/28/2023). Can use "/" or "-" as separator. Overides inferred "dates-dmy-sort" class. | +| "onload-sort" | Sort column on loading of the page. Simulates a click from the user. (can only sort onload for one column) | +| "disable-sort" | Disallow sorting the table by this specific column. |
diff --git a/browser-extensions/chrome/manifest.json b/browser-extensions/chrome/manifest.json index 2268f05..49e8ee5 100644 --- a/browser-extensions/chrome/manifest.json +++ b/browser-extensions/chrome/manifest.json @@ -2,7 +2,7 @@ "manifest_version": 3, "author": "Lee Wannacott", "name": "table-sort-js", - "version": "1.18.0", + "version": "1.18.1", "description": "Makes tables sortable using table-sort-js: https://github.com/LeeWannacott/table-sort-js", "icons": { "48": "icons/t.png" }, "browser_action": { diff --git a/browser-extensions/chrome/table-sort-js.zip b/browser-extensions/chrome/table-sort-js.zip index 435b1f81f91e465421d2fa12d79e4faa168dd23c..c04a81dd0340b2c17a84e159b26b62890772142b 100644 GIT binary patch delta 5540 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 diff --git a/browser-extensions/chrome/table-sort.js b/browser-extensions/chrome/table-sort.js index 455c4d2..1a9a2c0 100644 --- a/browser-extensions/chrome/table-sort.js +++ b/browser-extensions/chrome/table-sort.js @@ -55,57 +55,61 @@ function tableSortJs(testingTableSortJS = false, domDocumentWindow = document) { } function inferSortClasses(tableRows, columnIndex, column, 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; - // Don'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 numericRegex = /^(?:\(\d+(?:\.\d+)?\)|-?\d+(?:\.\d+)?)$/; doesn't handle commas - const numericRegex = - /^-?(?:\d{1,3}(?:[',]\d{3})*(?:\.\d+)?|\d+(?:\.\d+)?(?:[',]\d{3})*?)$/; - 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 }, - numericRegex: { regexp: numericRegex, class: "numeric-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( - column.span[columnIndex] === 1 - ? column.spanSum[columnIndex] - 1 - : column.spanSum[columnIndex] - column.span[columnIndex] - ); - let foundMatch = false; - for (let key of Object.keys(inferableClasses)) { - let classRegexp = inferableClasses[key].regexp; - if (tableColumn?.innerText !== undefined) { - if (tableColumn.innerText.match(classRegexp)) { - foundMatch = true; - inferableClasses[key].count++; + try { + 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; + // Don'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 numericRegex = /^(?:\(\d+(?:\.\d+)?\)|-?\d+(?:\.\d+)?)$/; doesn't handle commas + const numericRegex = + /^-?(?:\d{1,3}(?:[',]\d{3})*(?:\.\d+)?|\d+(?:\.\d+)?(?:[',]\d{3})*?)$/; + 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 }, + numericRegex: { regexp: numericRegex, class: "numeric-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( + column.span[columnIndex] === 1 + ? column.spanSum[columnIndex] - 1 + : column.spanSum[columnIndex] - column.span[columnIndex] + ); + let foundMatch = false; + for (let key of Object.keys(inferableClasses)) { + let classRegexp = inferableClasses[key].regexp; + if (tableColumn.innerText !== undefined) { + if (tableColumn.innerText.match(classRegexp)) { + foundMatch = true; + inferableClasses[key].count++; + } + } + if (inferableClasses[key].count >= threshold) { + th.classList.add(inferableClasses[key].class); + classNameAdded = true; + break; } } - if (inferableClasses[key].count >= threshold) { - th.classList.add(inferableClasses[key].class); - classNameAdded = true; + if (classNameAdded) { break; } + if (!foundMatch) { + regexNotFoundCount++; + continue; + } } - if (classNameAdded) { - break; - } - if (!foundMatch) { - regexNotFoundCount++; - continue; - } + } catch (e) { + console.log(e); } } diff --git a/browser-extensions/firefox/manifest.json b/browser-extensions/firefox/manifest.json index 354896d..e9af1a3 100644 --- a/browser-extensions/firefox/manifest.json +++ b/browser-extensions/firefox/manifest.json @@ -2,7 +2,7 @@ "manifest_version": 2, "author": "Lee Wannacott", "name": "table-sort-js", - "version": "1.18.0", + "version": "1.18.1", "description": "Makes tables sortable using table-sort-js: https://github.com/LeeWannacott/table-sort-js", "icons": { "48": "icons/t.png" }, "browser_action": { diff --git a/browser-extensions/firefox/table-sort-js.zip b/browser-extensions/firefox/table-sort-js.zip index 5a70363114f1e0b0846d6616c29785c480f20748..efd4576f2edbf1be19c8e8801bafb32d03dbdd2e 100644 GIT binary patch delta 5540 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 Img*n(KlPVgb^rhX delta 5499 zcmY+IRa6v=)`o{}k(BNpxtM_8By`EUPL^%>&4J>R*004jwP;Kc1NC)<0yN z;XmYr?jMp)jKTVER4ATt45g^_j1sOBCSW)c;~6kqZbX4IN-jzSbx0z6 zs&oyMa(vWwETGyE7t@KMOcvBRp4`paI`7St)OdyQ|E-e$Q!6&c7vm$MHyH>D03c60 zotTgYkNa;$e=AN064E^uUdUuLpViGUC?|BW;54gDHzMSPmg%Scnsyd%qfb6ojgIC< z_7zoT9Gj?&T*w*bZ&6uL{z&L3&A21~0TBn%9CT7PT;4pFfQ)dc>WSTXCwuz!)P!h!IK1E zi?WY7Ux>6pOWXEPC@p*;S;LOTup@Dq60;8$$c(kw7cq4^NSY3;4MyD9i zEsqu`zrJpm7PUnNF-DC#jHnq+6a<}gJCnU!iDj-hhQGps?cwl_PPq7_m#I)vG^z24 z>gcN%$#Cg0EHgH3+Txf!seF6q4|zcNYey30nQuc)*>Dy3U8QcQhO3c(OgTA8+FnWx z!*d>jjQcAyj4cvR$R-fJ687LU6ZX^-k<{lJ#TBB7hiq1NO^Rn-DPTkx@=6%KL9c-3 z6oS`VBlq^v0ZA^aiXIIQ%hl(1hz(Mec6?nID%8jB@( z_AsrF+!vV|KeZj7vFR947dPltL>!FTJHFt!`UqaX2((}OjC42p>0qZTG4M23yNqiw z1dl^HnjY9~mR4PNXT&r!IRqJB|1;j|-wsuH57B$eQlhC|nv?tKBP3%S+`S%eNovha z70vsu9-mTJIJ3y4nZ=TX@(N;oJ&wP_VB+-CrHW56d_ggDhfBhUL zzKqPO%;TiJe`h^2DJ+fm1@~mDQ{`kgJRrv8U0X#6C(7ejSU8VYjJqw1?@F9obrs##?i!^mX2d^=^NeB?bXMpw1+wN;S$jp$|f9a#!++DyQe6oS&zK0nSORcUGo$tqcrI*S<=z;x-xXn)bRd3jPN$_0n zz{h#358~{;M6Se!{GcqR-?8kXY*yEX{L&v|yye*N9A>g}bmRG^SSg^HB_?!FWY<88 zf$l8F28JvY7FC#ZWDB+7!E0~umDlABE2H7~1ErtF7$0E)0)af%msk= zt+S=H`OS-y9j%@TfXW^DDPSDNYu&`-(#WIl9>!FwB2^5oK!H5A@V0g7n2(|}b|ZPz zI+$kEeH%}G+#K`RazkWYplVbuDexM(I~RqBrxY)96n0>xo= zH2u6bz<6Ai8)jVe0AKz0OUB)4#wia*Act$YLcv6u6-(SwZ&pdqMT&oN7&P=Z#voI# z6;+Et!>c-zasrb&&W(T`?nnnZ!c2zBz|myNJ2}ir?y?`8_t5cS_6^!8@D5m8Ku^+q zPxWP7F(I*fNT7xtDN_{P^Cs)tk)P@IUX$3X{sFFnZpvIUH`cf{H`9Z)b_5fuj>C%6RXN6SQAye4W-XRR z@b0LcpK-PiO90m+{L1Wh;=Pd6NFsAMX>T`%FY z)FwJkQUMt|v0WWAi>4MR9i%O_=Ap15K1XPN8k%%3q133w^Y%)So8jyB=(2Wq9+-K) zg0EF7fho2XNzT!t3iGSmqiD_guB9d0<3gl*k7*6lp~RWb$f23lJm4u_Fm2~D=I^C8 zsJf9=hO)-Aaw72E$~ROe>PF20KKhVf^u0wfR2IeC#+)7TtU=i-Zf@vAotO$XA{R;l-IcbaYs?cK4ZR}EOGDcccFW;O9AjHEh zi(4l~?3YL4!-owb;ud$V3d-WSh6T$k3{hY#R0syCuNC51@E%Aq^Cqd#mDY_mI@9`dE3dB5uw3_ugC&wxjx8k2>#e4U** z_6DEMqN7ijx>=njg*ig7FM-%?^)BHl9vRb)tX>KH&-gjRpj^~@3qgyggqaI;Z(0G37hfFW7bWE7F<-)Dun8zlkn zgF~fo!o#dqrp`Ebp&OA-rK2t8;yrin_{w`Rl<#Ekh7zEUA@ z-=(PWvHM{za@~_;-$v-QlkH>UuofKY6d#4FAmeoGblRrT6~>zU#HZ=_8ypE8bm81k zWRIq9LT*SE#(cQcubtRrd`>~ot_n3C)gDuU)0=IIt(2PRA>7LBQTJZ{yC=D!7l$+c z!%JoHJDPDLh~5=NjOy=VSV%abgpcnO_mv!DsMEG1%-rp_J-kyScP@(>JL4qDb&-2> z^K)15sB{%~kd4;%&Hmo(du1pm{4v$_>WQnv&6!Kzx~qZelT-jz9+8BORJ2sUQNuEC z{H+VqiN1Qz;Wew3BpP8CKBa4(rwJlmLt88lZRe-Gh%X`%=DH4G;n|NJ18^L`4 zJ`|AW0vqxX|Ii$o9YpV?@aIqR9G95vQ>==T6oVpwTQ2p2!fh$9`6V>{_axhs<4dV8 zX?oeA&z(6Z(is>nY3^}ihkP1;9Y1F)ZRQ)7QlRDO1<^@tVG*4ACWStEKaA@1D ze0f}g`)#VnmghM0U5ya}?F=Fc%RV@)i0q$f+j|WKl{QM?OUkQqC9s8nW{$Gs-3G-l z(0th^w+?!rrjUl45pbv$sG7Sq>sM#;^D;E|p*F-;sjx9izWUl?IO}VIbN6TDm^fnk zefw^2%+T;1!F3wQ-r=~*M| zB96~o6>pUrr?--<6YOf9U3In%-M%v;`t!$6+F~a=0I_dn#_u9C(ye{*tZW}Ss4;d$ z_|E+Ana>?=o^jjCL+;rW`Tz`W|ub^Uw zIt>X(@F5intX(9lT5R*ornYYNR;zQ_#hr%O1!6zHdDS!E4(mQA2#Pmn-KVOidcQUq z$U;1=By`|+p8xP@ZH`*lze{SxrC|*-3;ejhbc<-HzggQey&N^N`n=Nu(I&Q17gXS1 zTw8OXBiJS=BE|H|R6Bipn=kn+#kVXGdP(3ppy~ehY@aNz?C~BR58k#|tl%$q4b|tOUW^>}D+9an*B(;8Y~ zCD%T%(%3rxE434?N;aaY-7T7SP^@$PdGE0FDo!qY| zITpm^b)dMw#~*MX#^K$ov{s%+EFw-_Hc7>N8KHq_*;He!kvjouk#ERF>GiPAbrWd%ax2oy42UP707`H+O3d~K!l9WoI zQ^lLyz2V6mpe7#%3BuQ5fj9chA7;v>xltd1-Q&qDW{jlAwMMy^x^s^HmAj?Y zu{g?v5$H~6je%-gS?e#Cvm0RAQ!FYQeRM8*gB3U_*au}<8+7+{7(>-*o5k;WYR;ET zzV|nMOM~q`%^iSqMzj$6vy71(^7pYzS0*jxq%N5hB{|Idu=q7Ytej-!l0nB^^Chdd zo`=jUQB;V{Ocu}Ocysv1@AiJO9xAy_9yhNo2cT>jCs(s0>ZpTXv^O7q0|oO9#%^)cB+$N>Xp7G9CQQjm7%yWof7q*uW!@kdgT76_O zz&-n29hMu>B5_qG_oFApQraVi>WQkFUapr;7wVf;>%mIi&NhR{>3Tq*HnpDRp|7vD zu|Y$3Q-JIHDUn8_45Hqo&8v7F7A`|uLL$GZAM=#`$VFOr@U_$s$1I{KBEAO_(Q`@U z`DGueT;)=Yg_oc}UmVcFPh|WV`kNeT%z{(KlBdEV>k&&=26_GF+r+tZymWUmojq$a zrCLF5LONmCRpX*33Z6&TC_m@~dkIRZk5yg_~e&m}nyJpH9MvymIBB%!y(nzR5@FxhkR- z05>#4xU=_{D%_r8nfGGQ4()}iSC_}E*F-GlpY3>$U(_Oc-FuP(4y#N(GJQ7vG(7U6 z@Qg~uT)%~k(JlT^@r3D(!32Lvnbw~TTZB58Fnc^LRP}iK!O;33{Dkcj-EtFg(wh~3 zdT`9@h5Ml$$L_rX*u(DL;+=vmJ8k$=^6z@0=}+Mc}Fie>kH5S89Z{;z5PBG=X8lrkt(@1|}2Me;jA}cSb3!f9x9r6T`oJ zrZf}Z|IG1BLjRhHnHl~|ZLTo^vHsDTf9cczReAsb34rFWK?MLX{-y!;n*adte`)9L eDB$Pi>o4f)XJm*2!20X_(ruVoaOWBS+5A7V>0!eF diff --git a/browser-extensions/firefox/table-sort.js b/browser-extensions/firefox/table-sort.js index 455c4d2..1a9a2c0 100644 --- a/browser-extensions/firefox/table-sort.js +++ b/browser-extensions/firefox/table-sort.js @@ -55,57 +55,61 @@ function tableSortJs(testingTableSortJS = false, domDocumentWindow = document) { } function inferSortClasses(tableRows, columnIndex, column, 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; - // Don'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 numericRegex = /^(?:\(\d+(?:\.\d+)?\)|-?\d+(?:\.\d+)?)$/; doesn't handle commas - const numericRegex = - /^-?(?:\d{1,3}(?:[',]\d{3})*(?:\.\d+)?|\d+(?:\.\d+)?(?:[',]\d{3})*?)$/; - 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 }, - numericRegex: { regexp: numericRegex, class: "numeric-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( - column.span[columnIndex] === 1 - ? column.spanSum[columnIndex] - 1 - : column.spanSum[columnIndex] - column.span[columnIndex] - ); - let foundMatch = false; - for (let key of Object.keys(inferableClasses)) { - let classRegexp = inferableClasses[key].regexp; - if (tableColumn?.innerText !== undefined) { - if (tableColumn.innerText.match(classRegexp)) { - foundMatch = true; - inferableClasses[key].count++; + try { + 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; + // Don'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 numericRegex = /^(?:\(\d+(?:\.\d+)?\)|-?\d+(?:\.\d+)?)$/; doesn't handle commas + const numericRegex = + /^-?(?:\d{1,3}(?:[',]\d{3})*(?:\.\d+)?|\d+(?:\.\d+)?(?:[',]\d{3})*?)$/; + 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 }, + numericRegex: { regexp: numericRegex, class: "numeric-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( + column.span[columnIndex] === 1 + ? column.spanSum[columnIndex] - 1 + : column.spanSum[columnIndex] - column.span[columnIndex] + ); + let foundMatch = false; + for (let key of Object.keys(inferableClasses)) { + let classRegexp = inferableClasses[key].regexp; + if (tableColumn.innerText !== undefined) { + if (tableColumn.innerText.match(classRegexp)) { + foundMatch = true; + inferableClasses[key].count++; + } + } + if (inferableClasses[key].count >= threshold) { + th.classList.add(inferableClasses[key].class); + classNameAdded = true; + break; } } - if (inferableClasses[key].count >= threshold) { - th.classList.add(inferableClasses[key].class); - classNameAdded = true; + if (classNameAdded) { break; } + if (!foundMatch) { + regexNotFoundCount++; + continue; + } } - if (classNameAdded) { - break; - } - if (!foundMatch) { - regexNotFoundCount++; - continue; - } + } catch (e) { + console.log(e); } } diff --git a/npm/README.md b/npm/README.md index 37ca0b9..0acc86a 100644 --- a/npm/README.md +++ b/npm/README.md @@ -61,12 +61,12 @@ Examples on using table-sort-js with frontend frameworks such as [React.js](http
-| <th> classes | Description | -| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- | -| "data-sort" | Sort by [data attributes](https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes), e.g <td data-sort="42"> | -| "dates-mdy-sort" | Sorts dates in US style mm/dd/yyyy format;. e.g (12/28/2023). Can use "/" or "-" as separator. Overides inferred "dates-dmy-sort" class. | -| "onload-sort" | Sort column on loading of the page. Simulates a click from the user. (can only sort onload for one column) | -| "disable-sort" | Disallow sorting the table by this specific column. | +| <th> classes | Description | +| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| "data-sort" | Sort by [data attributes](https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes), e.g <td data-sort="42">. Useful for doing custom sorts. | +| "dates-mdy-sort" | Sorts dates in US style mm/dd/yyyy format;. e.g (12/28/2023). Can use "/" or "-" as separator. Overides inferred "dates-dmy-sort" class. | +| "onload-sort" | Sort column on loading of the page. Simulates a click from the user. (can only sort onload for one column) | +| "disable-sort" | Disallow sorting the table by this specific column. |
diff --git a/npm/package.json b/npm/package.json index 880a314..0a910a8 100644 --- a/npm/package.json +++ b/npm/package.json @@ -1,6 +1,6 @@ { "name": "table-sort-js", - "version": "1.18.0", + "version": "1.18.1", "description": "A JavaScript client-side HTML table sorting library with no dependencies required.", "license": "MIT", "repository": "LeeWannacott/table-sort-js", diff --git a/npm/table-sort.js b/npm/table-sort.js index 455c4d2..1a9a2c0 100644 --- a/npm/table-sort.js +++ b/npm/table-sort.js @@ -55,57 +55,61 @@ function tableSortJs(testingTableSortJS = false, domDocumentWindow = document) { } function inferSortClasses(tableRows, columnIndex, column, 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; - // Don'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 numericRegex = /^(?:\(\d+(?:\.\d+)?\)|-?\d+(?:\.\d+)?)$/; doesn't handle commas - const numericRegex = - /^-?(?:\d{1,3}(?:[',]\d{3})*(?:\.\d+)?|\d+(?:\.\d+)?(?:[',]\d{3})*?)$/; - 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 }, - numericRegex: { regexp: numericRegex, class: "numeric-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( - column.span[columnIndex] === 1 - ? column.spanSum[columnIndex] - 1 - : column.spanSum[columnIndex] - column.span[columnIndex] - ); - let foundMatch = false; - for (let key of Object.keys(inferableClasses)) { - let classRegexp = inferableClasses[key].regexp; - if (tableColumn?.innerText !== undefined) { - if (tableColumn.innerText.match(classRegexp)) { - foundMatch = true; - inferableClasses[key].count++; + try { + 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; + // Don'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 numericRegex = /^(?:\(\d+(?:\.\d+)?\)|-?\d+(?:\.\d+)?)$/; doesn't handle commas + const numericRegex = + /^-?(?:\d{1,3}(?:[',]\d{3})*(?:\.\d+)?|\d+(?:\.\d+)?(?:[',]\d{3})*?)$/; + 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 }, + numericRegex: { regexp: numericRegex, class: "numeric-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( + column.span[columnIndex] === 1 + ? column.spanSum[columnIndex] - 1 + : column.spanSum[columnIndex] - column.span[columnIndex] + ); + let foundMatch = false; + for (let key of Object.keys(inferableClasses)) { + let classRegexp = inferableClasses[key].regexp; + if (tableColumn.innerText !== undefined) { + if (tableColumn.innerText.match(classRegexp)) { + foundMatch = true; + inferableClasses[key].count++; + } + } + if (inferableClasses[key].count >= threshold) { + th.classList.add(inferableClasses[key].class); + classNameAdded = true; + break; } } - if (inferableClasses[key].count >= threshold) { - th.classList.add(inferableClasses[key].class); - classNameAdded = true; + if (classNameAdded) { break; } + if (!foundMatch) { + regexNotFoundCount++; + continue; + } } - if (classNameAdded) { - break; - } - if (!foundMatch) { - regexNotFoundCount++; - continue; - } + } catch (e) { + console.log(e); } }