From b829a0c687562e7e711aafbd849b243b2a64ae02 Mon Sep 17 00:00:00 2001 From: Thomas Piccirello Date: Sun, 14 Jul 2019 21:34:12 -0700 Subject: [PATCH] Support exclusions in WebUI table filters Closes #10241 --- src/webui/www/private/scripts/dynamicTable.js | 30 ++++------------ src/webui/www/private/scripts/misc.js | 34 +++++++++++++++++++ 2 files changed, 40 insertions(+), 24 deletions(-) diff --git a/src/webui/www/private/scripts/dynamicTable.js b/src/webui/www/private/scripts/dynamicTable.js index 78d0d5baf..3ad61d130 100644 --- a/src/webui/www/private/scripts/dynamicTable.js +++ b/src/webui/www/private/scripts/dynamicTable.js @@ -1268,12 +1268,9 @@ const TorrentsTable = new Class({ } } - if (filterTerms) { - for (let i = 0; i < filterTerms.length; ++i) { - if (name.indexOf(filterTerms[i]) === -1) - return false; - } - } + if ((filterTerms !== undefined) && (filterTerms !== null) + && (filterTerms.length > 0) && !containsAllTerms(name, filterTerms)) + return false; return true; }, @@ -1517,16 +1514,6 @@ const SearchResultsTable = new Class({ }, getFilteredAndSortedRows: function() { - const containsAll = function(text, searchTerms) { - text = text.toLowerCase(); - for (let i = 0; i < searchTerms.length; ++i) { - if (text.indexOf(searchTerms[i].toLowerCase()) === -1) - return false; - } - - return true; - }; - const getSizeFilters = function() { let minSize = (searchSizeFilter.min > 0.00) ? (searchSizeFilter.min * Math.pow(1024, searchSizeFilter.minUnit)) : 0.00; let maxSize = (searchSizeFilter.max > 0.00) ? (searchSizeFilter.max * Math.pow(1024, searchSizeFilter.maxUnit)) : 0.00; @@ -1571,8 +1558,8 @@ const SearchResultsTable = new Class({ for (let i = 0; i < rows.length; ++i) { const row = rows[i]; - if (searchInTorrentName && !containsAll(row.full_data.fileName, searchTerms)) continue; - if ((filterTerms.length > 0) && !containsAll(row.full_data.fileName, filterTerms)) continue; + if (searchInTorrentName && !containsAllTerms(row.full_data.fileName, searchTerms)) continue; + if ((filterTerms.length > 0) && !containsAllTerms(row.full_data.fileName, filterTerms)) continue; if ((sizeFilters.min > 0.00) && (row.full_data.fileSize < sizeFilters.min)) continue; if ((sizeFilters.max > 0.00) && (row.full_data.fileSize > sizeFilters.max)) continue; if ((seedsFilters.min > 0) && (row.full_data.nbSeeders < seedsFilters.min)) continue; @@ -1907,12 +1894,7 @@ const TorrentFilesTable = new Class({ } } - const lowercaseName = node.name.toLowerCase(); - const matchesFilter = filterTerms.every(function(term) { - return (lowercaseName.indexOf(term) !== -1); - }); - - if (matchesFilter) { + if (containsAllTerms(node.name, filterTerms)) { const row = this.getRow(node); filteredRows.push(row); return true; diff --git a/src/webui/www/private/scripts/misc.js b/src/webui/www/private/scripts/misc.js index 589bb8548..b2b9e8b3c 100644 --- a/src/webui/www/private/scripts/misc.js +++ b/src/webui/www/private/scripts/misc.js @@ -167,3 +167,37 @@ function toFixedPointString(number, digits) { const power = Math.pow(10, digits); return (Math.floor(power * number) / power).toFixed(digits); } + +/** + * + * @param {String} text the text to search + * @param {Array} terms terms to search for within the text + * @returns {Boolean} true if all terms match the text, false otherwise + */ +function containsAllTerms(text, terms) { + const textToSearch = text.toLowerCase(); + for (let i = 0; i < terms.length; ++i) { + const term = terms[i].trim().toLowerCase(); + if ((term[0] === '-')) { + // ignore lonely - + if (term.length === 1) + continue; + // disallow any text after - + if (textToSearch.indexOf(term.substring(1)) !== -1) + return false; + } + else if ((term[0] === '+')) { + // ignore lonely + + if (term.length === 1) + continue; + // require any text after + + if (textToSearch.indexOf(term.substring(1)) === -1) + return false; + } + else if (textToSearch.indexOf(term) === -1){ + return false; + } + } + + return true; +}