Skip to content

Commit

Permalink
Fix filtering issues for string in different locales
Browse files Browse the repository at this point in the history
  • Loading branch information
GoodDayForSurf committed Aug 29, 2024
1 parent 463e0dd commit fee59e3
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 19 deletions.
15 changes: 9 additions & 6 deletions packages/devextreme/js/core/utils/data.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,14 +190,17 @@ export const toComparable = function(value, caseSensitive, options = {}) {
return value.valueOf();
}

const isCaseSensitive = options?.collatorOptions?.sensitivity === 'case' || caseSensitive;
if(!isCaseSensitive && typeof value === 'string') {
if(options?.collatorOptions?.sensitivity === 'base') {
const REMOVE_DIACRITICAL_MARKS_REGEXP = /[\u0300-\u036f]/g;
const collatorSensitivity = options?.collatorOptions?.sensitivity;

value = value.normalize('NFD').replace(REMOVE_DIACRITICAL_MARKS_REGEXP, '');
}
if(typeof value === 'string' && collatorSensitivity === 'base') {
const REMOVE_DIACRITICAL_MARKS_REGEXP = /[\u0300-\u036f]/g;

value = value.normalize('NFD').replace(REMOVE_DIACRITICAL_MARKS_REGEXP, '');
}

const isCaseSensitive = collatorSensitivity === 'case' || caseSensitive;

if(typeof value === 'string' && !isCaseSensitive) {
return options?.locale ? value.toLocaleLowerCase(options.locale) : value.toLowerCase();
}

Expand Down
42 changes: 29 additions & 13 deletions packages/devextreme/js/data/array_query.js
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ const SortIterator = Iterator.inherit({
const compileCriteria = (function() {
let langParams = {};

const _toComparable = (value) => toComparable(value, false, langParams);
const _toComparable = (value, caseSensitivity = false) => toComparable(value, caseSensitivity, langParams);

const compileUniformEqualsCriteria = (crit) => {
const getter = compileGetter(crit[0][0]);
Expand Down Expand Up @@ -309,9 +309,8 @@ const compileCriteria = (function() {
crit = normalizeBinaryCriterion(crit);
const getter = compileGetter(crit[0]);
const op = crit[1];
let value = crit[2];

value = _toComparable(value);
const origValue = crit[2];
const value = _toComparable(origValue);

const compare = (obj, operatorFn) => {
obj = _toComparable(getter(obj));
Expand All @@ -320,9 +319,9 @@ const compileCriteria = (function() {

switch(op.toLowerCase()) {
case '=':
return compileEquals(getter, value);
return compileEquals(getter, origValue);
case '<>':
return compileEquals(getter, value, true);
return compileEquals(getter, origValue, true);
case '>':
return (obj) => compare(obj, (a, b) => a > b);
case '<':
Expand All @@ -332,7 +331,14 @@ const compileCriteria = (function() {
case '<=':
return (obj) => compare(obj, (a, b) => a <= b);
case 'startswith':
return function(obj) { return _toComparable(toString(getter(obj))).indexOf(value) === 0; };
return function(obj) {
const objValue = _toComparable(toString(getter(obj)));
const result = objValue.indexOf(value) === 0;
/* eslint-disable-next-line no-undef */
const compareResult = new Intl.Collator(langParams.locale, { sensitivity: 'base', usage: 'search' }).compare(_toComparable(value, true), objValue);

return result || (compareResult === 0 || compareResult === -1);
};
case 'endswith':
return function(obj) {
const getterValue = _toComparable(toString(getter(obj)));
Expand All @@ -356,14 +362,24 @@ const compileCriteria = (function() {

function compileEquals(getter, value, negate) {
return function(obj) {
obj = _toComparable(getter(obj));
// eslint-disable-next-line eqeqeq
let result = useStrictComparison(value) ? obj === value : obj == value;
let result;

obj = getter(obj);

if(negate) {
result = !result;
if(typeof obj === 'string' && typeof value === 'string' && langParams?.locale) {
/* eslint-disable-next-line no-undef */
const compareResult = new Intl.Collator(langParams.locale, { sensitivity: 'base', usage: 'search' }).compare(_toComparable(value, true), _toComparable(obj, true));

result = compareResult === 0;
} else {
obj = _toComparable(getter(obj));
value = _toComparable(value);

// eslint-disable-next-line eqeqeq
result = useStrictComparison(value) ? obj === value : obj == value;
}
return result;

return negate ? !result : result;
};
}

Expand Down

0 comments on commit fee59e3

Please sign in to comment.