Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
xml('annotation').each((i, rawRow) => {
const row = xml(rawRow);
// Variation selectors are not present in the locale files
// So lets just strip unnecessary codepoints
const hexcode = stripHexcode(fromUnicodeToHexcode(row.attr('cp')));
if (!data[hexcode]) {
data[hexcode] = {
annotation: '',
tags: new Set(),
};
}
if (row.attr('type') === 'tts') {
data[hexcode].annotation = row.text().trim();
} else {
data[hexcode].tags = new Set(
row
.text()
.trim()
.split('|')
xml('annotation').each((i, rawRow) => {
const row = xml(rawRow);
// Variation selectors are not present in the locale files
// So lets just strip unnecessary codepoints
const hexcode = stripHexcode(fromUnicodeToHexcode(row.attr('cp')!));
if (!data[hexcode]) {
data[hexcode] = {
annotation: '',
tags: [],
};
}
if (row.attr('type') === 'tts') {
data[hexcode].annotation = row.text().trim();
} else {
data[hexcode].tags = row
.text()
.trim()
.split('|')
.map(tag => tag.trim().toLowerCase());
Object.keys(sequences).forEach(fullHexcode => {
const hexcode = stripHexcode(fullHexcode);
const emoji = sequences[fullHexcode];
const tags: string[] = extractField(hexcode, 'tags') || [];
let annotation: string = extractField(hexcode, 'annotation') || '';
// Use the localized territory name
if (hasProperty(emoji.property, ['Emoji_Flag_Sequence'])) {
const countryCode = fullHexcode
.split('-')
.map((hex: string) => REGIONAL_INDICATORS[hex])
.join('');
if (!annotation) {
annotation = localization.territories[countryCode];
}
tags.push(countryCode);
if ('tone' in baseEmoji && baseEmoji.tone !== null) {
emoji.tone = baseEmoji.tone;
}
// Presentation variations
if ('variations' in baseEmoji) {
emoji.emoji = toUnicode(baseEmoji.variations!.emoji);
emoji.text = toUnicode(baseEmoji.variations!.text);
}
if ('emoticon' in baseEmoji) {
emoji.emoticon = baseEmoji.emoticon;
}
// Annotations
const annotation = annotations[stripHexcode(emoji.hexcode)]; // No ZWJ, selectors
if (annotation) {
if (annotation.annotation) {
emoji.annotation = annotation.annotation;
}
if (annotation.tags && annotation.tags.length > 0) {
emoji.tags = annotation.tags;
// Sort the tags for easier diffs
emoji.tags.sort();
// Some locales duplicate the annotation in the tag list
if (emoji.tags.length > 1) {
emoji.tags = emoji.tags.filter((tag: string) => tag !== emoji.annotation);
}
emoji.skins = Object.values(baseEmoji.modifications!).map(mod => {
const skin = createEmoji(mod, versions, annotations);
skin.annotation = (annotations[stripHexcode(skin.hexcode)] || {}).annotation || '';
skin.shortcodes = (emoji.shortcodes || []).map(
code => `${code}_tone${Array.isArray(skin.tone) ? skin.tone.join('-') : skin.tone}`,
);
// Remove any tags
delete skin.tags;
return skin;
});
}
// We must use a variable here, otherwise webpack attempts to include it in the bundle.
// If that happens and the module does not exist, it will throw a warning.
// https://github.com/webpack/webpack/issues/8826
// https://github.com/webpack/webpack/issues/4175
const requireFunc =
// eslint-disable-next-line @typescript-eslint/camelcase
typeof __webpack_require__ === 'function' ? __non_webpack_require__ : require;
testData = requireFunc('emojibase-test-utils/test-data.json');
} catch {
testData = [];
}
request = Promise.resolve(testData);
} else {
request = fetchFromCDN(`${locale}/${set}.json`, version);
}
promises.set(
key,
request.then(response => {
const instance = EmojiDataManager.getInstance(locale);
instance.parseEmojiData(response);
return instance.getData();
}),
);
return promises.get(key)!;
}
// Abort as we've already loaded data
if (loaded.has(key) || emojis.length > 0) {
this.setEmojis(emojis);
return Promise.resolve();
}
// Or hook into the promise if we're loading
if (promise.has(key)) {
return promise.get(key)!.then(() => {
this.setEmojis();
});
}
// Otherwise, start loading emoji data from the CDN
const request = fetchFromCDN(`${locale}/${set}.json`, version)
.then(response => {
loaded.add(key);
this.getDataInstance().parseEmojiData(response);
this.setEmojis();
})
.catch(error => {
loaded.add(key);
if (throwErrors) {
throw error;
}
});
promise.set(key, request);
const mapHexcode = (hexcode: string) => {
if (map[hexcode]) {
// An emoji may belong to multiple properties,
// so keep a unique list of all applicable.
map[hexcode].property = Array.from(new Set([...map[hexcode].property, ...emoji.property]));
} else {
map[hexcode] = {
...emoji,
hexcode,
};
}
};
// A sequence of emoji
if (rawHexcode.includes('..')) {
const [lowCodepoint, highCodepoint] = fromHexcodeToCodepoint(rawHexcode, '..');
for (let codepoint = lowCodepoint; codepoint <= highCodepoint; codepoint += 1) {
mapHexcode(
codepoint
.toString(16)
.padStart(4, '0')
.toUpperCase(),
);
}
// A single emoji
} else {
// v1.0 had a different structure
if (version === '1.0') {
emoji.type = property === 'emoji' ? EMOJI : TEXT;
emoji.property = [
emoji.primary_shortcode = emoji.canonical_shortcodes[0];
// Support all shortcodes
emoji.canonical_shortcodes.forEach(shortcode => {
this.SHORTCODE_TO_HEXCODE[shortcode] = hexcode;
});
// Support all emoticons
if (emoticon) {
generateEmoticonPermutations(emoticon, EMOTICON_OPTIONS[emoticon]).forEach(emo => {
this.EMOTICON_TO_HEXCODE[emo] = hexcode;
});
}
// Support all presentations (even no variation selectors)
this.UNICODE_TO_HEXCODE[fromCodepointToUnicode(fromHexcodeToCodepoint(hexcode))] = hexcode;
if (emoji.emoji) {
this.UNICODE_TO_HEXCODE[emoji.emoji] = hexcode;
}
if (emoji.text) {
this.UNICODE_TO_HEXCODE[emoji.text] = hexcode;
}
// Map each emoji
this.EMOJIS[hexcode] = emoji;
// Apply same logic to all variations
if (baseEmoji.skins) {
emoji.skins = baseEmoji.skins.map(skinEmoji => this.packageEmoji(skinEmoji));
}
}
// Canonicalize the shortcodes for easy reuse
emoji.canonical_shortcodes = shortcodes.map(code => `:${code}:`);
// eslint-disable-next-line prefer-destructuring
emoji.primary_shortcode = emoji.canonical_shortcodes[0];
// Support all shortcodes
emoji.canonical_shortcodes.forEach(shortcode => {
this.SHORTCODE_TO_HEXCODE[shortcode] = hexcode;
});
// Support all emoticons
if (emoticon) {
generateEmoticonPermutations(emoticon, EMOTICON_OPTIONS[emoticon]).forEach(emo => {
this.EMOTICON_TO_HEXCODE[emo] = hexcode;
});
}
// Support all presentations (even no variation selectors)
this.UNICODE_TO_HEXCODE[fromCodepointToUnicode(fromHexcodeToCodepoint(hexcode))] = hexcode;
if (emoji.emoji) {
this.UNICODE_TO_HEXCODE[emoji.emoji] = hexcode;
}
if (emoji.text) {
this.UNICODE_TO_HEXCODE[emoji.text] = hexcode;
}
// Map each emoji