Skip to content

Commit c7a6871

Browse files
r-farkhutdinovRuslan FarkhutdinovCopilot
authored
Lookup: Normalize Unicode form before string comparison to support NFD input (T1326069) (#33256)
Signed-off-by: Ruslan Farkhutdinov <fr3ddy4@yandex.ru> Co-authored-by: Ruslan Farkhutdinov <ruslan.farkhutdinov@devexpress.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
1 parent 1c2c782 commit c7a6871

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

packages/devextreme/js/__internal/core/utils/m_data.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ export const toComparable = function (value, caseSensitive?, options: any = {})
215215
const isCaseSensitive = caseSensitive || collatorSensitivity === 'case' || collatorSensitivity === 'variant';
216216

217217
if (typeof value === 'string' && !isCaseSensitive) {
218+
value = value.normalize('NFC');
218219
const locale = options?.locale?.toLowerCase();
219220
const useUpperCase = locale && !!['hy', 'el'].find((code) => locale === code || locale.startsWith(`${code}-`));
220221

packages/devextreme/testing/tests/DevExpress.ui.widgets.editors/lookup.tests.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3379,6 +3379,36 @@ QUnit.module('dataSource integration', {
33793379
this.clock.tick(loadDelay / 2);
33803380
assert.ok($loadPanel.is(':hidden'), 'load panel is not visible if value length less than minSearchLength)');
33813381
});
3382+
3383+
QUnit.test('search should find items when search value is in NFD Unicode form and items are in NFC form (T1326069)', function(assert) {
3384+
const NFC_CHAR = '\u1EC7'; // precomposed form (NFC)
3385+
const itemsNFC = [
3386+
`test item 1 h${NFC_CHAR}`,
3387+
`test item 2 H${NFC_CHAR}`,
3388+
'test item 3',
3389+
];
3390+
3391+
const instance = this.$element.dxLookup({
3392+
dataSource: itemsNFC,
3393+
searchEnabled: true,
3394+
searchTimeout: 0,
3395+
opened: true
3396+
}).dxLookup('instance');
3397+
3398+
const $content = $(instance.content());
3399+
const $input = $content.find(`.${LOOKUP_SEARCH_CLASS} .${TEXTEDITOR_INPUT_CLASS}`);
3400+
3401+
const searchValueNFD = 'h\u0065\u0323\u0302';
3402+
3403+
assert.notStrictEqual(searchValueNFD, searchValueNFD.normalize('NFC'),
3404+
'NFD and NFC forms are different strings');
3405+
3406+
$($input.val(searchValueNFD)).trigger('input');
3407+
this.clock.tick(0);
3408+
3409+
const $listItems = $content.find(`.${LIST_ITEM_CLASS}`);
3410+
assert.equal($listItems.length, 2, 'items containing the NFC character should be found when searching with its NFD equivalent');
3411+
});
33823412
});
33833413

33843414

0 commit comments

Comments
 (0)