summaryrefslogtreecommitdiffstats
path: root/devtools/shared/natural-sort.js
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--devtools/shared/natural-sort.js120
1 files changed, 120 insertions, 0 deletions
diff --git a/devtools/shared/natural-sort.js b/devtools/shared/natural-sort.js
new file mode 100644
index 0000000000..548c39541c
--- /dev/null
+++ b/devtools/shared/natural-sort.js
@@ -0,0 +1,120 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * Natural Sort algorithm for Javascript - Version 0.8.1 - Released under MIT license
+ * Author: Jim Palmer (based on chunking idea from Dave Koelle)
+ *
+ * Includes pull request to move regexes out of main function for performance
+ * increases.
+ *
+ * Repository:
+ * https://github.com/overset/javascript-natural-sort/
+ */
+
+"use strict";
+
+var re = /(^([+\-]?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?(?=\D|\s|$))|^0x[\da-fA-F]+$|\d+)/g;
+var sre = /^\s+|\s+$/g; // trim pre-post whitespace
+var snre = /\s+/g; // normalize all whitespace to single ' ' character
+
+// eslint-disable-next-line
+var dre = /(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/;
+var hre = /^0x[0-9a-f]+$/i;
+var ore = /^0/;
+var b0re = /^\0/;
+var e0re = /\0$/;
+
+exports.naturalSortCaseSensitive = function naturalSortCaseSensitive(a, b) {
+ return naturalSort(a, b, false);
+};
+
+exports.naturalSortCaseInsensitive = function naturalSortCaseInsensitive(a, b) {
+ return naturalSort(a, b, true);
+};
+
+/**
+ * Sort numbers, strings, IP Addresses, Dates, Filenames, version numbers etc.
+ * "the way humans do."
+ *
+ * This function should only be called via naturalSortCaseSensitive and
+ * naturalSortCaseInsensitive.
+ *
+ * e.g. [3, 2, 1, 10].sort(naturalSort)
+ *
+ * @param {Object} a
+ * Passed in by Array.sort(a, b)
+ * @param {Object} b
+ * Passed in by Array.sort(a, b)
+ * @param {Boolean} insensitive
+ * Should the search be case insensitive?
+ */
+// eslint-disable-next-line complexity
+function naturalSort(a, b, insensitive) {
+ // convert all to strings strip whitespace
+ const i = function(s) {
+ return ((insensitive && ("" + s).toLowerCase()) || "" + s).replace(sre, "");
+ };
+ const x = i(a) || "";
+ const y = i(b) || "";
+ // chunk/tokenize
+ const xN = x
+ .replace(re, "\0$1\0")
+ .replace(e0re, "")
+ .replace(b0re, "")
+ .split("\0");
+ const yN = y
+ .replace(re, "\0$1\0")
+ .replace(e0re, "")
+ .replace(b0re, "")
+ .split("\0");
+ // numeric, hex or date detection
+ const xD = parseInt(x.match(hre), 16) || (xN.length !== 1 && Date.parse(x));
+ const yD =
+ parseInt(y.match(hre), 16) || (xD && y.match(dre) && Date.parse(y)) || null;
+ const normChunk = function(s, l) {
+ // normalize spaces; find floats not starting with '0', string or 0 if
+ // not defined (Clint Priest)
+ return (
+ ((!s.match(ore) || l == 1) && parseFloat(s)) ||
+ s.replace(snre, " ").replace(sre, "") ||
+ 0
+ );
+ };
+ let oFxNcL;
+ let oFyNcL;
+
+ // first try and sort Hex codes or Dates
+ if (yD) {
+ if (xD < yD) {
+ return -1;
+ } else if (xD > yD) {
+ return 1;
+ }
+ }
+
+ // natural sorting through split numeric strings and default strings
+ // eslint-disable-next-line
+ for (let cLoc = 0, xNl = xN.length, yNl = yN.length, numS = Math.max(xNl, yNl); cLoc < numS; cLoc++) {
+ oFxNcL = normChunk(xN[cLoc] || "", xNl);
+ oFyNcL = normChunk(yN[cLoc] || "", yNl);
+
+ // handle numeric vs string comparison - number < string - (Kyle Adams)
+ if (isNaN(oFxNcL) !== isNaN(oFyNcL)) {
+ return isNaN(oFxNcL) ? 1 : -1;
+ }
+ // if unicode use locale comparison
+ // eslint-disable-next-line
+ if (/[^\x00-\x80]/.test(oFxNcL + oFyNcL) && oFxNcL.localeCompare) {
+ const comp = oFxNcL.localeCompare(oFyNcL);
+ return comp / Math.abs(comp);
+ }
+ if (oFxNcL < oFyNcL) {
+ return -1;
+ } else if (oFxNcL > oFyNcL) {
+ return 1;
+ }
+ }
+ return null;
+}