From 4e84e1265e0f729c0ee8aed3bd8178bf16d4b426 Mon Sep 17 00:00:00 2001 From: Viktor Podzigun Date: Fri, 5 Apr 2024 22:06:39 +0200 Subject: [PATCH] Removed sort data from FileListItem --- README.md | 2 +- package.json | 2 +- src/api/FileListItem.d.ts | 6 --- src/api/FileListItem.mjs | 38 --------------- src/sort/FileListSort.mjs | 84 +++++++++++++++++++++++--------- test/api/FileListItem.test.mjs | 86 ++------------------------------- test/sort/FileListSort.test.mjs | 5 -- 7 files changed, 69 insertions(+), 154 deletions(-) diff --git a/README.md b/README.md index 5e810ef..cd21e22 100644 --- a/README.md +++ b/README.md @@ -4,4 +4,4 @@ ## @farjs/filelist -Common FileList api/plugin/interfaces library. +Common plugin/api/ui library for FAR.js **File Browser** module. diff --git a/package.json b/package.json index 2ec8a3c..9d6c4f7 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "author": "viktor-podzigun", "version": "0.0.0", "license": "MIT", - "description": "Common FileList api/plugin/interfaces", + "description": "Common plugin/api/ui for FAR.js File Browser module", "scripts": { "lint": "quick-lint-js ./**/*.mjs ./**/*.ts", "test": "tsc && bun test && node ./test/all.mjs", diff --git a/src/api/FileListItem.d.ts b/src/api/FileListItem.d.ts index 7c63dc6..ee053e9 100644 --- a/src/api/FileListItem.d.ts +++ b/src/api/FileListItem.d.ts @@ -11,10 +11,4 @@ export interface FileListItem { * Format: `drwx---rwx` */ readonly permissions: string; - - nameNormalized(): string; - ext(): string; - extNormalized(): string; - - toString(): string; } diff --git a/src/api/FileListItem.mjs b/src/api/FileListItem.mjs index 2e298af..a7ffd3b 100644 --- a/src/api/FileListItem.mjs +++ b/src/api/FileListItem.mjs @@ -8,38 +8,6 @@ * @returns {FileListItem} */ function FileListItem(name, isDir) { - /** @type {string | null} */ - let _nameNormalized = null; - - function nameNormalized() { - if (_nameNormalized === null) { - _nameNormalized = name.toLowerCase(); - } - return _nameNormalized; - } - - /** @type {string | null} */ - let _ext = null; - - function ext() { - if (_ext === null) { - const dotIndex = name.lastIndexOf("."); - if (dotIndex < 0) _ext = name; - else _ext = name.slice(dotIndex + 1); - } - return _ext; - } - - /** @type {string | null} */ - let _extNormalized = null; - - function extNormalized() { - if (_extNormalized === null) { - _extNormalized = ext().toLowerCase(); - } - return _extNormalized; - } - return { name, isDir: !!isDir, @@ -50,12 +18,6 @@ function FileListItem(name, isDir) { ctimeMs: 0, birthtimeMs: 0, permissions: "", - nameNormalized, - ext, - extNormalized, - toString: () => { - return name; - }, }; } diff --git a/src/sort/FileListSort.mjs b/src/sort/FileListSort.mjs index ea9a937..22c453c 100644 --- a/src/sort/FileListSort.mjs +++ b/src/sort/FileListSort.mjs @@ -11,7 +11,9 @@ import SortMode from "./SortMode.mjs"; * @returns {FileListSort} */ function nextSort(sort, nextMode) { - /** @returns {boolean} */ + /** + * @returns {boolean} + */ function nextAsc() { if (sort.mode === nextMode) { return !sort.asc; @@ -37,32 +39,46 @@ function nextSort(sort, nextMode) { } /** - * @param {string} s1 - * @param {string} s2 + * @typedef {{ + * idx: number, + * name: string, + * nameNormalized: string, + * ext: string, + * extNormalized: string, + * size: number, + * atimeMs: number, + * mtimeMs: number, + * ctimeMs: number, + * }} SortableItem + */ + +/** + * @param {string} a + * @param {string} b * @returns {number} */ -function strCompare(s1, s2) { - return s1 === s2 ? 0 : s1 < s2 ? -1 : 1; +function strCompare(a, b) { + return a === b ? 0 : a < b ? -1 : 1; } /** - * @param {FileListItem} i1 - * @param {FileListItem} i2 + * @param {SortableItem} a + * @param {SortableItem} b * @returns {number} */ -function sortByName(i1, i2) { - const res = strCompare(i1.nameNormalized(), i2.nameNormalized()); - return res === 0 ? strCompare(i1.name, i2.name) : res; +function sortByName(a, b) { + const res = strCompare(a.nameNormalized, b.nameNormalized); + return res === 0 ? strCompare(a.name, b.name) : res; } /** - * @param {FileListItem} i1 - * @param {FileListItem} i2 + * @param {SortableItem} a + * @param {SortableItem} b * @returns {number} */ -function sortByExt(i1, i2) { - const res = strCompare(i1.extNormalized(), i2.extNormalized()); - return res === 0 ? strCompare(i1.ext(), i2.ext()) : res; +function sortByExt(a, b) { + const res = strCompare(a.extNormalized, b.extNormalized); + return res === 0 ? strCompare(a.ext, b.ext) : res; } /** @@ -71,34 +87,58 @@ function sortByExt(i1, i2) { * @returns {FileListItem[]} */ function sortItems(items, mode) { - const newItems = [...items]; + /** + * @param {(a: SortableItem, b: SortableItem) => number} compareFn + * @returns {FileListItem[]} + */ + function doSort(compareFn) { + const sortableItems = items.map((item, idx) => { + const extIndex = item.name.lastIndexOf("."); + const ext = item.name.substring(extIndex + 1); + + return { + idx, + name: item.name, + nameNormalized: item.name.toLowerCase(), + ext, + extNormalized: ext.toLowerCase(), + size: item.size, + atimeMs: item.atimeMs, + mtimeMs: item.mtimeMs, + ctimeMs: item.ctimeMs, + }; + }); + + return sortableItems.sort(compareFn).map((item) => items[item.idx]); + } + switch (mode) { case SortMode.Name: - return newItems.sort(sortByName); + return doSort(sortByName); case SortMode.Extension: - return newItems.sort((i1, i2) => { + return doSort((i1, i2) => { const res = sortByExt(i1, i2); return res === 0 ? sortByName(i1, i2) : res; }); case SortMode.ModificationTime: - return newItems.sort((i1, i2) => { + return doSort((i1, i2) => { const res = i1.mtimeMs - i2.mtimeMs; return res === 0 ? sortByName(i1, i2) : res; }); case SortMode.Size: - return newItems.sort((i1, i2) => { + return doSort((i1, i2) => { const res = i1.size - i2.size; return res === 0 ? sortByName(i1, i2) : res; }); case SortMode.Unsorted: return items; case SortMode.CreationTime: - return newItems.sort((i1, i2) => { + return doSort((i1, i2) => { const res = i1.ctimeMs - i2.ctimeMs; return res === 0 ? sortByName(i1, i2) : res; }); case SortMode.AccessTime: - return newItems.sort((i1, i2) => { + return doSort((i1, i2) => { const res = i1.atimeMs - i2.atimeMs; return res === 0 ? sortByName(i1, i2) : res; }); diff --git a/test/api/FileListItem.test.mjs b/test/api/FileListItem.test.mjs index 1d8ffb8..eafd0a1 100644 --- a/test/api/FileListItem.test.mjs +++ b/test/api/FileListItem.test.mjs @@ -20,7 +20,7 @@ describe("FileListItem.test.mjs", () => { //then assert.deepEqual(result, { - ...defaultItem(result), + ...defaultItem(), name: "test.file", isDir: false, }); @@ -32,7 +32,7 @@ describe("FileListItem.test.mjs", () => { //then assert.deepEqual(result, { - ...defaultItem(result), + ...defaultItem(), name: "dir", isDir: true, }); @@ -44,7 +44,7 @@ describe("FileListItem.test.mjs", () => { //then assert.deepEqual(result, { - ...defaultItem(result), + ...defaultItem(), name: "..", isDir: true, }); @@ -56,89 +56,17 @@ describe("FileListItem.test.mjs", () => { //then assert.deepEqual(result, { - ...defaultItem(result), + ...defaultItem(), name: ".", isDir: true, }); }); - - it("should return normalized name when item.nameNormalized()", () => { - //given - const item = FileListItem("TEst"); - - //when - const result = item.nameNormalized(); - - //then - assert.deepEqual(result, "test"); - - //when & then - assert.deepEqual(item.nameNormalized() === result, true); - assert.deepEqual(FileListItem("").nameNormalized(), ""); - assert.deepEqual(FileListItem("test").nameNormalized(), "test"); - assert.deepEqual(FileListItem("A").nameNormalized(), "a"); - assert.deepEqual(FileListItem("aB").nameNormalized(), "ab"); - assert.deepEqual(FileListItem.up.nameNormalized(), ".."); - assert.deepEqual(FileListItem.currDir.nameNormalized(), "."); - }); - - it("should return file extension when item.ext()", () => { - //given - const item = FileListItem("Test.txt"); - - //when - const result = item.ext(); - - //then - assert.deepEqual(result, "txt"); - - //when & then - assert.deepEqual(item.ext() === result, true); - assert.deepEqual(FileListItem("").ext(), ""); - assert.deepEqual(FileListItem(".").ext(), ""); - assert.deepEqual(FileListItem("test.").ext(), ""); - assert.deepEqual(FileListItem("test").ext(), "test"); - assert.deepEqual(FileListItem(".Test2").ext(), "Test2"); - assert.deepEqual(FileListItem("A").ext(), "A"); - assert.deepEqual(FileListItem("aB").ext(), "aB"); - }); - - it("should return normalized extension when item.extNormalized()", () => { - //given - const item = FileListItem("Test.TXT"); - - //when - const result = item.extNormalized(); - - //then - assert.deepEqual(result, "txt"); - - //when & then - assert.deepEqual(item.extNormalized() === result, true); - assert.deepEqual(FileListItem("").extNormalized(), ""); - assert.deepEqual(FileListItem(".").extNormalized(), ""); - assert.deepEqual(FileListItem("Test.").extNormalized(), ""); - assert.deepEqual(FileListItem("Test").extNormalized(), "test"); - assert.deepEqual(FileListItem(".Test2").extNormalized(), "test2"); - assert.deepEqual(FileListItem("A").extNormalized(), "a"); - assert.deepEqual(FileListItem("aB").extNormalized(), "ab"); - }); - - it("should return name when item.toString()", () => { - //given - const item = FileListItem("Test.file"); - - //when & then - assert.deepEqual(item.toString(), "Test.file"); - assert.deepEqual(`${item}`, "Test.file"); - }); }); /** - * @param {FileListItem} result * @returns {FileListItem} */ -function defaultItem(result) { +function defaultItem() { return { name: "", isDir: false, @@ -149,9 +77,5 @@ function defaultItem(result) { ctimeMs: 0, birthtimeMs: 0, permissions: "", - nameNormalized: result.nameNormalized, - ext: result.ext, - extNormalized: result.extNormalized, - toString: result.toString, }; } diff --git a/test/sort/FileListSort.test.mjs b/test/sort/FileListSort.test.mjs index 7aa228c..6e0f73a 100644 --- a/test/sort/FileListSort.test.mjs +++ b/test/sort/FileListSort.test.mjs @@ -75,11 +75,6 @@ describe("FileListSort.test.mjs", () => { const items = [item0, item1, item2, item3, item4]; const itemsR = [...items].reverse(); - assert.deepEqual(item1.name , "Item.bin"); - assert.deepEqual(item1.nameNormalized() , "item.bin"); - assert.deepEqual(item2.ext() , "BIN"); - assert.deepEqual(item2.extNormalized() , "bin"); - /** * @param {FileListItem[]} items * @param {SortMode} mode