From 02406925d7672396430060822c114391c685c1d6 Mon Sep 17 00:00:00 2001 From: Hampus Date: Mon, 24 Aug 2026 12:31:51 +0200 Subject: [PATCH] refactor(app): collapse the duplicate emoji shortcode matchers into one (#1854) --- fluxer_app/scripts/GenerateEmojiSprites.ts | 14 +-- .../CustomStatusDisplay.tsx | 2 +- .../emoji_picker/EmojiPickerInspector.tsx | 10 +- .../components/emoji_picker/EmojiRenderer.tsx | 10 +- .../bottomsheets/EmojiInfoBottomSheet.tsx | 2 +- fluxer_app/src/features/emoji/state/Emoji.ts | 8 +- .../src/features/emoji/types/EmojiTypes.ts | 8 +- .../expressions/utils/SkinToneUtils.ts | 4 +- .../expressions/utils/UnicodeEmojis.ts | 103 +++++++++--------- .../utils/EmoticonConversionUtils.ts | 4 +- .../messaging/utils/markdown/JumboDetector.ts | 2 +- 11 files changed, 81 insertions(+), 86 deletions(-) diff --git a/fluxer_app/scripts/GenerateEmojiSprites.ts b/fluxer_app/scripts/GenerateEmojiSprites.ts index 074fe90ae..88dc8520f 100644 --- a/fluxer_app/scripts/GenerateEmojiSprites.ts +++ b/fluxer_app/scripts/GenerateEmojiSprites.ts @@ -6,8 +6,8 @@ import sharp from 'sharp'; import {convertToCodePoints} from '../src/features/expressions/utils/EmojiCodepointUtils'; const EMOJI_SPRITES = { - nonDiversityPerRow: 42, - diversityPerRow: 10, + basePerRow: 42, + skinTonePerRow: 10, pickerPerRow: 11, pickerCount: 50, } as const; @@ -173,10 +173,10 @@ async function generateMainSpriteSheet( base.push({surrogates: obj.surrogates}); } } - await renderSpriteSheet(base, EMOJI_SPRITES.nonDiversityPerRow, 'spritesheet-emoji', outputDir); + await renderSpriteSheet(base, EMOJI_SPRITES.basePerRow, 'spritesheet-emoji', outputDir); } -async function generateDiversitySpriteSheets( +async function generateSkinToneSpriteSheets( emojiData: Record>, outputDir: string, ): Promise { @@ -195,7 +195,7 @@ async function generateDiversitySpriteSheets( if (skinEntries.length === 0) { continue; } - await renderSpriteSheet(skinEntries, EMOJI_SPRITES.diversityPerRow, `spritesheet-${skinCodepoint}`, outputDir); + await renderSpriteSheet(skinEntries, EMOJI_SPRITES.skinTonePerRow, `spritesheet-${skinCodepoint}`, outputDir); } } @@ -245,8 +245,8 @@ async function main(): Promise { const emojiData: Record> = JSON.parse(readFileSync(emojiDataPath, 'utf-8')); console.log('Generating main sprite sheet...'); await generateMainSpriteSheet(emojiData, outputDir); - console.log('Generating diversity sprite sheets...'); - await generateDiversitySpriteSheets(emojiData, outputDir); + console.log('Generating skin tone sprite sheets...'); + await generateSkinToneSpriteSheets(emojiData, outputDir); console.log('Generating picker sprite sheet...'); await generatePickerSpriteSheet(outputDir); console.log('Emoji sprites generated successfully.'); diff --git a/fluxer_app/src/features/app/components/shared/custom_status_display/CustomStatusDisplay.tsx b/fluxer_app/src/features/app/components/shared/custom_status_display/CustomStatusDisplay.tsx index 5517c28b5..e9906cd6f 100644 --- a/fluxer_app/src/features/app/components/shared/custom_status_display/CustomStatusDisplay.tsx +++ b/fluxer_app/src/features/app/components/shared/custom_status_display/CustomStatusDisplay.tsx @@ -99,7 +99,7 @@ const StatusEmojiWithTooltip = observer( return `:${status.emojiName}:`; } if (status.emojiName) { - return UnicodeEmojis.convertSurrogateToName(status.emojiName, true, status.emojiName); + return UnicodeEmojis.nameForSurrogate(status.emojiName, true, status.emojiName); } return ''; }; diff --git a/fluxer_app/src/features/channel/components/emoji_picker/EmojiPickerInspector.tsx b/fluxer_app/src/features/channel/components/emoji_picker/EmojiPickerInspector.tsx index 145daca14..805c1a09b 100644 --- a/fluxer_app/src/features/channel/components/emoji_picker/EmojiPickerInspector.tsx +++ b/fluxer_app/src/features/channel/components/emoji_picker/EmojiPickerInspector.tsx @@ -42,16 +42,16 @@ export const EmojiPickerInspector = observer(({hoveredEmoji}: EmojiPickerInspect const {url} = getEmojiDisplayDataWithSkinTone(emoji, skinTone); if (url) return {url, useImg: true}; } - const hasDiversity = emoji.hasDiversity && skinTone; - const index = hasDiversity ? emoji.diversityIndex : emoji.index; + const hasSkinTones = emoji.hasSkinTones && skinTone; + const index = hasSkinTones ? emoji.skinToneIndex : emoji.index; if (index === undefined) return {url: emoji.url, useImg: true}; - const perRow = hasDiversity ? EMOJI_SPRITES.DiversityPerRow : EMOJI_SPRITES.NonDiversityPerRow; + const perRow = hasSkinTones ? EMOJI_SPRITES.SkinTonePerRow : EMOJI_SPRITES.BasePerRow; const rows = Math.ceil( - (hasDiversity ? UnicodeEmojis.numDiversitySprites : UnicodeEmojis.numNonDiversitySprites) / perRow, + (hasSkinTones ? UnicodeEmojis.skinToneSpriteCount : UnicodeEmojis.baseSpriteCount) / perRow, ); return { style: { - backgroundImage: getSpriteSheetBackground(hasDiversity ? skinTone : ''), + backgroundImage: getSpriteSheetBackground(hasSkinTones ? skinTone : ''), ...getEmojiSpriteSheetLayout(index, perRow, rows), }, useImg: false, diff --git a/fluxer_app/src/features/channel/components/emoji_picker/EmojiRenderer.tsx b/fluxer_app/src/features/channel/components/emoji_picker/EmojiRenderer.tsx index c43936574..e5dd8e9b4 100644 --- a/fluxer_app/src/features/channel/components/emoji_picker/EmojiRenderer.tsx +++ b/fluxer_app/src/features/channel/components/emoji_picker/EmojiRenderer.tsx @@ -139,8 +139,8 @@ export const EmojiRenderer = React.forwardRef, ); } - const hasDiversity = emoji.hasDiversity && skinTone; - const index = hasDiversity ? emoji.diversityIndex : emoji.index; + const hasSkinTones = emoji.hasSkinTones && skinTone; + const index = hasSkinTones ? emoji.skinToneIndex : emoji.index; if (isFirefoxBrowser()) { const {url} = getEmojiDisplayDataWithSkinTone(emoji, skinTone); if (url) { @@ -166,12 +166,12 @@ export const EmojiRenderer = React.forwardRef, ); } - const perRow = hasDiversity ? EMOJI_SPRITES.DiversityPerRow : EMOJI_SPRITES.NonDiversityPerRow; + const perRow = hasSkinTones ? EMOJI_SPRITES.SkinTonePerRow : EMOJI_SPRITES.BasePerRow; const rows = Math.ceil( - (hasDiversity ? UnicodeEmojis.numDiversitySprites : UnicodeEmojis.numNonDiversitySprites) / perRow, + (hasSkinTones ? UnicodeEmojis.skinToneSpriteCount : UnicodeEmojis.baseSpriteCount) / perRow, ); const spriteStyle = { - backgroundImage: getSpriteSheetBackground(hasDiversity ? skinTone : ''), + backgroundImage: getSpriteSheetBackground(hasSkinTones ? skinTone : ''), ...getEmojiSpriteSheetLayout(index, perRow, rows), }; return renderButton( diff --git a/fluxer_app/src/features/emoji/components/bottomsheets/EmojiInfoBottomSheet.tsx b/fluxer_app/src/features/emoji/components/bottomsheets/EmojiInfoBottomSheet.tsx index 09ae8ba68..a28cec6fe 100644 --- a/fluxer_app/src/features/emoji/components/bottomsheets/EmojiInfoBottomSheet.tsx +++ b/fluxer_app/src/features/emoji/components/bottomsheets/EmojiInfoBottomSheet.tsx @@ -66,7 +66,7 @@ const EmojiInfoBottomSheetContent: React.FC = if (isCustomEmoji) { return `:${emoji.name}:`; } - return UnicodeEmojis.convertSurrogateToName(defaultEmojiSurrogate ?? emoji.name, true, `:${emoji.name}:`); + return UnicodeEmojis.nameForSurrogate(defaultEmojiSurrogate ?? emoji.name, true, `:${emoji.name}:`); }; const emojiName = getEmojiDisplayName(); const renderSubtext = () => { diff --git a/fluxer_app/src/features/emoji/state/Emoji.ts b/fluxer_app/src/features/emoji/state/Emoji.ts index d77b5a9b6..51df3915c 100644 --- a/fluxer_app/src/features/emoji/state/Emoji.ts +++ b/fluxer_app/src/features/emoji/state/Emoji.ts @@ -50,8 +50,8 @@ function toFlatUnicodeEmoji(unicodeEmoji: UnicodeEmoji): FlatEmoji { url: unicodeEmoji.url || undefined, useSpriteSheet: unicodeEmoji.useSpriteSheet, index: unicodeEmoji.index, - diversityIndex: unicodeEmoji.diversityIndex, - hasDiversity: unicodeEmoji.hasDiversity, + skinToneIndex: unicodeEmoji.skinToneIndex, + hasSkinTones: unicodeEmoji.hasSkinTones, }; } @@ -392,8 +392,8 @@ class Emoji { if (emoji.id) { return `<${emoji.animated ? 'a' : ''}:${emoji.uniqueName}:${emoji.id}>`; } - if (emoji.hasDiversity && this.skinTone) { - const skinToneName = UnicodeEmojis.convertSurrogateToName(this.skinTone, false); + if (emoji.hasSkinTones && this.skinTone) { + const skinToneName = UnicodeEmojis.nameForSurrogate(this.skinTone, false); if (skinToneName) { return `:${emoji.uniqueName}::${skinToneName}:`; } diff --git a/fluxer_app/src/features/emoji/types/EmojiTypes.ts b/fluxer_app/src/features/emoji/types/EmojiTypes.ts index 697faba1f..b6e679ced 100644 --- a/fluxer_app/src/features/emoji/types/EmojiTypes.ts +++ b/fluxer_app/src/features/emoji/types/EmojiTypes.ts @@ -23,11 +23,11 @@ export interface UnicodeEmoji { allNamesString: string; url?: string; surrogates: string; - hasDiversity: boolean; + hasSkinTones: boolean; managed: boolean; useSpriteSheet: boolean; index?: number; - diversityIndex?: number; + skinToneIndex?: number; guildId?: string; } @@ -39,7 +39,7 @@ export type FlatEmoji = Readonly< uniqueName: string; useSpriteSheet?: boolean; index?: number; - diversityIndex?: number; - hasDiversity?: boolean; + skinToneIndex?: number; + hasSkinTones?: boolean; } >; diff --git a/fluxer_app/src/features/expressions/utils/SkinToneUtils.ts b/fluxer_app/src/features/expressions/utils/SkinToneUtils.ts index 7d0e315eb..2f3e7eddd 100644 --- a/fluxer_app/src/features/expressions/utils/SkinToneUtils.ts +++ b/fluxer_app/src/features/expressions/utils/SkinToneUtils.ts @@ -10,7 +10,7 @@ export interface EmojiDisplayData { } export function getSkinTonedEmoji(emoji: FlatEmoji, skinTone: string): UnicodeEmoji | null { - if (!emoji.hasDiversity || !skinTone || !emoji.uniqueName) { + if (!emoji.hasSkinTones || !skinTone || !emoji.uniqueName) { return null; } return UnicodeEmojis.findEmojiWithSkinTone(emoji.uniqueName, skinTone); @@ -35,7 +35,7 @@ export function getEmojiDisplayDataWithSkinTone(emoji: FlatEmoji, skinTone: stri export function getSkinTonedSurrogate(emoji: FlatEmoji): string { const skinTone = Emoji.skinTone; - if (!emoji.hasDiversity || !skinTone || !emoji.uniqueName) { + if (!emoji.hasSkinTones || !skinTone || !emoji.uniqueName) { return emoji.surrogates ?? ''; } const skinTonedEmoji = UnicodeEmojis.findEmojiWithSkinTone(emoji.uniqueName, skinTone); diff --git a/fluxer_app/src/features/expressions/utils/UnicodeEmojis.ts b/fluxer_app/src/features/expressions/utils/UnicodeEmojis.ts index 440f06855..feec8310f 100644 --- a/fluxer_app/src/features/expressions/utils/UnicodeEmojis.ts +++ b/fluxer_app/src/features/expressions/utils/UnicodeEmojis.ts @@ -51,8 +51,8 @@ const FLAGS_DESCRIPTOR = msg({ comment: 'Unicode emoji category label.', }); export const EMOJI_SPRITES = { - NonDiversityPerRow: 42, - DiversityPerRow: 10, + BasePerRow: 42, + SkinTonePerRow: 10, PickerPerRow: 11, PickerCount: 50, }; @@ -69,12 +69,12 @@ class UnicodeEmojiClass { allNamesString: string; defaultUrl?: string; surrogates: string; - hasDiversity: boolean; + hasSkinTones: boolean; managed: boolean; useSpriteSheet: boolean; index?: number; - diversityIndex?: number; - diversitiesByName: Record< + skinToneIndex?: number; + skinTonesByName: Record< string, { url: string; @@ -82,12 +82,12 @@ class UnicodeEmojiClass { surrogatePair: string; } >; - urlForDiversitySurrogate: Record; + urlBySkinToneSurrogate: Record; constructor(emojiObject: { names: Array; surrogates: string; - hasDiversity?: boolean; + hasSkinTones?: boolean; keywords?: Array; skins?: Array<{ surrogates: string; @@ -103,22 +103,22 @@ class UnicodeEmojiClass { this.surrogates = surrogates; this.useSpriteSheet = false; this.index = undefined; - this.diversityIndex = undefined; - this.urlForDiversitySurrogate = {}; - this.diversitiesByName = {}; - this.hasDiversity = emojiObject.hasDiversity || !!(emojiObject.skins && emojiObject.skins.length > 0); + this.skinToneIndex = undefined; + this.urlBySkinToneSurrogate = {}; + this.skinTonesByName = {}; + this.hasSkinTones = emojiObject.hasSkinTones || !!(emojiObject.skins && emojiObject.skins.length > 0); this.managed = true; - if (this.hasDiversity && emojiObject.skins) { + if (this.hasSkinTones && emojiObject.skins) { SKIN_TONE_SURROGATES.forEach((skinTone, index) => { const skinData = emojiObject.skins?.[index]; if (skinData) { const surrogatePair = skinData.surrogates; const url = EmojiUtils.getEmojiURL(surrogatePair); if (url) { - this.urlForDiversitySurrogate[skinTone] = url; + this.urlBySkinToneSurrogate[skinTone] = url; names.forEach((name) => { const skinName = `${name}::skin-tone-${index + 1}`; - this.diversitiesByName[skinName] = { + this.skinTonesByName[skinName] = { name: skinName, surrogatePair, url, @@ -130,9 +130,9 @@ class UnicodeEmojiClass { } } - setSpriteSheetIndex(index: number, isDiversity = false) { - if (isDiversity) { - this.diversityIndex = index; + setSpriteSheetIndex(index: number, isSkinTone = false) { + if (isSkinTone) { + this.skinToneIndex = index; } else { this.index = index; } @@ -148,11 +148,11 @@ class UnicodeEmojiClass { allNamesString: this.allNamesString, url: this.defaultUrl, surrogates: this.surrogates, - hasDiversity: this.hasDiversity, + hasSkinTones: this.hasSkinTones, managed: this.managed, useSpriteSheet: this.useSpriteSheet, index: this.index, - diversityIndex: this.diversityIndex, + skinToneIndex: this.skinToneIndex, }; } } @@ -167,8 +167,8 @@ interface EmojiIndex { canonicalSurrogateToName: Record; shortcutToName: Record; emojis: Array; - numDiversitySprites: number; - numNonDiversitySprites: number; + skinToneSpriteCount: number; + baseSpriteCount: number; emojiSurrogateRegex: RegExp; emojiShortcutRegex: RegExp; } @@ -185,16 +185,16 @@ function buildEmojiIndex(): EmojiIndex { const canonicalSurrogateToName: Record = {}; const shortcutToName: Record = {}; const emojis: Array = []; - let numDiversitySprites = 0; - let numNonDiversitySprites = 0; + let skinToneSpriteCount = 0; + let baseSpriteCount = 0; Object.entries(emojiData.categories).forEach(([category, emojiObjects]) => { emojisByCategory[category] = emojiObjects.map((emojiObject) => { const emoji = new UnicodeEmojiClass(emojiObject); - if (emoji.hasDiversity) { - emoji.setSpriteSheetIndex(numDiversitySprites++, true); + if (emoji.hasSkinTones) { + emoji.setSpriteSheetIndex(skinToneSpriteCount++, true); } - emoji.setSpriteSheetIndex(numNonDiversitySprites++, false); + emoji.setSpriteSheetIndex(baseSpriteCount++, false); surrogateToName[emoji.surrogates] = emoji.uniqueName; canonicalSurrogateToName[toCanonicalSurrogate(emoji.surrogates)] = emoji.uniqueName; const emojiJson = emoji.toJSON(); @@ -203,18 +203,18 @@ function buildEmojiIndex(): EmojiIndex { shortcodeNameToEmoji[name] = emojiJson; nameToSurrogate[name] = emoji.surrogates; }); - Object.values(emoji.diversitiesByName).forEach((diversity) => { + Object.values(emoji.skinTonesByName).forEach((skinToneEntry) => { const skinTonedEmoji: UnicodeEmoji = { ...emojiJson, - name: diversity.name, - surrogates: diversity.surrogatePair, - url: diversity.url, + name: skinToneEntry.name, + surrogates: skinToneEntry.surrogatePair, + url: skinToneEntry.url, }; - nameToEmoji[diversity.name] = skinTonedEmoji; - shortcodeNameToEmoji[diversity.name] = skinTonedEmoji; - nameToSurrogate[diversity.name] = diversity.surrogatePair; - surrogateToName[diversity.surrogatePair] = diversity.name; - canonicalSurrogateToName[toCanonicalSurrogate(diversity.surrogatePair)] = diversity.name; + nameToEmoji[skinToneEntry.name] = skinTonedEmoji; + shortcodeNameToEmoji[skinToneEntry.name] = skinTonedEmoji; + nameToSurrogate[skinToneEntry.name] = skinToneEntry.surrogatePair; + surrogateToName[skinToneEntry.surrogatePair] = skinToneEntry.name; + canonicalSurrogateToName[toCanonicalSurrogate(skinToneEntry.surrogatePair)] = skinToneEntry.name; }); categoryByEmojiName[emoji.uniqueName] = category; emojis.push(emojiJson); @@ -273,8 +273,8 @@ function buildEmojiIndex(): EmojiIndex { canonicalSurrogateToName, shortcutToName, emojis, - numDiversitySprites, - numNonDiversitySprites, + skinToneSpriteCount, + baseSpriteCount, emojiSurrogateRegex: new RegExp(`(${surrogateAlternation})`, 'g'), emojiShortcutRegex: new RegExp(`^(${shortcutAlternation})`), }; @@ -288,8 +288,7 @@ function getEmojiIndex(): EmojiIndex { const lookupSurrogateName = (surrogate: string): string | null => getEmojiIndex().canonicalSurrogateToName[toCanonicalSurrogate(surrogate)] ?? null; -const EMOJI_NAME_RE = /^:([^\s:]+?(?:::skin-tone-\d)?):/; -const EMOJI_NAME_AND_DIVERSITY_RE = /^:([^\s:]+?(?:::skin-tone-\d)?):/; +const EMOJI_SHORTCODE_RE = /^:([^\s:]+(?:::skin-tone-[0-9])?):/; const categoryIcons = { people: SmileyIcon, nature: LeafIcon, @@ -332,20 +331,17 @@ export default { getByName: (emojiName: string): UnicodeEmoji | null => getEmojiIndex().nameToEmoji[emojiName] || null, getByCategory: (emojiCategory: string): ReadonlyArray | null => getEmojiIndex().emojisByCategory[emojiCategory] || null, - translateInlineEmojiToSurrogates: (content: string): string => { - return content.replace( - EMOJI_NAME_AND_DIVERSITY_RE, - (original, emoji) => getEmojiIndex().nameToSurrogate[emoji] || original, - ); + shortcodeTextToSurrogates: (content: string): string => { + return content.replace(EMOJI_SHORTCODE_RE, (original, emoji) => getEmojiIndex().nameToSurrogate[emoji] || original); }, - translateSurrogatesToInlineEmoji: (content: string): string => { + surrogateTextToShortcodes: (content: string): string => { const index = getEmojiIndex(); return content.replace(index.emojiSurrogateRegex, (_, surrogate) => { const name = index.surrogateToName[surrogate]; return name ? `:${name}:` : surrogate; }); }, - convertNameToSurrogate: (emojiName: string, defaultSurrogate = ''): string => { + surrogateForName: (emojiName: string, defaultSurrogate = ''): string => { return getEmojiIndex().nameToSurrogate[emojiName] || defaultSurrogate; }, normalizeEmojiNameToSurrogate: (emojiName: string): string => { @@ -354,7 +350,7 @@ export default { trimmed.startsWith(':') && trimmed.endsWith(':') && trimmed.length > 2 ? trimmed.slice(1, -1) : trimmed; return getEmojiIndex().nameToSurrogate[name] || trimmed; }, - convertSurrogateToName: (surrogate: string, includeColons = true, defaultName = ''): string => { + nameForSurrogate: (surrogate: string, includeColons = true, defaultName = ''): string => { const name = lookupSurrogateName(surrogate); if (!name) return defaultName; return includeColons ? `:${name}:` : name; @@ -394,15 +390,14 @@ export default { const skinToneEmojiName = `${baseName}::${skinToneName}`; return index.nameToEmoji[skinToneEmojiName] || null; }, - get numDiversitySprites(): number { - return getEmojiIndex().numDiversitySprites; + get skinToneSpriteCount(): number { + return getEmojiIndex().skinToneSpriteCount; }, - get numNonDiversitySprites(): number { - return getEmojiIndex().numNonDiversitySprites; + get baseSpriteCount(): number { + return getEmojiIndex().baseSpriteCount; }, - EMOJI_NAME_RE, - EMOJI_NAME_AND_DIVERSITY_RE, - get EMOJI_SHORTCUT_RE(): RegExp { + EMOJI_SHORTCODE_RE, + get EMOTICON_PREFIX_RE(): RegExp { return getEmojiIndex().emojiShortcutRegex; }, get EMOJI_SURROGATE_RE(): RegExp { diff --git a/fluxer_app/src/features/messaging/utils/EmoticonConversionUtils.ts b/fluxer_app/src/features/messaging/utils/EmoticonConversionUtils.ts index 3d6b0f31e..12b3c00ed 100644 --- a/fluxer_app/src/features/messaging/utils/EmoticonConversionUtils.ts +++ b/fluxer_app/src/features/messaging/utils/EmoticonConversionUtils.ts @@ -194,7 +194,7 @@ function shortcutToEmoji(shortcut: string): string | null { if (!name) { return null; } - const surrogate = UnicodeEmojis.convertNameToSurrogate(name); + const surrogate = UnicodeEmojis.surrogateForName(name); return surrogate || null; } @@ -202,7 +202,7 @@ function matchEmoticonAt(content: string, index: number): {shortcut: string; emo if (!hasLeadingBoundary(content, index)) { return null; } - const match = UnicodeEmojis.EMOJI_SHORTCUT_RE.exec(content.slice(index)); + const match = UnicodeEmojis.EMOTICON_PREFIX_RE.exec(content.slice(index)); if (match == null) { return null; } diff --git a/fluxer_app/src/features/messaging/utils/markdown/JumboDetector.ts b/fluxer_app/src/features/messaging/utils/markdown/JumboDetector.ts index 7927e754f..0a02d4ec6 100644 --- a/fluxer_app/src/features/messaging/utils/markdown/JumboDetector.ts +++ b/fluxer_app/src/features/messaging/utils/markdown/JumboDetector.ts @@ -23,7 +23,7 @@ export function shouldRenderAsJumboEmojis(nodes: ReadonlyArray): boolean { return false; } const content = (node as TextNode).content; - if (UnicodeEmojis.EMOJI_NAME_RE.test(content)) { + if (UnicodeEmojis.EMOJI_SHORTCODE_RE.test(content)) { emojiCount++; if (emojiCount > MAX_JUMBO_EMOJI_COUNT) return false; continue;