Работа автодополнения в Awesomplete напрямую связана с тем, как библиотека сравнивает строки, фильтрует список и отображает результаты. При переходе от латинских наборов данных к многоязычным источникам основная сложность возникает из-за особенностей Unicode: различий в нормализации, наличии диакритических знаков, разных системах письма и неоднозначного сравнения символов.
Unicode представляет собой универсальную систему кодирования символов, в которой каждый знак — от латиницы до кириллицы, от иероглифов до математических символов — имеет собственный код. В контексте автодополнения это означает, что строка перестаёт быть просто последовательностью байтов и становится структурой, требующей корректной нормализации перед сравнением.
Ключевая проблема заключается в том, что визуально одинаковые строки могут иметь разные представления:
ée + ́ (акцент)Без нормализации такие строки не будут равны при прямом сравнении.
Для корректной работы поиска в Awesomplete необходимо привести все строки к единому виду. Чаще всего используется Unicode Normalization Form C (NFC), которая объединяет составные символы.
function normalize(str) {
return str.normalize("NFC");
}
Однако в задачах поиска часто требуется не только нормализация, но и устранение диакритических знаков:
function stripDiacritics(str) {
return str.normalize("NFD").replace(/[\u0300-\u036f]/g, "");
}
Такой подход позволяет сопоставлять:
как эквивалентные строки.
Обычное toLowerCase() недостаточно в многоязычных
системах. В Unicode существуют языки, где регистровая трансформация
зависит от локали.
Например:
I и İssБолее корректный подход:
function normalizeCase(str) {
return str.toLocaleLowerCase("en");
}
Для универсальных решений часто комбинируют:
function prepare(str) {
return stripDiacritics(
str.normalize("NFC").toLocaleLowerCase("en")
);
}
В Awesomplete фильтрация списка выполняется через функцию
filter. По умолчанию используется простое сравнение начала
строки, но для Unicode это поведение часто требуется заменить.
Базовая настройка:
new Awesomplete(input, {
list: [...],
filter: Awesomplete.FILTER_CONTAINS
});
Однако при работе с многоязычными данными стандартные фильтры не учитывают диакритики и нормализацию. Поэтому используется кастомная логика:
function unicodeFilter(text, input) {
const t = prepare(text);
const i = prepare(input);
return t.indexOf(i) !== -1;
}
Для более точной поддержки различных языков используется
localeCompare. Он учитывает правила конкретной локали:
function unicodeCompare(a, b) {
return a.localeCompare(b, "en", { sensitivity: "base" });
}
Параметр sensitivity: "base" позволяет игнорировать
регистр и диакритические знаки, что особенно важно при поиске в
глобальных каталогах.
Внутренний механизм Awesomplete обычно работает с предположением, что строки уже приведены к сопоставимому виду. Однако при подключении внешних API или динамических источников данных это предположение нарушается.
Типичные проблемы:
Unicode включает эмодзи, которые могут занимать несколько кодовых точек. Это влияет на:
Пример:
"?".length // 2 или больше в зависимости от кодировки
Для корректной работы поиска важно не полагаться на
.length, а использовать посимвольную итерацию:
for (const char of str) {
console.log(char);
}
Awesomplete не требует дополнительной настройки для кириллицы, однако поведение фильтрации зависит от выбранного алгоритма сравнения.
Проблемы возникают при смешанных данных:
Для унификации используется нормализация + приведение к единому алфавитному представлению:
function normalizeMultilang(str) {
return stripDiacritics(
str.normalize("NFC")
).toLocaleLowerCase("en");
}
При работе с динамическими источниками важно нормализовать данные до передачи в Awesomplete:
fetch("/api/cities")
.then(r => r.json())
.then(data => {
awesomplete.list = data.map(item => ({
label: item.name,
value: normalizeMultilang(item.name)
}));
});
Это предотвращает расхождение между отображаемым значением и поисковым индексом.
Корректная схема обработки данных обычно включает несколько этапов:
function pipeline(str) {
return str
.normalize("NFC")
.toLocaleLowerCase("en")
.replace(/[\u0300-\u036f]/g, "");
}
Стандартное автодополнение часто опирается на проверку начала строки. В Unicode это может давать неожиданные результаты при комбинированных символах.
Корректный подход:
function startsWithUnicode(text, input) {
return pipeline(text).startsWith(pipeline(input));
}
Такой метод обеспечивает стабильность независимо от языка и кодировки.
В системах на основе Awesomplete корректная работа с Unicode достигается не изменением самой библиотеки, а подготовкой входных данных и переопределением функций сравнения. Именно слой предобработки определяет, насколько устойчивым будет поиск при работе с глобальными наборами строк, включающими различные системы письма, диакритику и комбинированные символы.