From 0c2ad0dab50c4c3721074ce3bc8459ebfce42ccb Mon Sep 17 00:00:00 2001 From: Aliullov Vlad Date: Thu, 29 Aug 2024 22:58:13 +0400 Subject: [PATCH] Fix filtering issues for string in different locales (T1242756) --- packages/devextreme/js/core/utils/data.js | 2 +- packages/devextreme/js/data/array_query.js | 80 +++------------------- 2 files changed, 12 insertions(+), 70 deletions(-) diff --git a/packages/devextreme/js/core/utils/data.js b/packages/devextreme/js/core/utils/data.js index b5a471b12168..11fb29ec699d 100644 --- a/packages/devextreme/js/core/utils/data.js +++ b/packages/devextreme/js/core/utils/data.js @@ -201,7 +201,7 @@ export const toComparable = function(value, caseSensitive, options = {}) { const isCaseSensitive = collatorSensitivity === 'case' || caseSensitive; if(typeof value === 'string' && !isCaseSensitive) { - return options?.locale ? value.toLocaleLowerCase(options.locale) : value.toLowerCase(); + return options?.locale ? value.toLocaleUpperCase(options.locale) : value.toUpperCase(); } return value; diff --git a/packages/devextreme/js/data/array_query.js b/packages/devextreme/js/data/array_query.js index a93c5ec9acc6..738bfb1ccdf2 100644 --- a/packages/devextreme/js/data/array_query.js +++ b/packages/devextreme/js/data/array_query.js @@ -242,14 +242,7 @@ const SortIterator = Iterator.inherit({ const compileCriteria = (function() { let langParams = {}; - const _toComparable = (value, caseSensitivity = false) => toComparable(value, caseSensitivity, langParams); - - const toLowerCase = (value) => langParams?.locale ? value.toLocaleLowerCase(langParams.locale) : value.toLowerCase(); - const toUpperCase = (value) => langParams?.locale ? value.toLocaleUpperCase(langParams.locale) : value.toUpperCase(); - - const compareCaseInsensitive = (value1, value2) => { - return toLowerCase(value1) === toLowerCase(value2) || toUpperCase(value1) === toUpperCase(value2); - }; + const _toComparable = (value) => toComparable(value, false, langParams); const compileUniformEqualsCriteria = (crit) => { const getter = compileGetter(crit[0][0]); @@ -316,9 +309,9 @@ const compileCriteria = (function() { crit = normalizeBinaryCriterion(crit); const getter = compileGetter(crit[0]); const op = crit[1]; - const origValue = crit[2]; + let value = crit[2]; - const value = _toComparable(origValue); + value = _toComparable(value); const compare = (obj, operatorFn) => { obj = _toComparable(getter(obj)); @@ -327,9 +320,9 @@ const compileCriteria = (function() { switch(op.toLowerCase()) { case '=': - return compileEquals(getter, origValue); + return compileEquals(getter, value); case '<>': - return compileEquals(getter, origValue, true); + return compileEquals(getter, value, true); case '>': return (obj) => compare(obj, (a, b) => a > b); case '<': @@ -339,52 +332,13 @@ const compileCriteria = (function() { case '<=': return (obj) => compare(obj, (a, b) => a <= b); case 'startswith': - return function(obj) { - let objValue = toString(getter(obj)); - let result; - - if(objValue.length < origValue.length) { - return false; - } - - if(langParams.collatorOptions?.sensitivity !== 'case') { - objValue = _toComparable(objValue, true); - const searchValue = _toComparable(origValue, true); - - result = toUpperCase(objValue).startsWith(toUpperCase(searchValue)) || - toLowerCase(objValue).startsWith(toLowerCase(searchValue)); - } else { - result = _toComparable(objValue).startsWith(value); - } - - return result; - }; + return (obj) => _toComparable(toString(getter(obj))).startsWith(value); case 'endswith': - return function(obj) { - let objValue = toString(getter(obj)); - let searchValue = toString(origValue); - - if(objValue.length < searchValue.length) { - return false; - } - - let result = _toComparable(objValue).endsWith(_toComparable(searchValue)); - - if(!result && langParams.collatorOptions?.sensitivity !== 'case') { - objValue = _toComparable(objValue, true); - searchValue = _toComparable(searchValue, true); - - result = toUpperCase(objValue).endsWith(toUpperCase(searchValue)); - } - - return result; - }; + return (obj) => _toComparable(toString(getter(obj))).endsWith(value); case 'contains': - return function(obj) { - return _toComparable(toString(getter(obj))).indexOf(value) > -1; - }; + return (obj) => _toComparable(toString(getter(obj))).includes(value); case 'notcontains': - return function(obj) { return _toComparable(toString(getter(obj))).indexOf(value) === -1; }; + return (obj) => !_toComparable(toString(getter(obj))).includes(value); } throw errors.Error('E4003', op); @@ -392,25 +346,13 @@ const compileCriteria = (function() { function compileEquals(getter, value, negate) { return function(obj) { - obj = getter(obj); + obj = _toComparable(getter(obj)); // eslint-disable-next-line eqeqeq - let result; - - if(typeof obj === 'string' && typeof value === 'string' && langParams.collatorOptions?.sensitivity !== 'case' && !useStrictComparison(value)) { - /* eslint-disable-next-line no-undef */ - result = compareCaseInsensitive(_toComparable(value, true), _toComparable(obj, true)); - } else { - obj = _toComparable(obj); - value = _toComparable(value); - - // eslint-disable-next-line eqeqeq - result = useStrictComparison(value) ? obj === value : obj == value; - } + let result = useStrictComparison(value) ? obj === value : obj == value; if(negate) { result = !result; } - return result; }; }