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'
|
|
|
|
|
|
|
|
const _JSON = JSON
|
2016-07-19 16:27:24 +00:00
|
|
|
|
2016-11-01 15:10:16 +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,
|
|
|
|
imageUrl,
|
|
|
|
} = emoji,
|
|
|
|
id = emoji.id || short_names[0],
|
|
|
|
colons = `:${id}:`
|
2016-07-19 16:27:24 +00:00
|
|
|
|
2017-05-26 08:09:42 +00:00
|
|
|
if (custom) {
|
|
|
|
return {
|
|
|
|
id,
|
|
|
|
name,
|
2019-03-18 20:10:40 +00:00
|
|
|
short_names,
|
2017-05-26 08:09:42 +00:00
|
|
|
colons,
|
|
|
|
emoticons,
|
|
|
|
custom,
|
2017-10-07 04:02:02 +00:00
|
|
|
imageUrl,
|
2017-05-26 08:09:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-19 16:27:24 +00:00
|
|
|
if (skin_tone) {
|
|
|
|
colons += `:skin-tone-${skin_tone}:`
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
id,
|
|
|
|
name,
|
|
|
|
colons,
|
|
|
|
emoticons,
|
2017-03-17 13:02:53 +00:00
|
|
|
unified: unified.toLowerCase(),
|
2016-12-13 02:33:06 +00:00
|
|
|
skin: skin_tone || (skin_variations ? 1 : null),
|
2016-07-19 16:27:24 +00:00
|
|
|
native: unifiedToNative(unified),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function getSanitizedData() {
|
|
|
|
return sanitize(getData(...arguments))
|
|
|
|
}
|
|
|
|
|
2018-03-28 21:30:47 +00:00
|
|
|
function getData(emoji, skin, set, data) {
|
2016-10-18 23:00:51 +00:00
|
|
|
var emojiData = {}
|
2016-07-19 16:27:24 +00:00
|
|
|
|
|
|
|
if (typeof emoji == 'string') {
|
2016-11-01 15:10:16 +00:00
|
|
|
let matches = emoji.match(COLONS_REGEX)
|
|
|
|
|
|
|
|
if (matches) {
|
|
|
|
emoji = matches[1]
|
|
|
|
|
|
|
|
if (matches[2]) {
|
2018-03-28 21:30:47 +00:00
|
|
|
skin = parseInt(matches[2], 10)
|
2016-11-01 15:10:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-26 20:31:16 +00:00
|
|
|
if (data.aliases.hasOwnProperty(emoji)) {
|
|
|
|
emoji = data.aliases[emoji]
|
2016-10-13 20:19:46 +00:00
|
|
|
}
|
|
|
|
|
2016-10-18 23:00:51 +00:00
|
|
|
if (data.emojis.hasOwnProperty(emoji)) {
|
|
|
|
emojiData = data.emojis[emoji]
|
2017-10-09 18:23:28 +00:00
|
|
|
} else {
|
|
|
|
return null
|
2016-10-13 00:26:10 +00:00
|
|
|
}
|
2016-07-19 16:27:24 +00:00
|
|
|
} else if (emoji.id) {
|
2018-04-26 20:31:16 +00:00
|
|
|
if (data.aliases.hasOwnProperty(emoji.id)) {
|
|
|
|
emoji.id = data.aliases[emoji.id]
|
2016-10-13 20:19:46 +00:00
|
|
|
}
|
|
|
|
|
2016-10-18 23:00:51 +00:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2017-09-30 14:37:13 +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 = [])
|
|
|
|
|
2019-03-23 15:17:37 +00:00
|
|
|
if (emojiData.skin_variations && skin > 1) {
|
2017-09-17 08:54:22 +00:00
|
|
|
emojiData = JSON.parse(_JSON.stringify(emojiData))
|
2016-07-19 16:27:24 +00:00
|
|
|
|
|
|
|
var skinKey = SKINS[skin - 1],
|
2017-10-07 04:02:02 +00:00
|
|
|
variationData = emojiData.skin_variations[skinKey]
|
2016-07-19 16:27:24 +00:00
|
|
|
|
2017-02-17 17:50:20 +00:00
|
|
|
if (!variationData.variations && emojiData.variations) {
|
|
|
|
delete emojiData.variations
|
|
|
|
}
|
|
|
|
|
2018-04-30 00:55:13 +00:00
|
|
|
if (
|
2019-03-23 16:18:50 +00:00
|
|
|
(set && variationData[`has_img_${set}`] == undefined) ||
|
|
|
|
variationData[`has_img_${set}`] ||
|
|
|
|
!set
|
2018-04-30 00:55:13 +00:00
|
|
|
) {
|
2016-07-19 16:27:24 +00:00
|
|
|
emojiData.skin_tone = skin
|
2019-03-23 15:20:21 +00:00
|
|
|
|
2016-07-19 16:27:24 +00:00
|
|
|
for (let k in variationData) {
|
|
|
|
let v = variationData[k]
|
|
|
|
emojiData[k] = v
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-17 17:50:20 +00:00
|
|
|
if (emojiData.variations && emojiData.variations.length) {
|
2017-09-17 08:54:22 +00:00
|
|
|
emojiData = JSON.parse(_JSON.stringify(emojiData))
|
2017-02-17 17:50:20 +00:00
|
|
|
emojiData.unified = emojiData.variations.shift()
|
|
|
|
}
|
|
|
|
|
2016-07-19 16:27:24 +00:00
|
|
|
return emojiData
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2017-09-28 23:57:20 +00:00
|
|
|
// https://github.com/sonicdoe/measure-scrollbar
|
|
|
|
function measureScrollbar() {
|
2017-11-02 23:50:19 +00:00
|
|
|
if (typeof document == 'undefined') return 0
|
2017-09-28 23:57:20 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2019-03-10 16:40:59 +00:00
|
|
|
// 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 =
|
2019-03-10 16:40:59 +00:00
|
|
|
typeof requestIdleCallback === 'function' ? requestIdleCallback : setTimeout
|
|
|
|
|
2019-03-13 15:54:40 +00:00
|
|
|
let running = false
|
2019-03-10 16:40:59 +00:00
|
|
|
|
|
|
|
return function throttled() {
|
2019-03-13 15:54:40 +00:00
|
|
|
if (running) {
|
|
|
|
return
|
2019-03-10 16:40:59 +00:00
|
|
|
}
|
2019-03-13 15:54:40 +00:00
|
|
|
running = true
|
|
|
|
doIdleTask(() => {
|
|
|
|
running = false
|
|
|
|
func()
|
|
|
|
})
|
2019-03-10 16:40:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-17 08:54:22 +00:00
|
|
|
export {
|
|
|
|
getData,
|
|
|
|
getSanitizedData,
|
|
|
|
uniq,
|
|
|
|
intersect,
|
|
|
|
deepMerge,
|
2017-09-28 23:57:20 +00:00
|
|
|
unifiedToNative,
|
2017-10-07 04:02:02 +00:00
|
|
|
measureScrollbar,
|
2019-03-10 16:40:59 +00:00
|
|
|
throttleIdleTask,
|
2017-09-17 08:54:22 +00:00
|
|
|
}
|