diff --git a/package.json b/package.json index 607a011f..557cd542 100644 --- a/package.json +++ b/package.json @@ -69,6 +69,7 @@ "format-message-interpret": "^6.2.3", "format-message-parse": "^6.2.3", "glob": "^7.1.6", + "is-emoji-supported": "^0.0.5", "li": "^1.3.0", "localstorage-memory": "^1.0.3", "lodash-es": "4.17.15", diff --git a/src/routes/_utils/testColorEmojiSupported.js b/src/routes/_utils/testColorEmojiSupported.js deleted file mode 100644 index 1ef66fef..00000000 --- a/src/routes/_utils/testColorEmojiSupported.js +++ /dev/null @@ -1,39 +0,0 @@ -// Copied from -// https://github.com/nolanlawson/emoji-picker-element/blob/04f490a/src/picker/utils/testColorEmojiSupported.js - -import { FONT_FAMILY } from '../_static/fonts' - -const getTextFeature = (text, color) => { - try { - const canvas = document.createElement('canvas') - canvas.width = canvas.height = 1 - - const ctx = canvas.getContext('2d') - ctx.textBaseline = 'top' - ctx.font = `100px ${FONT_FAMILY}` - ctx.fillStyle = color - ctx.scale(0.01, 0.01) - ctx.fillText(text, 0, 0) - - return ctx.getImageData(0, 0, 1, 1).data - } catch (e) { /* ignore, return undefined */ } -} - -const compareFeatures = (feature1, feature2) => { - const feature1Str = [...feature1].join(',') - const feature2Str = [...feature2].join(',') - return feature1Str === feature2Str && feature1Str !== '0,0,0,0' -} - -export function testColorEmojiSupported (text) { - // Render white and black and then compare them to each other and ensure they're the same - // color, and neither one is black. This shows that the emoji was rendered in color. - const feature1 = getTextFeature(text, '#000') - const feature2 = getTextFeature(text, '#fff') - - const supported = feature1 && feature2 && compareFeatures(feature1, feature2) - if (!supported) { - console.log('Filtered unsupported emoji via color test', text) - } - return supported -} diff --git a/src/routes/_utils/testEmojiRenderedAtCorrectSize.js b/src/routes/_utils/testEmojiRenderedAtCorrectSize.js deleted file mode 100644 index e04e51e1..00000000 --- a/src/routes/_utils/testEmojiRenderedAtCorrectSize.js +++ /dev/null @@ -1,43 +0,0 @@ -// Return true if the unicode is rendered as a double character, e.g. -// "black cat" or "polar bar" or "person with red hair" or other emoji -// that look like double or triple emoji if the unicode is not rendered properly - -const BASELINE_EMOJI = '😀' - -let baselineWidth - -export function testEmojiRenderedAtCorrectSize (unicode) { - if (!unicode.includes('\u200d')) { // ZWJ - return true // benefit of the doubt - } - - let emojiTestDiv = document.getElementById('emoji-test') - if (!emojiTestDiv) { - emojiTestDiv = document.createElement('div') - emojiTestDiv.id = 'emoji-test' - emojiTestDiv.ariaHidden = true - Object.assign(emojiTestDiv.style, { - position: 'absolute', - opacity: '0', - 'pointer-events': 'none', - 'font-family': 'PinaforeEmoji', - 'font-size': '14px', - contain: 'content' - }) - document.body.appendChild(emojiTestDiv) - } - emojiTestDiv.textContent = unicode - const { width } = emojiTestDiv.getBoundingClientRect() - if (typeof baselineWidth === 'undefined') { - emojiTestDiv.textContent = BASELINE_EMOJI - baselineWidth = emojiTestDiv.getBoundingClientRect().width - } - - // WebKit has some imprecision here, so round it - const emojiSupported = width.toFixed(2) === baselineWidth.toFixed(2) - if (!emojiSupported) { - console.log('Filtered unsupported emoji via size test', unicode, 'width', width, 'baselineWidth', baselineWidth) - } - - return emojiSupported -} diff --git a/src/routes/_utils/testEmojiSupported.js b/src/routes/_utils/testEmojiSupported.js index dc3ed35f..3873191f 100644 --- a/src/routes/_utils/testEmojiSupported.js +++ b/src/routes/_utils/testEmojiSupported.js @@ -1,17 +1,8 @@ -import { testColorEmojiSupported } from './testColorEmojiSupported' -import { testEmojiRenderedAtCorrectSize } from './testEmojiRenderedAtCorrectSize' +import { isEmojiSupported, setCacheHandler } from 'is-emoji-supported' import { QuickLRU } from '../_thirdparty/quick-lru/quick-lru' // avoid recomputing emoji support over and over again -const emojiSupportCache = new QuickLRU({ - maxSize: 500 -}) +// use our own LRU since the built-in one grows forever, which is a small memory leak, but still +setCacheHandler(new QuickLRU({ maxSize: 500 })) -export function testEmojiSupported (unicode) { - let supported = emojiSupportCache.get(unicode) - if (typeof supported !== 'boolean') { - supported = !!(testColorEmojiSupported(unicode) && testEmojiRenderedAtCorrectSize(unicode)) - emojiSupportCache.set(unicode, supported) - } - return supported -} +export const testEmojiSupported = isEmojiSupported diff --git a/yarn.lock b/yarn.lock index e131b994..eac8a325 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4325,6 +4325,11 @@ is-electron@^2.2.0: resolved "https://registry.yarnpkg.com/is-electron/-/is-electron-2.2.0.tgz#8943084f09e8b731b3a7a0298a7b5d56f6b7eef0" integrity sha512-SpMppC2XR3YdxSzczXReBjqs2zGscWQpBIKqwXYBFic0ERaxNVgwLCHwOLZeESfdJQjX0RDvrJ1lBXX2ij+G1Q== +is-emoji-supported@^0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/is-emoji-supported/-/is-emoji-supported-0.0.5.tgz#f22301b22c63d6322935e829f39dfa59d03a7fe2" + integrity sha512-WOlXUhDDHxYqcSmFZis+xWhhqXiK2SU0iYiqmth5Ip0FHLZQAt9rKL5ahnilE8/86WH8tZ3bmNNNC+bTzamqlw== + is-es2016-keyword@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-es2016-keyword/-/is-es2016-keyword-1.0.0.tgz#f6e54e110c5e4f8d265e69d2ed0eaf8cf5f47718"