bf508b9f74
* Changes behavior from search light to keep custom search The new version of emoji-mart needs the search function to constantly receive the custom emoji array. This changes the behavior back to the previous one in the search light method to keep the emoji autocomplete as before * Change test order The order was breaking the tests * Fix codeclimate issues * Update to emoji mart to version without issue in picker Fixes #7760
177 lines
4.3 KiB
JavaScript
177 lines
4.3 KiB
JavaScript
// This code is largely borrowed from:
|
|
// https://github.com/missive/emoji-mart/blob/5f2ffcc/src/utils/emoji-index.js
|
|
|
|
import data from './emoji_mart_data_light';
|
|
import { getData, getSanitizedData, intersect } from './emoji_utils';
|
|
|
|
let originalPool = {};
|
|
let index = {};
|
|
let emojisList = {};
|
|
let emoticonsList = {};
|
|
let customEmojisList = [];
|
|
|
|
for (let emoji in data.emojis) {
|
|
let emojiData = data.emojis[emoji];
|
|
let { short_names, emoticons } = emojiData;
|
|
let id = short_names[0];
|
|
|
|
if (emoticons) {
|
|
emoticons.forEach(emoticon => {
|
|
if (emoticonsList[emoticon]) {
|
|
return;
|
|
}
|
|
|
|
emoticonsList[emoticon] = id;
|
|
});
|
|
}
|
|
|
|
emojisList[id] = getSanitizedData(id);
|
|
originalPool[id] = emojiData;
|
|
}
|
|
|
|
function clearCustomEmojis(pool) {
|
|
customEmojisList.forEach((emoji) => {
|
|
let emojiId = emoji.id || emoji.short_names[0];
|
|
|
|
delete pool[emojiId];
|
|
delete emojisList[emojiId];
|
|
});
|
|
}
|
|
|
|
function addCustomToPool(custom, pool) {
|
|
if (customEmojisList.length) clearCustomEmojis(pool);
|
|
|
|
custom.forEach((emoji) => {
|
|
let emojiId = emoji.id || emoji.short_names[0];
|
|
|
|
if (emojiId && !pool[emojiId]) {
|
|
pool[emojiId] = getData(emoji);
|
|
emojisList[emojiId] = getSanitizedData(emoji);
|
|
}
|
|
});
|
|
|
|
customEmojisList = custom;
|
|
index = {};
|
|
}
|
|
|
|
function search(value, { emojisToShowFilter, maxResults, include, exclude, custom } = {}) {
|
|
if (custom !== undefined) {
|
|
if (customEmojisList !== custom)
|
|
addCustomToPool(custom, originalPool);
|
|
} else {
|
|
custom = [];
|
|
}
|
|
|
|
maxResults = maxResults || 75;
|
|
include = include || [];
|
|
exclude = exclude || [];
|
|
|
|
let results = null,
|
|
pool = originalPool;
|
|
|
|
if (value.length) {
|
|
if (value === '-' || value === '-1') {
|
|
return [emojisList['-1']];
|
|
}
|
|
|
|
let values = value.toLowerCase().split(/[\s|,|\-|_]+/),
|
|
allResults = [];
|
|
|
|
if (values.length > 2) {
|
|
values = [values[0], values[1]];
|
|
}
|
|
|
|
if (include.length || exclude.length) {
|
|
pool = {};
|
|
|
|
data.categories.forEach(category => {
|
|
let isIncluded = include && include.length ? include.indexOf(category.name.toLowerCase()) > -1 : true;
|
|
let isExcluded = exclude && exclude.length ? exclude.indexOf(category.name.toLowerCase()) > -1 : false;
|
|
if (!isIncluded || isExcluded) {
|
|
return;
|
|
}
|
|
|
|
category.emojis.forEach(emojiId => pool[emojiId] = data.emojis[emojiId]);
|
|
});
|
|
|
|
if (custom.length) {
|
|
let customIsIncluded = include && include.length ? include.indexOf('custom') > -1 : true;
|
|
let customIsExcluded = exclude && exclude.length ? exclude.indexOf('custom') > -1 : false;
|
|
if (customIsIncluded && !customIsExcluded) {
|
|
addCustomToPool(custom, pool);
|
|
}
|
|
}
|
|
}
|
|
|
|
allResults = values.map((value) => {
|
|
let aPool = pool,
|
|
aIndex = index,
|
|
length = 0;
|
|
|
|
for (let charIndex = 0; charIndex < value.length; charIndex++) {
|
|
const char = value[charIndex];
|
|
length++;
|
|
|
|
aIndex[char] = aIndex[char] || {};
|
|
aIndex = aIndex[char];
|
|
|
|
if (!aIndex.results) {
|
|
let scores = {};
|
|
|
|
aIndex.results = [];
|
|
aIndex.pool = {};
|
|
|
|
for (let id in aPool) {
|
|
let emoji = aPool[id],
|
|
{ search } = emoji,
|
|
sub = value.substr(0, length),
|
|
subIndex = search.indexOf(sub);
|
|
|
|
if (subIndex !== -1) {
|
|
let score = subIndex + 1;
|
|
if (sub === id) score = 0;
|
|
|
|
aIndex.results.push(emojisList[id]);
|
|
aIndex.pool[id] = emoji;
|
|
|
|
scores[id] = score;
|
|
}
|
|
}
|
|
|
|
aIndex.results.sort((a, b) => {
|
|
let aScore = scores[a.id],
|
|
bScore = scores[b.id];
|
|
|
|
return aScore - bScore;
|
|
});
|
|
}
|
|
|
|
aPool = aIndex.pool;
|
|
}
|
|
|
|
return aIndex.results;
|
|
}).filter(a => a);
|
|
|
|
if (allResults.length > 1) {
|
|
results = intersect.apply(null, allResults);
|
|
} else if (allResults.length) {
|
|
results = allResults[0];
|
|
} else {
|
|
results = [];
|
|
}
|
|
}
|
|
|
|
if (results) {
|
|
if (emojisToShowFilter) {
|
|
results = results.filter((result) => emojisToShowFilter(data.emojis[result.id]));
|
|
}
|
|
|
|
if (results && results.length > maxResults) {
|
|
results = results.slice(0, maxResults);
|
|
}
|
|
}
|
|
|
|
return results;
|
|
}
|
|
|
|
export { search };
|