UNPKG

@dialpad/dialtone

Version:

Dialpad's Dialtone design system monorepo

1 lines 10.4 kB
{"version":3,"file":"index.cjs","sources":["../../../common/emoji/index.js"],"sourcesContent":["import { emojiPattern } from 'regex-combined-emojis';\nimport emojiJsonLocal from 'emoji-toolkit/emoji_strategy.json' with { type: 'json' };\n\nexport const emojiRegex = new RegExp(emojiPattern, 'g');\nexport const emojiVersion = '9.0';\nexport const defaultEmojiAssetUrl = 'https://cdn.jsdelivr.net/joypixels/assets/' + emojiVersion + '/png/unicode/32/';\nexport let customEmojiAssetUrl = null;\n\n// Used for emoji 16px and smaller\nexport let emojiImageUrlSmall = defaultEmojiAssetUrl;\nexport let emojiFileExtensionSmall = '.png';\n\n// Used for emoji larger than 16px\nexport let emojiImageUrlLarge = defaultEmojiAssetUrl;\nexport let emojiFileExtensionLarge = '.png';\n\nexport const emojiJson = emojiJsonLocal;\n\nexport const emojiShortCodeRegex = /(^| |(?<=:))(:\\w+:)/g;\n\nexport function getEmojiData () {\n return emojiJson;\n}\n\nexport function setEmojiAssetUrlSmall (url, fileExtension = '.png') {\n if (!url.endsWith('/')) {\n url = url + '/';\n }\n emojiImageUrlSmall = url;\n emojiFileExtensionSmall = fileExtension;\n}\n\nexport function setEmojiAssetUrlLarge (url, fileExtension = '.svg') {\n if (!url.endsWith('/')) {\n url = url + '/';\n }\n emojiImageUrlLarge = url;\n emojiFileExtensionLarge = fileExtension;\n}\n\nexport function setCustomEmojiUrl (url) {\n customEmojiAssetUrl = url;\n}\n\nexport function setCustomEmojiJson (json) {\n validateCustomEmojiJson(json);\n}\n\n/**\n * Validate custom emoji json\n */\nexport function validateCustomEmojiJson (json) {\n const customEmojiProps = ['extension', 'custom'];\n const customEmojiRequiredProps = [\n 'name',\n 'category',\n 'shortname',\n 'extension',\n 'custom',\n ];\n\n /**\n * Update single emoji properties.\n * If the property exists in emojiData, it'll add the values if the property is an array, otherwise will overwrite.\n * If not exists, will add the property to the emojiData object.\n */\n const _updateNativeEmojiData = (emojiData, propName, propValue) => {\n if (emojiData[propName] === undefined) {\n if (!customEmojiProps.includes(propName)) {\n return;\n }\n\n // new property to add\n emojiData[propName] = propValue;\n } else {\n if (Array.isArray(emojiData[propName])) {\n emojiData[propName] = emojiData[propName].concat(propValue);\n } else {\n emojiData[propName] = propValue;\n }\n }\n };\n\n Object.entries(json).forEach((item) => {\n const [customEmojiKey, customEmojiValue] = item;\n\n if (customEmojiKey in emojiJson) {\n // custom emoji exists in emoji json which means to update some data in the native emoji\n const emojiData = emojiJson[customEmojiKey];\n\n for (const customEmojiPropertyName in customEmojiValue) {\n const customEmojiPropertyValue = customEmojiValue[customEmojiPropertyName];\n\n _updateNativeEmojiData(emojiData, customEmojiPropertyName, customEmojiPropertyValue);\n }\n } else {\n // new custom emoji\n const _validateRequiredProps = () =>\n customEmojiRequiredProps.every((val) => {\n return customEmojiValue[val] !== undefined;\n });\n\n if (_validateRequiredProps()) {\n emojiJson[customEmojiKey] = customEmojiValue;\n } else {\n console.error(\n 'The following custom emoji doesn\\'t contain the required properties:',\n customEmojiValue,\n );\n }\n }\n });\n}\n\n// recursively searches the emoji data object containing data for all emojis\n// and returns the object with the specified shortcode.\nexport function shortcodeToEmojiData (shortcode) {\n // eslint-disable-next-line complexity\n function f (o, key) {\n if (!o || typeof o !== 'object') {\n return;\n }\n if ('shortname' in o) {\n if (o.shortname === shortcode || o.shortname_alternates.includes(shortcode)) {\n o.key = key;\n reference = o;\n return true;\n }\n }\n Object.keys(o).some(function (k) {\n return f(o[k], k);\n });\n }\n\n let reference;\n f(getEmojiData(), null);\n return reference;\n}\n\n// Takes in an emoji unicode character(s) and converts it to an emoji string in the format the emoji data object expects\n// as a key. There can be multiple unicode characters in an emoji to denote the emoji itself, skin tone, gender\n// and such. Note that this function does NOT return variation selectors (fe0f) or zero width joiners (200d), as these\n// are not included as part of the key in the emoji.json.\n//\n// Example:\n// return value for smile emoji (no skin tone): 1f600\n// return value for left facing fist (light skin tone): 1f91b-1f3fb\nexport function unicodeToString (emoji) {\n let key = '';\n for (const codePoint of emoji) {\n const codepoint = codePoint.codePointAt(0).toString(16).padStart(4, '0');\n\n // skip 200d and fe0f as these are not included in emoji_strategy.json keys\n if (['200d', 'fe0f'].includes(codepoint)) continue;\n if (key !== '') { key = key + '-'; }\n key = key + codepoint;\n }\n return key;\n}\n\n// Takes in unicode in string form ex: '1f91b-1f3fb' and converts it to an actual unicode character.\nexport function stringToUnicode (str) {\n const uChars = str.split('-');\n let result = '';\n uChars.forEach((uChar) => {\n result = result + String.fromCodePoint(parseInt(uChar, 16));\n });\n return result;\n}\n\n// Takes in a code (which could be unicode or shortcode) and returns the emoji data for it.\nexport function codeToEmojiData (code) {\n code = code?.trim();\n if (code.startsWith(':') && code.endsWith(':')) {\n return shortcodeToEmojiData(code);\n } else {\n const unicodeString = unicodeToString(code);\n const result = emojiJson[unicodeString];\n if (result) result.key = unicodeString;\n return result;\n }\n}\n\n// Finds every shortcode in slot text\n// filters only the existing codes in emojiJson\n// removes duplicates.\n// @returns {string[]}\nexport function findShortCodes (textContent) {\n const shortcodes = (\n textContent.match(emojiShortCodeRegex) || []\n ).map(code => code.trim());\n return filterValidShortCodes(shortcodes);\n}\n\nexport function filterValidShortCodes (shortcodes) {\n const filtered = shortcodes ? shortcodes.filter(code => shortcodeToEmojiData(code)) : [];\n return new Set(filtered);\n}\n\n// Finds every emoji in slot text\n// removes duplicates\n// @returns {string[]}\nexport function findEmojis (textContent) {\n const matches = [...textContent.matchAll(emojiRegex)];\n const emojis = matches.length ? matches.map(match => match[0]) : [];\n return new Set(emojis);\n}\n"],"names":["emojiRegex","emojiPattern","emojiVersion","defaultEmojiAssetUrl","customEmojiAssetUrl","emojiImageUrlSmall","emojiFileExtensionSmall","emojiImageUrlLarge","emojiFileExtensionLarge","emojiJson","emojiJsonLocal","emojiShortCodeRegex","getEmojiData","setEmojiAssetUrlSmall","url","fileExtension","setEmojiAssetUrlLarge","setCustomEmojiUrl","setCustomEmojiJson","json","validateCustomEmojiJson","customEmojiProps","customEmojiRequiredProps","_updateNativeEmojiData","emojiData","propName","propValue","item","customEmojiKey","customEmojiValue","customEmojiPropertyName","customEmojiPropertyValue","val","shortcodeToEmojiData","shortcode","f","o","key","reference","k","unicodeToString","emoji","codePoint","codepoint","stringToUnicode","str","uChars","result","uChar","codeToEmojiData","code","unicodeString","findShortCodes","textContent","shortcodes","filterValidShortCodes","filtered","findEmojis","matches","emojis","match"],"mappings":"wKAGaA,EAAa,IAAI,OAAOC,EAAAA,aAAc,GAAG,EACzCC,EAAe,MACfC,EAAuB,6CAA+CD,EAAe,mBACvFE,QAAAA,oBAAsB,KAGtBC,QAAAA,mBAAqBF,EACrBG,QAAAA,wBAA0B,OAG1BC,QAAAA,mBAAqBJ,EACrBK,QAAAA,wBAA0B,OAEzB,MAACC,EAAYC,EAEZC,EAAsB,WAAA,uBAAA,GAAA,EAE5B,SAASC,GAAgB,CAC9B,OAAOH,CACT,CAEO,SAASI,EAAuBC,EAAKC,EAAgB,OAAQ,CAC7DD,EAAI,SAAS,GAAG,IACnBA,EAAMA,EAAM,KAEdT,QAAAA,mBAAqBS,EACrBR,QAAAA,wBAA0BS,CAC5B,CAEO,SAASC,EAAuBF,EAAKC,EAAgB,OAAQ,CAC7DD,EAAI,SAAS,GAAG,IACnBA,EAAMA,EAAM,KAEdP,QAAAA,mBAAqBO,EACrBN,QAAAA,wBAA0BO,CAC5B,CAEO,SAASE,EAAmBH,EAAK,CACtCV,QAAAA,oBAAsBU,CACxB,CAEO,SAASI,EAAoBC,EAAM,CACxCC,EAAwBD,CAAI,CAC9B,CAKO,SAASC,EAAyBD,EAAM,CAC7C,MAAME,EAAmB,CAAC,YAAa,QAAQ,EACzCC,EAA2B,CAC/B,OACA,WACA,YACA,YACA,QACJ,EAOQC,EAAyB,CAACC,EAAWC,EAAUC,IAAc,CACjE,GAAIF,EAAUC,CAAQ,IAAM,OAAW,CACrC,GAAI,CAACJ,EAAiB,SAASI,CAAQ,EACrC,OAIFD,EAAUC,CAAQ,EAAIC,CACxB,MACM,MAAM,QAAQF,EAAUC,CAAQ,CAAC,EACnCD,EAAUC,CAAQ,EAAID,EAAUC,CAAQ,EAAE,OAAOC,CAAS,EAE1DF,EAAUC,CAAQ,EAAIC,CAG5B,EAEA,OAAO,QAAQP,CAAI,EAAE,QAASQ,GAAS,CACrC,KAAM,CAACC,EAAgBC,CAAgB,EAAIF,EAE3C,GAAIC,KAAkBnB,EAAW,CAE/B,MAAMe,EAAYf,EAAUmB,CAAc,EAE1C,UAAWE,KAA2BD,EAAkB,CACtD,MAAME,EAA2BF,EAAiBC,CAAuB,EAEzEP,EAAuBC,EAAWM,EAAyBC,CAAwB,CACrF,CACF,MAGIT,EAAyB,MAAOU,GACvBH,EAAiBG,CAAG,IAAM,MAClC,EAGDvB,EAAUmB,CAAc,EAAIC,EAE5B,QAAQ,MACN,sEACAA,CACV,CAGE,CAAC,CACH,CAIO,SAASI,EAAsBC,EAAW,CAE/C,SAASC,EAAGC,EAAGC,EAAK,CAClB,GAAI,GAACD,GAAK,OAAOA,GAAM,UAGvB,IAAI,cAAeA,IACbA,EAAE,YAAcF,GAAaE,EAAE,qBAAqB,SAASF,CAAS,GACxE,OAAAE,EAAE,IAAMC,EACRC,EAAYF,EACL,GAGX,OAAO,KAAKA,CAAC,EAAE,KAAK,SAAUG,EAAG,CAC/B,OAAOJ,EAAEC,EAAEG,CAAC,EAAGA,CAAC,CAClB,CAAC,EACH,CAEA,IAAID,EACJ,OAAAH,EAAEvB,EAAY,EAAI,IAAI,EACf0B,CACT,CAUO,SAASE,EAAiBC,EAAO,CACtC,IAAIJ,EAAM,GACV,UAAWK,KAAaD,EAAO,CAC7B,MAAME,EAAYD,EAAU,YAAY,CAAC,EAAE,SAAS,EAAE,EAAE,SAAS,EAAG,GAAG,EAGnE,CAAC,OAAQ,MAAM,EAAE,SAASC,CAAS,IACnCN,IAAQ,KAAMA,EAAMA,EAAM,KAC9BA,EAAMA,EAAMM,EACd,CACA,OAAON,CACT,CAGO,SAASO,EAAiBC,EAAK,CACpC,MAAMC,EAASD,EAAI,MAAM,GAAG,EAC5B,IAAIE,EAAS,GACb,OAAAD,EAAO,QAASE,GAAU,CACxBD,EAASA,EAAS,OAAO,cAAc,SAASC,EAAO,EAAE,CAAC,CAC5D,CAAC,EACMD,CACT,CAGO,SAASE,EAAiBC,EAAM,CAErC,GADAA,EAAOA,GAAA,YAAAA,EAAM,OACTA,EAAK,WAAW,GAAG,GAAKA,EAAK,SAAS,GAAG,EAC3C,OAAOjB,EAAqBiB,CAAI,EAC3B,CACL,MAAMC,EAAgBX,EAAgBU,CAAI,EACpCH,EAAStC,EAAU0C,CAAa,EACtC,OAAIJ,IAAQA,EAAO,IAAMI,GAClBJ,CACT,CACF,CAMO,SAASK,EAAgBC,EAAa,CAC3C,MAAMC,GACJD,EAAY,MAAM1C,CAAmB,GAAK,CAAA,GAC1C,IAAIuC,GAAQA,EAAK,MAAM,EACzB,OAAOK,EAAsBD,CAAU,CACzC,CAEO,SAASC,EAAuBD,EAAY,CACjD,MAAME,EAAWF,EAAaA,EAAW,OAAOJ,GAAQjB,EAAqBiB,CAAI,CAAC,EAAI,CAAA,EACtF,OAAO,IAAI,IAAIM,CAAQ,CACzB,CAKO,SAASC,EAAYJ,EAAa,CACvC,MAAMK,EAAU,CAAC,GAAGL,EAAY,SAASrD,CAAU,CAAC,EAC9C2D,EAASD,EAAQ,OAASA,EAAQ,IAAIE,GAASA,EAAM,CAAC,CAAC,EAAI,CAAA,EACjE,OAAO,IAAI,IAAID,CAAM,CACvB"}