emoji-mart-lazyload/src/utils/index.js

276 lines
5.7 KiB
JavaScript
Raw Normal View History

2018-04-30 00:55:13 +00:00
import { buildSearch } from './data'
2017-09-17 08:54:22 +00:00
import stringFromCodePoint from '../polyfills/stringFromCodePoint'
import { uncompress } from './data'
2017-09-17 08:54:22 +00:00
const COLONS_REGEX = /^(?:\:([^\:]+)\:)(?:\:skin-tone-(\d)\:)?$/
2017-10-07 04:02:02 +00:00
const SKINS = ['1F3FA', '1F3FB', '1F3FC', '1F3FD', '1F3FE', '1F3FF']
2016-07-19 16:27:24 +00:00
function unifiedToNative(unified) {
var unicodes = unified.split('-'),
2018-03-27 18:51:26 +00:00
codePoints = unicodes.map((u) => `0x${u}`)
2016-07-19 16:27:24 +00:00
2017-09-17 08:54:22 +00:00
return stringFromCodePoint.apply(null, codePoints)
2016-07-19 16:27:24 +00:00
}
function sanitize(emoji) {
2017-10-07 04:02:02 +00:00
var {
name,
short_names,
skin_tone,
skin_variations,
emoticons,
unified,
custom,
customCategory,
2017-10-07 04:02:02 +00:00
imageUrl,
} = emoji,
id = emoji.id || short_names[0],
colons = `:${id}:`
2016-07-19 16:27:24 +00:00
if (custom) {
return {
id,
name,
2019-03-18 20:10:40 +00:00
short_names,
colons,
emoticons,
custom,
customCategory,
2017-10-07 04:02:02 +00:00
imageUrl,
}
}
2016-07-19 16:27:24 +00:00
if (skin_tone) {
colons += `:skin-tone-${skin_tone}:`
}
return {
id,
name,
short_names,
2016-07-19 16:27:24 +00:00
colons,
emoticons,
unified: unified.toLowerCase(),
skin: skin_tone || (skin_variations ? 1 : null),
2016-07-19 16:27:24 +00:00
native: unifiedToNative(unified),
}
}
function getSanitizedData() {
return sanitize(getData(...arguments))
}
function getData(emoji, skin, set, data) {
var emojiData = {}
2016-07-19 16:27:24 +00:00
if (typeof emoji == 'string') {
let matches = emoji.match(COLONS_REGEX)
if (matches) {
emoji = matches[1]
if (matches[2]) {
skin = parseInt(matches[2], 10)
}
}
if (data.aliases.hasOwnProperty(emoji)) {
emoji = data.aliases[emoji]
}
if (data.emojis.hasOwnProperty(emoji)) {
emojiData = data.emojis[emoji]
} else {
return null
2016-10-13 00:26:10 +00:00
}
2016-07-19 16:27:24 +00:00
} else if (emoji.id) {
if (data.aliases.hasOwnProperty(emoji.id)) {
emoji.id = data.aliases[emoji.id]
}
if (data.emojis.hasOwnProperty(emoji.id)) {
emojiData = data.emojis[emoji.id]
2016-10-13 00:26:10 +00:00
skin || (skin = emoji.skin)
}
2016-07-19 16:27:24 +00:00
}
if (!Object.keys(emojiData).length) {
emojiData = emoji
emojiData.custom = true
if (!emojiData.search) {
emojiData.search = buildSearch(emoji)
}
}
2017-03-10 17:11:05 +00:00
emojiData.emoticons || (emojiData.emoticons = [])
emojiData.variations || (emojiData.variations = [])
if (emojiData.skin_variations && skin > 1) {
2019-12-30 17:07:47 +00:00
emojiData = JSON.parse(JSON.stringify(emojiData))
2016-07-19 16:27:24 +00:00
2020-03-16 13:07:15 +00:00
var skinKey = SKINS[skin - 1],
variationData = emojiData.skin_variations[skinKey]
2016-07-19 16:27:24 +00:00
2020-03-16 13:07:15 +00:00
if (variationData) {
if (!variationData.variations && emojiData.variations) {
delete emojiData.variations
}
2020-01-26 18:23:41 +00:00
if (
(set &&
(variationData[`has_img_${set}`] == undefined ||
variationData[`has_img_${set}`])) ||
!set
) {
emojiData.skin_tone = skin
2020-01-26 18:23:41 +00:00
for (let k in variationData) {
let v = variationData[k]
emojiData[k] = v
}
2016-07-19 16:27:24 +00:00
}
}
}
if (emojiData.variations && emojiData.variations.length) {
2019-12-30 17:07:47 +00:00
emojiData = JSON.parse(JSON.stringify(emojiData))
emojiData.unified = emojiData.variations.shift()
}
2016-07-19 16:27:24 +00:00
return emojiData
}
function getEmojiDataFromNative(nativeString, set, data) {
if (data.compressed) {
2019-03-23 21:15:47 +00:00
uncompress(data)
}
const skinTones = ['🏻', '🏼', '🏽', '🏾', '🏿']
const skinCodes = ['1F3FB', '1F3FC', '1F3FD', '1F3FE', '1F3FF']
let skin
let skinCode
let baseNativeString = nativeString
skinTones.forEach((skinTone, skinToneIndex) => {
if (nativeString.indexOf(skinTone) > 0) {
skin = skinToneIndex + 2
skinCode = skinCodes[skinToneIndex]
}
})
2019-03-23 21:15:47 +00:00
let emojiData
2019-03-23 21:14:52 +00:00
for (let id in data.emojis) {
let emoji = data.emojis[id]
let emojiUnified = emoji.unified
if (emoji.variations && emoji.variations.length) {
2019-03-23 21:15:47 +00:00
emojiUnified = emoji.variations.shift()
}
if (skin && emoji.skin_variations && emoji.skin_variations[skinCode]) {
2019-03-23 21:14:52 +00:00
emojiUnified = emoji.skin_variations[skinCode].unified
}
2019-03-23 21:14:52 +00:00
if (unifiedToNative(emojiUnified) === baseNativeString) emojiData = emoji
}
if (!emojiData) {
return null
}
emojiData.id = emojiData.short_names[0]
return getSanitizedData(emojiData, skin, set, data)
}
2017-09-17 08:54:22 +00:00
function uniq(arr) {
return arr.reduce((acc, item) => {
if (acc.indexOf(item) === -1) {
acc.push(item)
}
return acc
}, [])
}
2016-07-22 20:04:30 +00:00
2017-09-17 08:54:22 +00:00
function intersect(a, b) {
const uniqA = uniq(a)
const uniqB = uniq(b)
2016-07-22 20:04:30 +00:00
2018-03-27 18:51:26 +00:00
return uniqA.filter((item) => uniqB.indexOf(item) >= 0)
2016-07-22 20:04:30 +00:00
}
2016-10-27 03:22:59 +00:00
function deepMerge(a, b) {
var o = {}
for (let key in a) {
let originalValue = a[key],
2017-10-07 04:02:02 +00:00
value = originalValue
2016-10-27 03:22:59 +00:00
if (b.hasOwnProperty(key)) {
value = b[key]
}
if (typeof value === 'object') {
value = deepMerge(originalValue, value)
}
o[key] = value
}
return o
}
// https://github.com/sonicdoe/measure-scrollbar
function measureScrollbar() {
if (typeof document == 'undefined') return 0
const div = document.createElement('div')
div.style.width = '100px'
div.style.height = '100px'
div.style.overflow = 'scroll'
div.style.position = 'absolute'
div.style.top = '-9999px'
document.body.appendChild(div)
const scrollbarWidth = div.offsetWidth - div.clientWidth
document.body.removeChild(div)
return scrollbarWidth
}
// Use requestIdleCallback() if available, else fall back to setTimeout().
// Throttle so as not to run too frequently.
function throttleIdleTask(func) {
2019-03-13 15:54:40 +00:00
const doIdleTask =
typeof requestIdleCallback === 'function' ? requestIdleCallback : setTimeout
2019-03-13 15:54:40 +00:00
let running = false
return function throttled() {
2019-03-13 15:54:40 +00:00
if (running) {
return
}
2019-03-13 15:54:40 +00:00
running = true
doIdleTask(() => {
running = false
func()
})
}
}
2017-09-17 08:54:22 +00:00
export {
getData,
getEmojiDataFromNative,
2017-09-17 08:54:22 +00:00
getSanitizedData,
uniq,
intersect,
deepMerge,
unifiedToNative,
2017-10-07 04:02:02 +00:00
measureScrollbar,
throttleIdleTask,
2017-09-17 08:54:22 +00:00
}