parent
c8220be1b4
commit
54d76d6b56
@ -0,0 +1,39 @@
|
|||||||
|
import {
|
||||||
|
removeVS16s,
|
||||||
|
toCodePoints,
|
||||||
|
} from '../emoji';
|
||||||
|
|
||||||
|
const ASCII_HEART = '❤'; // '\u2764\uFE0F'
|
||||||
|
const RED_HEART_RGI = '❤️'; // '\u2764'
|
||||||
|
const JOY = '😂';
|
||||||
|
|
||||||
|
describe('removeVS16s()', () => {
|
||||||
|
it('removes Variation Selector-16 characters from emoji', () => {
|
||||||
|
// Sanity check
|
||||||
|
expect(ASCII_HEART).not.toBe(RED_HEART_RGI);
|
||||||
|
|
||||||
|
// It normalizes an emoji with VS16s
|
||||||
|
expect(removeVS16s(RED_HEART_RGI)).toBe(ASCII_HEART);
|
||||||
|
|
||||||
|
// Leaves a regular emoji alone
|
||||||
|
expect(removeVS16s(JOY)).toBe(JOY);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('toCodePoints()', () => {
|
||||||
|
it('converts a plain emoji', () => {
|
||||||
|
expect(toCodePoints('😂')).toEqual(['1f602']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('converts a VS16 emoji', () => {
|
||||||
|
expect(toCodePoints(RED_HEART_RGI)).toEqual(['2764', 'fe0f']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('converts an ASCII character', () => {
|
||||||
|
expect(toCodePoints(ASCII_HEART)).toEqual(['2764']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('converts a sequence emoji', () => {
|
||||||
|
expect(toCodePoints('🇺🇸')).toEqual(['1f1fa', '1f1f8']);
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,35 @@
|
|||||||
|
// Taken from twemoji-parser
|
||||||
|
// https://github.com/twitter/twemoji-parser/blob/a97ef3994e4b88316812926844d51c296e889f76/src/index.js
|
||||||
|
|
||||||
|
/** Remove Variation Selector-16 characters from emoji */
|
||||||
|
// https://emojipedia.org/variation-selector-16/
|
||||||
|
const removeVS16s = (rawEmoji: string): string => {
|
||||||
|
const vs16RegExp = /\uFE0F/g;
|
||||||
|
const zeroWidthJoiner = String.fromCharCode(0x200d);
|
||||||
|
return rawEmoji.indexOf(zeroWidthJoiner) < 0 ? rawEmoji.replace(vs16RegExp, '') : rawEmoji;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Convert emoji into an array of Unicode codepoints */
|
||||||
|
const toCodePoints = (unicodeSurrogates: string): string[] => {
|
||||||
|
const points = [];
|
||||||
|
let char = 0;
|
||||||
|
let previous = 0;
|
||||||
|
let i = 0;
|
||||||
|
while (i < unicodeSurrogates.length) {
|
||||||
|
char = unicodeSurrogates.charCodeAt(i++);
|
||||||
|
if (previous) {
|
||||||
|
points.push((0x10000 + ((previous - 0xd800) << 10) + (char - 0xdc00)).toString(16));
|
||||||
|
previous = 0;
|
||||||
|
} else if (char > 0xd800 && char <= 0xdbff) {
|
||||||
|
previous = char;
|
||||||
|
} else {
|
||||||
|
points.push(char.toString(16));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return points;
|
||||||
|
};
|
||||||
|
|
||||||
|
export {
|
||||||
|
removeVS16s,
|
||||||
|
toCodePoints,
|
||||||
|
};
|
Loading…
Reference in new issue