@ckeditor/ckeditor5-emoji 0.0.0-nightly-20250129.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/LICENSE.md +28 -0
  3. package/README.md +31 -0
  4. package/build/emoji.js +4 -0
  5. package/ckeditor5-metadata.json +32 -0
  6. package/dist/index-content.css +4 -0
  7. package/dist/index-editor.css +111 -0
  8. package/dist/index.css +143 -0
  9. package/dist/index.css.map +1 -0
  10. package/dist/index.js +1477 -0
  11. package/dist/index.js.map +1 -0
  12. package/lang/contexts.json +24 -0
  13. package/package.json +67 -0
  14. package/src/augmentation.d.ts +24 -0
  15. package/src/augmentation.js +5 -0
  16. package/src/emoji.d.ts +32 -0
  17. package/src/emoji.js +38 -0
  18. package/src/emojicommand.d.ts +24 -0
  19. package/src/emojicommand.js +33 -0
  20. package/src/emojiconfig.d.ts +80 -0
  21. package/src/emojiconfig.js +5 -0
  22. package/src/emojimention.d.ts +68 -0
  23. package/src/emojimention.js +193 -0
  24. package/src/emojipicker.d.ts +97 -0
  25. package/src/emojipicker.js +255 -0
  26. package/src/emojirepository.d.ts +139 -0
  27. package/src/emojirepository.js +267 -0
  28. package/src/index.d.ts +14 -0
  29. package/src/index.js +13 -0
  30. package/src/ui/emojicategoriesview.d.ts +68 -0
  31. package/src/ui/emojicategoriesview.js +131 -0
  32. package/src/ui/emojigridview.d.ts +140 -0
  33. package/src/ui/emojigridview.js +183 -0
  34. package/src/ui/emojipickerview.d.ts +91 -0
  35. package/src/ui/emojipickerview.js +172 -0
  36. package/src/ui/emojisearchview.d.ts +51 -0
  37. package/src/ui/emojisearchview.js +89 -0
  38. package/src/ui/emojitoneview.d.ts +46 -0
  39. package/src/ui/emojitoneview.js +89 -0
  40. package/theme/emojicategories.css +29 -0
  41. package/theme/emojigrid.css +55 -0
  42. package/theme/emojipicker.css +32 -0
  43. package/theme/emojitone.css +21 -0
@@ -0,0 +1,24 @@
1
+ {
2
+ "Emoji": "Toolbar button tooltip for the Emoji feature.",
3
+ "Show all emoji...": "Dropdown option label for opening an emoji picker offering more results to choose from.",
4
+ "Find an emoji (min. 2 characters)": "Label of an input field for filtering an emoji collection by the typed value.",
5
+ "No emojis were found matching \"%0\".": "The main text of the message shown to the user when no emoji are available for the search criteria.",
6
+ "Keep on typing to see the emoji.": "The main text of the message shown to the user when the provided search query does not contain the required number of characters.",
7
+ "The query must contain at least two characters.": "The secondary text of the message shown to the user to explain how many characters the search query must consist of.",
8
+ "Smileys & Expressions": "Tooltip for filtering the displayed emoji by the \"Smileys & Expressions\" category.",
9
+ "Gestures & People": "Tooltip for filtering the displayed emoji by the \"Gestures & People\" category.",
10
+ "Animals & Nature": "Tooltip for filtering the displayed emoji by the \"Animals & Nature\" category.",
11
+ "Food & Drinks": "Tooltip for filtering the displayed emoji by the \"Food & Drinks\" category.",
12
+ "Travel & Places": "Tooltip for filtering the displayed emoji by the \"Travel & Places\" category.",
13
+ "Activities": "Tooltip for filtering the displayed emoji by the \"Activities\" category.",
14
+ "Objects": "Tooltip for filtering the displayed emoji by the \"Objects\" category.",
15
+ "Symbols": "Tooltip for filtering the displayed emoji by the \"Symbols\" category.",
16
+ "Flags": "Tooltip for filtering the displayed emoji by the \"Flags\" category.",
17
+ "Select skin tone": "Default label for the emoji skin tone dropdown.",
18
+ "Default skin tone": "Dropdown option label for using the \"Default skin tone\" variant. Example emoji: 👋.",
19
+ "Light skin tone": "Dropdown option label for using the \"Light skin tone\" variant. Example emoji: 👋🏻.",
20
+ "Medium Light skin tone": "Dropdown option label for using the \"Medium Light skin tone\" variant. Example emoji: 👋🏼.",
21
+ "Medium skin tone": "Dropdown option label for using the \"Medium skin tone\" variant. Example emoji: 👋🏽.",
22
+ "Medium Dark skin tone": "Dropdown option label for using the \"Medium Dark skin tone\" variant. Example emoji: 👋🏾.",
23
+ "Dark skin tone": "Dropdown option label for using the \"Dark skin tone\" variant. Example emoji: 👋🏿."
24
+ }
package/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "@ckeditor/ckeditor5-emoji",
3
+ "version": "0.0.0-nightly-20250129.0",
4
+ "description": "Emoji feature for CKEditor 5.",
5
+ "keywords": [
6
+ "ckeditor",
7
+ "ckeditor5",
8
+ "ckeditor 5",
9
+ "ckeditor5-feature",
10
+ "ckeditor5-plugin",
11
+ "ckeditor5-dll"
12
+ ],
13
+ "type": "module",
14
+ "main": "src/index.js",
15
+ "dependencies": {
16
+ "@ckeditor/ckeditor5-core": "0.0.0-nightly-20250129.0",
17
+ "@ckeditor/ckeditor5-mention": "0.0.0-nightly-20250129.0",
18
+ "@ckeditor/ckeditor5-typing": "0.0.0-nightly-20250129.0",
19
+ "@ckeditor/ckeditor5-ui": "0.0.0-nightly-20250129.0",
20
+ "@ckeditor/ckeditor5-utils": "0.0.0-nightly-20250129.0",
21
+ "ckeditor5": "0.0.0-nightly-20250129.0",
22
+ "fuse.js": "7.0.0",
23
+ "lodash-es": "4.17.21"
24
+ },
25
+ "author": "CKSource (http://cksource.com/)",
26
+ "license": "SEE LICENSE IN LICENSE.md",
27
+ "homepage": "https://ckeditor.com",
28
+ "bugs": "https://github.com/ckeditor/ckeditor5/issues",
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "https://github.com/ckeditor/ckeditor5.git",
32
+ "directory": "packages/ckeditor5-emoji"
33
+ },
34
+ "files": [
35
+ "dist",
36
+ "lang",
37
+ "src/**/*.js",
38
+ "src/**/*.d.ts",
39
+ "theme",
40
+ "build",
41
+ "ckeditor5-metadata.json",
42
+ "CHANGELOG.md"
43
+ ],
44
+ "types": "src/index.d.ts",
45
+ "exports": {
46
+ ".": {
47
+ "types": "./src/index.d.ts",
48
+ "import": "./src/index.js",
49
+ "default": "./src/index.js"
50
+ },
51
+ "./dist/*": {
52
+ "types": "./src/index.d.ts",
53
+ "import": "./dist/*",
54
+ "default": "./dist/*"
55
+ },
56
+ "./src/*": {
57
+ "types": "./src/*.d.ts",
58
+ "import": "./src/*",
59
+ "default": "./src/*"
60
+ },
61
+ "./build/*": "./build/*",
62
+ "./lang/*": "./lang/*",
63
+ "./theme/*": "./theme/*",
64
+ "./ckeditor5-metadata.json": "./ckeditor5-metadata.json",
65
+ "./package.json": "./package.json"
66
+ }
67
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
+ */
5
+ import type { Emoji, EmojiConfig, EmojiMention, EmojiPicker, EmojiRepository, EmojiCommand } from './index.js';
6
+ declare module '@ckeditor/ckeditor5-core' {
7
+ interface EditorConfig {
8
+ /**
9
+ * The configuration of the {@link module:emoji/emoji~Emoji} feature.
10
+ *
11
+ * Read more in {@link module:emoji/emojiconfig~EmojiConfig}.
12
+ */
13
+ emoji?: EmojiConfig;
14
+ }
15
+ interface PluginsMap {
16
+ [Emoji.pluginName]: Emoji;
17
+ [EmojiMention.pluginName]: EmojiMention;
18
+ [EmojiPicker.pluginName]: EmojiPicker;
19
+ [EmojiRepository.pluginName]: EmojiRepository;
20
+ }
21
+ interface CommandsMap {
22
+ emoji: EmojiCommand;
23
+ }
24
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
+ */
5
+ export {};
package/src/emoji.d.ts ADDED
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
+ */
5
+ /**
6
+ * @module emoji/emoji
7
+ */
8
+ import { Plugin } from 'ckeditor5/src/core.js';
9
+ import EmojiMention from './emojimention.js';
10
+ import EmojiPicker from './emojipicker.js';
11
+ /**
12
+ * The emoji plugin.
13
+ *
14
+ * This is a "glue" plugin which loads the following plugins:
15
+ *
16
+ * * {@link module:emoji/emojimention~EmojiMention},
17
+ * * {@link module:emoji/emojipicker~EmojiPicker},
18
+ */
19
+ export default class Emoji extends Plugin {
20
+ /**
21
+ * @inheritDoc
22
+ */
23
+ static get requires(): readonly [typeof EmojiMention, typeof EmojiPicker];
24
+ /**
25
+ * @inheritDoc
26
+ */
27
+ static get pluginName(): "Emoji";
28
+ /**
29
+ * @inheritDoc
30
+ */
31
+ static get isOfficialPlugin(): true;
32
+ }
package/src/emoji.js ADDED
@@ -0,0 +1,38 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
+ */
5
+ /**
6
+ * @module emoji/emoji
7
+ */
8
+ import { Plugin } from 'ckeditor5/src/core.js';
9
+ import EmojiMention from './emojimention.js';
10
+ import EmojiPicker from './emojipicker.js';
11
+ /**
12
+ * The emoji plugin.
13
+ *
14
+ * This is a "glue" plugin which loads the following plugins:
15
+ *
16
+ * * {@link module:emoji/emojimention~EmojiMention},
17
+ * * {@link module:emoji/emojipicker~EmojiPicker},
18
+ */
19
+ export default class Emoji extends Plugin {
20
+ /**
21
+ * @inheritDoc
22
+ */
23
+ static get requires() {
24
+ return [EmojiMention, EmojiPicker];
25
+ }
26
+ /**
27
+ * @inheritDoc
28
+ */
29
+ static get pluginName() {
30
+ return 'Emoji';
31
+ }
32
+ /**
33
+ * @inheritDoc
34
+ */
35
+ static get isOfficialPlugin() {
36
+ return true;
37
+ }
38
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
+ */
5
+ /**
6
+ * @module emoji/emojicommand
7
+ */
8
+ import { Command } from 'ckeditor5/src/core.js';
9
+ /**
10
+ * Command that shows the emoji user interface.
11
+ */
12
+ export default class EmojiCommand extends Command {
13
+ /**
14
+ * Updates the command's {@link #isEnabled} based on the current selection.
15
+ */
16
+ refresh(): void;
17
+ /**
18
+ * Opens emoji user interface for the current document selection.
19
+ *
20
+ * @fires execute
21
+ * @param [searchValue=''] A default query used to filer the grid when opening the UI.
22
+ */
23
+ execute(searchValue?: string): void;
24
+ }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
+ */
5
+ /**
6
+ * @module emoji/emojicommand
7
+ */
8
+ import { Command } from 'ckeditor5/src/core.js';
9
+ /**
10
+ * Command that shows the emoji user interface.
11
+ */
12
+ export default class EmojiCommand extends Command {
13
+ /**
14
+ * Updates the command's {@link #isEnabled} based on the current selection.
15
+ */
16
+ refresh() {
17
+ const editor = this.editor;
18
+ const model = editor.model;
19
+ const schema = model.schema;
20
+ const selection = model.document.selection;
21
+ this.isEnabled = schema.checkChild(selection.getFirstPosition(), '$text');
22
+ }
23
+ /**
24
+ * Opens emoji user interface for the current document selection.
25
+ *
26
+ * @fires execute
27
+ * @param [searchValue=''] A default query used to filer the grid when opening the UI.
28
+ */
29
+ execute(searchValue = '') {
30
+ const emojiPickerPlugin = this.editor.plugins.get('EmojiPicker');
31
+ emojiPickerPlugin.showUI(searchValue);
32
+ }
33
+ }
@@ -0,0 +1,80 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
+ */
5
+ /**
6
+ * @module emoji/emojiconfig
7
+ */
8
+ /**
9
+ * The configuration of the emoji feature.
10
+ *
11
+ * Read more about {@glink features/emoji#configuration configuring the emoji feature}.
12
+ *
13
+ * ```ts
14
+ * ClassicEditor
15
+ * .create( editorElement, {
16
+ * emoji: ... // Emoji feature options.
17
+ * } )
18
+ * .then( ... )
19
+ * .catch( ... );
20
+ * ```
21
+ *
22
+ * See {@link module:core/editor/editorconfig~EditorConfig all editor configuration options}.
23
+ */
24
+ export interface EmojiConfig {
25
+ /**
26
+ * The maximum number of emojis displayed in the dropdown list.
27
+ *
28
+ * ```ts
29
+ * ClassicEditor
30
+ * .create( editorElement, {
31
+ * plugins: [ Emoji, ... ],
32
+ * emoji: {
33
+ * dropdownLimit: 4
34
+ * }
35
+ * } )
36
+ * .then( ... )
37
+ * .catch( ... );
38
+ * ```
39
+ *
40
+ * @default 6
41
+ */
42
+ dropdownLimit?: number;
43
+ /**
44
+ * Initial skin tone for the emojis that support skin tones.
45
+ *
46
+ * ```ts
47
+ * ClassicEditor
48
+ * .create( editorElement, {
49
+ * plugins: [ Emoji, ... ],
50
+ * emoji: {
51
+ * skinTone: 'medium'
52
+ * }
53
+ * } )
54
+ * .then( ... )
55
+ * .catch( ... );
56
+ * ```
57
+ *
58
+ * @default 'default'
59
+ */
60
+ skinTone?: SkinToneId;
61
+ /**
62
+ * The emoji database version.
63
+ *
64
+ * ```ts
65
+ * ClassicEditor
66
+ * .create( editorElement, {
67
+ * plugins: [ Emoji, ... ],
68
+ * emoji: {
69
+ * version: 15
70
+ * }
71
+ * } )
72
+ * .then( ... )
73
+ * .catch( ... );
74
+ * ```
75
+ *
76
+ * @default 16
77
+ */
78
+ version?: 15 | 16;
79
+ }
80
+ export type SkinToneId = 'default' | 'light' | 'medium-light' | 'medium' | 'medium-dark' | 'dark';
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
+ */
5
+ export {};
@@ -0,0 +1,68 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
+ */
5
+ import { Plugin, type Editor } from 'ckeditor5/src/core.js';
6
+ import { Typing } from 'ckeditor5/src/typing.js';
7
+ import EmojiRepository from './emojirepository.js';
8
+ /**
9
+ * The emoji mention plugin.
10
+ *
11
+ * Introduces the autocomplete of emojis while typing.
12
+ */
13
+ export default class EmojiMention extends Plugin {
14
+ /**
15
+ * An instance of the {@link module:emoji/emojipicker~EmojiPicker} plugin if it is loaded in the editor.
16
+ */
17
+ private _emojiPickerPlugin;
18
+ /**
19
+ * An instance of the {@link module:emoji/emojirepository~EmojiRepository} plugin.
20
+ */
21
+ private _emojiRepositoryPlugin;
22
+ /**
23
+ * Defines a number of displayed items in the auto complete dropdown.
24
+ *
25
+ * It includes the "Show all emoji..." option if the `EmojiPicker` plugin is loaded.
26
+ */
27
+ private readonly _emojiDropdownLimit;
28
+ /**
29
+ * Defines a skin tone that is set in the emoji config.
30
+ */
31
+ private readonly _skinTone;
32
+ /**
33
+ * @inheritDoc
34
+ */
35
+ static get requires(): readonly [typeof EmojiRepository, typeof Typing, "Mention"];
36
+ /**
37
+ * @inheritDoc
38
+ */
39
+ static get pluginName(): "EmojiMention";
40
+ /**
41
+ * @inheritDoc
42
+ */
43
+ static get isOfficialPlugin(): true;
44
+ /**
45
+ * @inheritDoc
46
+ */
47
+ constructor(editor: Editor);
48
+ /**
49
+ * @inheritDoc
50
+ */
51
+ init(): Promise<void>;
52
+ /**
53
+ * Initializes the configuration for emojis in the mention feature.
54
+ */
55
+ private _setupMentionConfiguration;
56
+ /**
57
+ * Returns the `itemRenderer()` callback for mention config.
58
+ */
59
+ private _customItemRendererFactory;
60
+ /**
61
+ * Overrides the default mention execute listener to insert an emoji as plain text instead.
62
+ */
63
+ private _overrideMentionExecuteListener;
64
+ /**
65
+ * Returns the `feed()` callback for mention config.
66
+ */
67
+ private _queryEmojiCallbackFactory;
68
+ }
@@ -0,0 +1,193 @@
1
+ /**
2
+ * @license Copyright (c) 2003-2025, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
4
+ */
5
+ /**
6
+ * @module emoji/emojimention
7
+ */
8
+ import { logWarning } from 'ckeditor5/src/utils.js';
9
+ import { Plugin } from 'ckeditor5/src/core.js';
10
+ import { Typing } from 'ckeditor5/src/typing.js';
11
+ import EmojiRepository from './emojirepository.js';
12
+ const EMOJI_MENTION_MARKER = ':';
13
+ const EMOJI_SHOW_ALL_OPTION_ID = ':__EMOJI_SHOW_ALL:';
14
+ const EMOJI_HINT_OPTION_ID = ':__EMOJI_HINT:';
15
+ /**
16
+ * The emoji mention plugin.
17
+ *
18
+ * Introduces the autocomplete of emojis while typing.
19
+ */
20
+ export default class EmojiMention extends Plugin {
21
+ /**
22
+ * @inheritDoc
23
+ */
24
+ static get requires() {
25
+ return [EmojiRepository, Typing, 'Mention'];
26
+ }
27
+ /**
28
+ * @inheritDoc
29
+ */
30
+ static get pluginName() {
31
+ return 'EmojiMention';
32
+ }
33
+ /**
34
+ * @inheritDoc
35
+ */
36
+ static get isOfficialPlugin() {
37
+ return true;
38
+ }
39
+ /**
40
+ * @inheritDoc
41
+ */
42
+ constructor(editor) {
43
+ super(editor);
44
+ this.editor.config.define('emoji', {
45
+ dropdownLimit: 6
46
+ });
47
+ this._emojiDropdownLimit = editor.config.get('emoji.dropdownLimit');
48
+ this._skinTone = editor.config.get('emoji.skinTone');
49
+ const mentionFeedsConfigs = editor.config.get('mention.feeds');
50
+ const mergeFieldsPrefix = editor.config.get('mergeFields.prefix');
51
+ const markerAlreadyUsed = mentionFeedsConfigs.some(config => config.marker === EMOJI_MENTION_MARKER);
52
+ const isMarkerUsedByMergeFields = mergeFieldsPrefix ? mergeFieldsPrefix[0] === EMOJI_MENTION_MARKER : false;
53
+ if (markerAlreadyUsed || isMarkerUsedByMergeFields) {
54
+ /**
55
+ * The `marker` in the `emoji` config is already used by other plugin configuration.
56
+ *
57
+ * @error emoji-config-marker-already-used
58
+ * @param {string} marker Used marker.
59
+ */
60
+ logWarning('emoji-config-marker-already-used', { marker: EMOJI_MENTION_MARKER });
61
+ return;
62
+ }
63
+ this._setupMentionConfiguration(mentionFeedsConfigs);
64
+ }
65
+ /**
66
+ * @inheritDoc
67
+ */
68
+ async init() {
69
+ const editor = this.editor;
70
+ this._emojiPickerPlugin = editor.plugins.has('EmojiPicker') ? editor.plugins.get('EmojiPicker') : null;
71
+ this._emojiRepositoryPlugin = editor.plugins.get('EmojiRepository');
72
+ // Skip overriding the `mention` command listener if the emoji repository is not ready.
73
+ if (!await this._emojiRepositoryPlugin.isReady()) {
74
+ return;
75
+ }
76
+ editor.once('ready', this._overrideMentionExecuteListener.bind(this));
77
+ }
78
+ /**
79
+ * Initializes the configuration for emojis in the mention feature.
80
+ */
81
+ _setupMentionConfiguration(mentionFeedsConfigs) {
82
+ const emojiMentionFeedConfig = {
83
+ marker: EMOJI_MENTION_MARKER,
84
+ dropdownLimit: this._emojiDropdownLimit,
85
+ itemRenderer: this._customItemRendererFactory(this.editor.t),
86
+ feed: this._queryEmojiCallbackFactory()
87
+ };
88
+ this.editor.config.set('mention.feeds', [...mentionFeedsConfigs, emojiMentionFeedConfig]);
89
+ }
90
+ /**
91
+ * Returns the `itemRenderer()` callback for mention config.
92
+ */
93
+ _customItemRendererFactory(t) {
94
+ return (item) => {
95
+ const itemElement = document.createElement('button');
96
+ itemElement.classList.add('ck');
97
+ itemElement.classList.add('ck-button');
98
+ itemElement.classList.add('ck-button_with-text');
99
+ itemElement.id = `mention-list-item-id${item.id.slice(0, -1)}`;
100
+ itemElement.type = 'button';
101
+ itemElement.tabIndex = -1;
102
+ const labelElement = document.createElement('span');
103
+ labelElement.classList.add('ck');
104
+ labelElement.classList.add('ck-button__label');
105
+ itemElement.appendChild(labelElement);
106
+ if (item.id === EMOJI_HINT_OPTION_ID) {
107
+ itemElement.classList.add('ck-list-item-button');
108
+ itemElement.classList.add('ck-disabled');
109
+ labelElement.textContent = t('Keep on typing to see the emoji.');
110
+ }
111
+ else if (item.id === EMOJI_SHOW_ALL_OPTION_ID) {
112
+ labelElement.textContent = t('Show all emoji...');
113
+ }
114
+ else {
115
+ labelElement.textContent = `${item.text} ${item.id}`;
116
+ }
117
+ return itemElement;
118
+ };
119
+ }
120
+ /**
121
+ * Overrides the default mention execute listener to insert an emoji as plain text instead.
122
+ */
123
+ _overrideMentionExecuteListener() {
124
+ const editor = this.editor;
125
+ editor.commands.get('mention').on('execute', (event, data) => {
126
+ const eventData = data[0];
127
+ // Ignore non-emoji auto-complete actions.
128
+ if (eventData.marker !== EMOJI_MENTION_MARKER) {
129
+ return;
130
+ }
131
+ // Do not propagate the event.
132
+ event.stop();
133
+ // Do nothing when executing after selecting a hint message.
134
+ if (eventData.mention.id === EMOJI_HINT_OPTION_ID) {
135
+ return;
136
+ }
137
+ // Trigger the picker UI.
138
+ if (eventData.mention.id === EMOJI_SHOW_ALL_OPTION_ID) {
139
+ const text = [...eventData.range.getItems()]
140
+ .filter(item => item.is('$textProxy'))
141
+ .map(item => item.data)
142
+ .reduce((result, text) => result + text, '');
143
+ editor.model.change(writer => {
144
+ editor.model.deleteContent(writer.createSelection(eventData.range));
145
+ });
146
+ const emojiPickerPlugin = this._emojiPickerPlugin;
147
+ emojiPickerPlugin.showUI(text.slice(1));
148
+ setTimeout(() => {
149
+ emojiPickerPlugin.emojiPickerView.focus();
150
+ });
151
+ }
152
+ // Or insert the emoji to editor.
153
+ else {
154
+ editor.execute('insertText', {
155
+ text: eventData.mention.text,
156
+ range: eventData.range
157
+ });
158
+ }
159
+ }, { priority: 'high' });
160
+ }
161
+ /**
162
+ * Returns the `feed()` callback for mention config.
163
+ */
164
+ _queryEmojiCallbackFactory() {
165
+ return (searchQuery) => {
166
+ // Do not show anything when a query starts with a space.
167
+ if (searchQuery.startsWith(' ')) {
168
+ return [];
169
+ }
170
+ const emojis = this._emojiRepositoryPlugin.getEmojiByQuery(searchQuery)
171
+ .map(emoji => {
172
+ let text = emoji.skins[this._skinTone] || emoji.skins.default;
173
+ if (this._emojiPickerPlugin) {
174
+ text = emoji.skins[this._emojiPickerPlugin.skinTone] || emoji.skins.default;
175
+ }
176
+ return {
177
+ id: `:${emoji.annotation}:`,
178
+ text
179
+ };
180
+ });
181
+ if (!this._emojiPickerPlugin) {
182
+ return emojis.slice(0, this._emojiDropdownLimit);
183
+ }
184
+ const actionItem = {
185
+ id: searchQuery.length > 1 ? EMOJI_SHOW_ALL_OPTION_ID : EMOJI_HINT_OPTION_ID
186
+ };
187
+ return [
188
+ ...emojis.slice(0, this._emojiDropdownLimit - 1),
189
+ actionItem
190
+ ];
191
+ };
192
+ }
193
+ }