function autoSuggestService() {
var exports = {};
var levenshtein = window.Levenshtein;
function getDistance(str1, str2) {
//levenshtein.get('mikailovitch', 'Mikhaïlovitch', { useCollator: true});
return levenshtein.get(str1, str2, {
useCollator: true
});
}
function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\&'); // & means the whole matched string
}
var getWordsRegEx = new RegExp('\\b([^.,? ]+?)\\b', 'gm');
var getWordsRegEx = new RegExp('([^\\s.,;:]+)', 'gm');
function getWords(str) {
var matches = [];
var match;
while (match = getWordsRegEx.exec(str)) {
if (match[1].length > 0) { matches.push(match[1]); }
}
return matches;
}
function replaceWord(str, find, replace) {
return str.replace(new RegExp('\\b' + escapeRegExp(find) + '\\b', 'gmi'), replace);
}
function multiFor(a, b, fn) {
for (var i = 0; i < a.length; i++) {
for (var j = 0; j < b.length; j++) {
var res = fn(a[i], b[j]);
if (res === false) { break; }
}
}
}
function arrayCountMatch(a, b) {
var matchCount = 0;
multiFor(a, b, function (c, d) { if (c === d) { matchCount++; } });
return matchCount;
}
function getUniqueWords(suggestions) {
var wordMap = {};
suggestions.forEach(function (s) { var words = getWords((s.text || ''));
words.forEach(function (w) { wordMap[w] = true; }); });
return Object.keys(wordMap);
}
function findWordSuggestions(text, uniqueWords) {
if (!text || text === '' || text === ' ') { return []; }
var words = getWords(text);
var results = [];
multiFor(words, uniqueWords, function (word, uniqueWord) {
var lowerWord = word.toLowerCase(); var lowerUniqueWord = uniqueWord.toLowerCase();
if (lowerUniqueWord === lowerWord) {
return; // exact word no suggestions
}
if (lowerUniqueWord.charAt(0) !== lowerWord.charAt(0)) { return; }
var dist = getDistance(lowerWord, lowerUniqueWord.slice(0, lowerWord.length));
var score = (lowerWord.length / (dist + 1 * lowerWord.length));
if (score >= 0.7) { results.push({ src: word, target: uniqueWord, score: score }); }
});
results.sort(function (a, b) { return b.score - a.score; }); return results;
}
function findSuggestions(text, suggestions) {
var results = [];
if (typeof text === 'string' && text.length > 3) {
text = text.toLowerCase(); var words = getWords(text); if (words.length < 1) { return results; }
suggestions.forEach(function (s) {
var str = (s.text || '').toLowerCase();
if (str.indexOf(text) >= 0) { s.score = 1; results.push(s); return; }
var sugWords = getWords(str);
var matchCount = arrayCountMatch(words, sugWords);
if (matchCount > 0) {
s.score = matchCount / Math.min(words.length, sugWords.length);
if (s.score > 0.2) { results.push(s); }
}
});
} results.sort(function (a, b) { return b.score - a.score; }); return results;
}
exports = { findSuggestions: findSuggestions, findWordSuggestions: findWordSuggestions, getUniqueWords: getUniqueWords, replaceWord: replaceWord }; return exports;
}
function loadSuggestions() {
var suggestions = [{ text: '', value: '' }];
return suggestions;
}
var _suggestions = null;
function getSuggestions() {
if (!_suggestions) {
_suggestions = loadSuggestions();
}
return _suggestions;
}
function getSuggestionsForText(text) {
return getSuggestions()
.then(function (suggestions) {
return autoSuggestService.findSuggestions(text, suggestions);
});
}
function getWordSuggestionsForText(text) {
return getSuggestions()
.then(function (suggestions) {
var uniqueWords = autoSuggestService.getUniqueWords(suggestions);
return autoSuggestService.findWordSuggestions(text, uniqueWords);
});
}
131300cookie-checkJavascript autosuggest service (levenshtein + word matching)