From 3b5e302f7fc1e62cbd075e154ad9415f20fde2ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=9F=E3=81=84=E3=81=A1=20=E3=81=B2?= Date: Wed, 14 Jun 2023 02:28:31 +0900 Subject: [PATCH] Rewrite `emoji_mart_data_light` as TS (#25138) --- .../features/emoji/emoji_compressed.d.ts | 51 ++++++++++++++++++ .../features/emoji/emoji_compressed.js | 10 ++++ .../features/emoji/emoji_mart_data_light.js | 43 --------------- .../features/emoji/emoji_mart_data_light.ts | 52 +++++++++++++++++++ 4 files changed, 113 insertions(+), 43 deletions(-) create mode 100644 app/javascript/mastodon/features/emoji/emoji_compressed.d.ts delete mode 100644 app/javascript/mastodon/features/emoji/emoji_mart_data_light.js create mode 100644 app/javascript/mastodon/features/emoji/emoji_mart_data_light.ts diff --git a/app/javascript/mastodon/features/emoji/emoji_compressed.d.ts b/app/javascript/mastodon/features/emoji/emoji_compressed.d.ts new file mode 100644 index 000000000..2408942ed --- /dev/null +++ b/app/javascript/mastodon/features/emoji/emoji_compressed.d.ts @@ -0,0 +1,51 @@ +import type { BaseEmoji, EmojiData, NimbleEmojiIndex } from 'emoji-mart'; +import type { Category, Data, Emoji } from 'emoji-mart/dist-es/utils/data'; + +/* + * The 'search' property, although not defined in the [`Emoji`]{@link node_modules/@types/emoji-mart/dist-es/utils/data.d.ts#Emoji} type, + * is used in the application. + * This could be due to an oversight by the library maintainer. + * The `search` property is defined and used [here]{@link node_modules/emoji-mart/dist/utils/data.js#uncompress}. + */ +export type Search = string; +/* + * The 'skins' property does not exist in the application data. + * This could be a potential area of refactoring or error handling. + * The non-existence of 'skins' property is evident at [this location]{@link app/javascript/mastodon/features/emoji/emoji_compressed.js:121}. + */ +export type Skins = null; + +export type FilenameData = string[] | string[][]; +export type ShortCodesToEmojiDataKey = + | EmojiData['id'] + | BaseEmoji['native'] + | keyof NimbleEmojiIndex['emojis']; + +export type SearchData = [ + BaseEmoji['native'], + Emoji['short_names'], + Search, + Emoji['unified'] +]; + +export interface ShortCodesToEmojiData { + [key: ShortCodesToEmojiDataKey]: [FilenameData, SearchData]; +} +export type EmojisWithoutShortCodes = FilenameData[]; + +export type EmojiCompressed = [ + ShortCodesToEmojiData, + Skins, + Category[], + Data['aliases'], + EmojisWithoutShortCodes +]; + +/* + * `emoji_compressed.js` uses `babel-plugin-preval`, which makes it difficult to convert to TypeScript. + * As a temporary solution, we are allowing a default export here to apply the TypeScript type `EmojiCompressed` to the JS file export. + * - {@link app/javascript/mastodon/features/emoji/emoji_compressed.js} + */ +declare const emojiCompressed: EmojiCompressed; + +export default emojiCompressed; // eslint-disable-line import/no-default-export diff --git a/app/javascript/mastodon/features/emoji/emoji_compressed.js b/app/javascript/mastodon/features/emoji/emoji_compressed.js index 3d577e50f..883bf21a4 100644 --- a/app/javascript/mastodon/features/emoji/emoji_compressed.js +++ b/app/javascript/mastodon/features/emoji/emoji_compressed.js @@ -118,6 +118,16 @@ Object.keys(emojiIndex.emojis).forEach(key => { // inconsistent behavior in dev mode module.exports = JSON.parse(JSON.stringify([ shortCodesToEmojiData, + /* + * The property `skins` is not found in the current context. + * This could potentially lead to issues when interacting with modules or data structures + * that expect the presence of `skins` property. + * Currently, no definitions or references to `skins` property can be found in: + * - {@link node_modules/emoji-mart/dist/utils/data.js} + * - {@link node_modules/emoji-mart/data/all.json} + * - {@link app/javascript/mastodon/features/emoji/emoji_compressed.d.ts#Skins} + * Future refactorings or updates should consider adding definitions or handling for `skins` property. + */ emojiMartData.skins, emojiMartData.categories, emojiMartData.aliases, diff --git a/app/javascript/mastodon/features/emoji/emoji_mart_data_light.js b/app/javascript/mastodon/features/emoji/emoji_mart_data_light.js deleted file mode 100644 index 11698937c..000000000 --- a/app/javascript/mastodon/features/emoji/emoji_mart_data_light.js +++ /dev/null @@ -1,43 +0,0 @@ -// The output of this module is designed to mimic emoji-mart's -// "data" object, such that we can use it for a light version of emoji-mart's -// emojiIndex.search functionality. -import emojiCompressed from './emoji_compressed'; -import { unicodeToUnifiedName } from './unicode_to_unified_name'; - -const [ shortCodesToEmojiData, skins, categories, short_names ] = emojiCompressed; - -const emojis = {}; - -// decompress -Object.keys(shortCodesToEmojiData).forEach((shortCode) => { - let [ - filenameData, // eslint-disable-line @typescript-eslint/no-unused-vars - searchData, - ] = shortCodesToEmojiData[shortCode]; - let [ - native, - short_names, - search, - unified, - ] = searchData; - - if (!unified) { - // unified name can be derived from unicodeToUnifiedName - unified = unicodeToUnifiedName(native); - } - - short_names = [shortCode].concat(short_names); - emojis[shortCode] = { - native, - search, - short_names, - unified, - }; -}); - -export { - emojis, - skins, - categories, - short_names, -}; diff --git a/app/javascript/mastodon/features/emoji/emoji_mart_data_light.ts b/app/javascript/mastodon/features/emoji/emoji_mart_data_light.ts new file mode 100644 index 000000000..62cb84baf --- /dev/null +++ b/app/javascript/mastodon/features/emoji/emoji_mart_data_light.ts @@ -0,0 +1,52 @@ +// The output of this module is designed to mimic emoji-mart's +// "data" object, such that we can use it for a light version of emoji-mart's +// emojiIndex.search functionality. +import type { BaseEmoji } from 'emoji-mart'; +import type { Emoji } from 'emoji-mart/dist-es/utils/data'; + +import type { Search, ShortCodesToEmojiData } from './emoji_compressed'; +import emojiCompressed from './emoji_compressed'; +import { unicodeToUnifiedName } from './unicode_to_unified_name'; + +type Emojis = { + [key in keyof ShortCodesToEmojiData]: { + native: BaseEmoji['native']; + search: Search; + short_names: Emoji['short_names']; + unified: Emoji['unified']; + }; +}; + +const [ + shortCodesToEmojiData, + skins, + categories, + short_names, + _emojisWithoutShortCodes, +] = emojiCompressed; + +const emojis: Emojis = {}; + +// decompress +Object.keys(shortCodesToEmojiData).forEach((shortCode) => { + const [_filenameData, searchData] = shortCodesToEmojiData[shortCode]; + const native = searchData[0]; + let short_names = searchData[1]; + const search = searchData[2]; + let unified = searchData[3]; + + if (!unified) { + // unified name can be derived from unicodeToUnifiedName + unified = unicodeToUnifiedName(native); + } + + if (short_names) short_names = [shortCode].concat(short_names); + emojis[shortCode] = { + native, + search, + short_names, + unified, + }; +}); + +export { emojis, skins, categories, short_names };