158 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			158 lines
		
	
	
		
			3.9 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 = {};
 | 
						|
 | 
						|
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 addCustomToPool(custom, pool) {
 | 
						|
  custom.forEach((emoji) => {
 | 
						|
    let emojiId = emoji.id || emoji.short_names[0];
 | 
						|
 | 
						|
    if (emojiId && !pool[emojiId]) {
 | 
						|
      pool[emojiId] = getData(emoji);
 | 
						|
      emojisList[emojiId] = getSanitizedData(emoji);
 | 
						|
    }
 | 
						|
  });
 | 
						|
}
 | 
						|
 | 
						|
function search(value, { emojisToShowFilter, maxResults, include, exclude, custom = [] } = {}) {
 | 
						|
  addCustomToPool(custom, originalPool);
 | 
						|
 | 
						|
  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].unified));
 | 
						|
    }
 | 
						|
 | 
						|
    if (results && results.length > maxResults) {
 | 
						|
      results = results.slice(0, maxResults);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return results;
 | 
						|
}
 | 
						|
 | 
						|
export { search };
 |