Commit 9e5db3e2 authored by Eric Eastwood's avatar Eric Eastwood

Add rainbow_flag to emoji support map

Tested on the following platforms that split the emoji into separate
characters currently.
 - Windows 10 FCU
    - Chrome 62.0.3202.89
    - Firefox 57.0b14
    - MS Edge 41.16299.15.0
 - macOS 10.12.6
    - Chrome 63.0.3239.40
    - Safari 11.0.1 (12604.3.5.1.1)
    - Firefox 57.0
 - Ubuntu 16.04
    - Chromium 62.0.3202.75
    - Firefox 56.0
parent b5b35865
...@@ -7,6 +7,17 @@ function isFlagEmoji(emojiUnicode) { ...@@ -7,6 +7,17 @@ function isFlagEmoji(emojiUnicode) {
return emojiUnicode.length === 4 && cp >= flagACodePoint && cp <= flagZCodePoint; return emojiUnicode.length === 4 && cp >= flagACodePoint && cp <= flagZCodePoint;
} }
// Tested on mac OS 10.12.6 and Windows 10 FCU, it renders as two separate characters
const baseFlagCodePoint = 127987; // parseInt('1F3F3', 16)
const rainbowCodePoint = 127752; // parseInt('1F308', 16)
function isRainbowFlagEmoji(emojiUnicode) {
const characters = Array.from(emojiUnicode);
// Length 4 because flags are made of 2 characters which are surrogate pairs
return emojiUnicode.length === 4 &&
characters[0].codePointAt(0) === baseFlagCodePoint &&
characters[1].codePointAt(0) === rainbowCodePoint;
}
// Chrome <57 renders keycaps oddly // Chrome <57 renders keycaps oddly
// See https://bugs.chromium.org/p/chromium/issues/detail?id=632294 // See https://bugs.chromium.org/p/chromium/issues/detail?id=632294
// Same issue on Windows also fixed in Chrome 57, http://i.imgur.com/rQF7woO.png // Same issue on Windows also fixed in Chrome 57, http://i.imgur.com/rQF7woO.png
...@@ -57,9 +68,11 @@ function isPersonZwjEmoji(emojiUnicode) { ...@@ -57,9 +68,11 @@ function isPersonZwjEmoji(emojiUnicode) {
// in `isEmojiUnicodeSupported` logic // in `isEmojiUnicodeSupported` logic
function checkFlagEmojiSupport(unicodeSupportMap, emojiUnicode) { function checkFlagEmojiSupport(unicodeSupportMap, emojiUnicode) {
const isFlagResult = isFlagEmoji(emojiUnicode); const isFlagResult = isFlagEmoji(emojiUnicode);
const isRainbowFlagResult = isRainbowFlagEmoji(emojiUnicode);
return ( return (
(unicodeSupportMap.flag && isFlagResult) || (unicodeSupportMap.flag && isFlagResult) ||
!isFlagResult (unicodeSupportMap.rainbowFlag && isRainbowFlagResult) ||
(!isFlagResult && !isRainbowFlagResult)
); );
} }
...@@ -113,6 +126,7 @@ function isEmojiUnicodeSupported(unicodeSupportMap = {}, emojiUnicode, unicodeVe ...@@ -113,6 +126,7 @@ function isEmojiUnicodeSupported(unicodeSupportMap = {}, emojiUnicode, unicodeVe
export { export {
isEmojiUnicodeSupported as default, isEmojiUnicodeSupported as default,
isFlagEmoji, isFlagEmoji,
isRainbowFlagEmoji,
isKeycapEmoji, isKeycapEmoji,
isSkinToneComboEmoji, isSkinToneComboEmoji,
isHorceRacingSkinToneComboEmoji, isHorceRacingSkinToneComboEmoji,
......
import AccessorUtilities from '../../lib/utils/accessor'; import AccessorUtilities from '../../lib/utils/accessor';
const GL_EMOJI_VERSION = '0.2.0';
const unicodeSupportTestMap = { const unicodeSupportTestMap = {
// man, student (emojione does not have any of these yet), http://emojipedia.org/emoji-zwj-sequences/ // man, student (emojione does not have any of these yet), http://emojipedia.org/emoji-zwj-sequences/
// occupationZwj: '\u{1F468}\u{200D}\u{1F393}', // occupationZwj: '\u{1F468}\u{200D}\u{1F393}',
...@@ -13,6 +15,7 @@ const unicodeSupportTestMap = { ...@@ -13,6 +15,7 @@ const unicodeSupportTestMap = {
horseRacing: '\u{1F3C7}\u{1F3FF}', horseRacing: '\u{1F3C7}\u{1F3FF}',
// US flag, http://emojipedia.org/flags/ // US flag, http://emojipedia.org/flags/
flag: '\u{1F1FA}\u{1F1F8}', flag: '\u{1F1FA}\u{1F1F8}',
rainbowFlag: '\u{1F3F3}\u{1F308}',
// http://emojipedia.org/modifiers/ // http://emojipedia.org/modifiers/
skinToneModifier: [ skinToneModifier: [
// spy_tone5 // spy_tone5
...@@ -141,23 +144,31 @@ function generateUnicodeSupportMap(testMap) { ...@@ -141,23 +144,31 @@ function generateUnicodeSupportMap(testMap) {
} }
export default function getUnicodeSupportMap() { export default function getUnicodeSupportMap() {
let unicodeSupportMap;
let userAgentFromCache;
const isLocalStorageAvailable = AccessorUtilities.isLocalStorageAccessSafe(); const isLocalStorageAvailable = AccessorUtilities.isLocalStorageAccessSafe();
if (isLocalStorageAvailable) userAgentFromCache = window.localStorage.getItem('gl-emoji-user-agent'); let glEmojiVersionFromCache;
let userAgentFromCache;
if (isLocalStorageAvailable) {
glEmojiVersionFromCache = window.localStorage.getItem('gl-emoji-version');
userAgentFromCache = window.localStorage.getItem('gl-emoji-user-agent');
}
let unicodeSupportMap;
try { try {
unicodeSupportMap = JSON.parse(window.localStorage.getItem('gl-emoji-unicode-support-map')); unicodeSupportMap = JSON.parse(window.localStorage.getItem('gl-emoji-unicode-support-map'));
} catch (err) { } catch (err) {
// swallow // swallow
} }
if (!unicodeSupportMap || userAgentFromCache !== navigator.userAgent) { if (
!unicodeSupportMap ||
glEmojiVersionFromCache !== GL_EMOJI_VERSION ||
userAgentFromCache !== navigator.userAgent
) {
unicodeSupportMap = generateUnicodeSupportMap(unicodeSupportTestMap); unicodeSupportMap = generateUnicodeSupportMap(unicodeSupportTestMap);
if (isLocalStorageAvailable) { if (isLocalStorageAvailable) {
window.localStorage.setItem('gl-emoji-version', GL_EMOJI_VERSION);
window.localStorage.setItem('gl-emoji-user-agent', navigator.userAgent); window.localStorage.setItem('gl-emoji-user-agent', navigator.userAgent);
window.localStorage.setItem('gl-emoji-unicode-support-map', JSON.stringify(unicodeSupportMap)); window.localStorage.setItem('gl-emoji-unicode-support-map', JSON.stringify(unicodeSupportMap));
} }
......
...@@ -21,13 +21,18 @@ describe('Unicode Support Map', () => { ...@@ -21,13 +21,18 @@ describe('Unicode Support Map', () => {
}); });
it('should call .getItem and .setItem', () => { it('should call .getItem and .setItem', () => {
const allArgs = window.localStorage.setItem.calls.allArgs(); const getArgs = window.localStorage.getItem.calls.allArgs();
const setArgs = window.localStorage.setItem.calls.allArgs();
expect(window.localStorage.getItem).toHaveBeenCalledWith('gl-emoji-user-agent');
expect(allArgs[0][0]).toBe('gl-emoji-user-agent'); expect(getArgs[0][0]).toBe('gl-emoji-version');
expect(allArgs[0][1]).toBe(navigator.userAgent); expect(getArgs[1][0]).toBe('gl-emoji-user-agent');
expect(allArgs[1][0]).toBe('gl-emoji-unicode-support-map');
expect(allArgs[1][1]).toBe(stringSupportMap); expect(setArgs[0][0]).toBe('gl-emoji-version');
expect(setArgs[0][1]).toBe('0.2.0');
expect(setArgs[1][0]).toBe('gl-emoji-user-agent');
expect(setArgs[1][1]).toBe(navigator.userAgent);
expect(setArgs[2][0]).toBe('gl-emoji-unicode-support-map');
expect(setArgs[2][1]).toBe(stringSupportMap);
}); });
}); });
......
import { glEmojiTag } from '~/emoji'; import { glEmojiTag } from '~/emoji';
import isEmojiUnicodeSupported, { import isEmojiUnicodeSupported, {
isFlagEmoji, isFlagEmoji,
isRainbowFlagEmoji,
isKeycapEmoji, isKeycapEmoji,
isSkinToneComboEmoji, isSkinToneComboEmoji,
isHorceRacingSkinToneComboEmoji, isHorceRacingSkinToneComboEmoji,
...@@ -217,6 +218,24 @@ describe('gl_emoji', () => { ...@@ -217,6 +218,24 @@ describe('gl_emoji', () => {
}); });
}); });
describe('isRainbowFlagEmoji', () => {
it('should gracefully handle empty string', () => {
expect(isRainbowFlagEmoji('')).toBeFalsy();
});
it('should detect rainbow_flag', () => {
expect(isRainbowFlagEmoji('🏳🌈')).toBeTruthy();
});
it('should not detect flag_white on its\' own', () => {
expect(isRainbowFlagEmoji('🏳')).toBeFalsy();
});
it('should not detect rainbow on its\' own', () => {
expect(isRainbowFlagEmoji('🌈')).toBeFalsy();
});
it('should not detect flag_white with something else', () => {
expect(isRainbowFlagEmoji('🏳🔵')).toBeFalsy();
});
});
describe('isKeycapEmoji', () => { describe('isKeycapEmoji', () => {
it('should gracefully handle empty string', () => { it('should gracefully handle empty string', () => {
expect(isKeycapEmoji('')).toBeFalsy(); expect(isKeycapEmoji('')).toBeFalsy();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment