43 lines
1.1 KiB
TypeScript
43 lines
1.1 KiB
TypeScript
let RE_NOT_LETTER: RegExp;
|
||
|
||
try {
|
||
RE_NOT_LETTER = /[^\p{L}\p{M}]+/ui;
|
||
} catch (e) {
|
||
// Support for older versions of firefox
|
||
RE_NOT_LETTER = /[^\wа-яё]+/i;
|
||
}
|
||
|
||
export default function searchWords(haystack: string, needle: string | string[]) {
|
||
if (!haystack || !needle) {
|
||
return false;
|
||
}
|
||
|
||
const needleWords = typeof needle === 'string' ? needle.toLowerCase().split(RE_NOT_LETTER) : needle;
|
||
const haystackLower = haystack.toLowerCase();
|
||
|
||
// @optimization
|
||
if (needleWords.length === 1 && !haystackLower.includes(needleWords[0])) {
|
||
return false;
|
||
}
|
||
|
||
let haystackWords: string[];
|
||
|
||
return needleWords.every((needleWord) => {
|
||
if (!haystackLower.includes(needleWord)) {
|
||
return false;
|
||
}
|
||
|
||
if (!haystackWords) {
|
||
haystackWords = haystackLower.split(RE_NOT_LETTER);
|
||
}
|
||
|
||
return haystackWords.some((haystackWord) => haystackWord.startsWith(needleWord));
|
||
});
|
||
}
|
||
|
||
export function prepareSearchWordsForNeedle(needle: string) {
|
||
const needleWords = needle.toLowerCase().split(RE_NOT_LETTER);
|
||
|
||
return (haystack: string) => searchWords(haystack, needleWords);
|
||
}
|