@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.
- package/CHANGELOG.md +4 -0
- package/LICENSE.md +28 -0
- package/README.md +31 -0
- package/build/emoji.js +4 -0
- package/ckeditor5-metadata.json +32 -0
- package/dist/index-content.css +4 -0
- package/dist/index-editor.css +111 -0
- package/dist/index.css +143 -0
- package/dist/index.css.map +1 -0
- package/dist/index.js +1477 -0
- package/dist/index.js.map +1 -0
- package/lang/contexts.json +24 -0
- package/package.json +67 -0
- package/src/augmentation.d.ts +24 -0
- package/src/augmentation.js +5 -0
- package/src/emoji.d.ts +32 -0
- package/src/emoji.js +38 -0
- package/src/emojicommand.d.ts +24 -0
- package/src/emojicommand.js +33 -0
- package/src/emojiconfig.d.ts +80 -0
- package/src/emojiconfig.js +5 -0
- package/src/emojimention.d.ts +68 -0
- package/src/emojimention.js +193 -0
- package/src/emojipicker.d.ts +97 -0
- package/src/emojipicker.js +255 -0
- package/src/emojirepository.d.ts +139 -0
- package/src/emojirepository.js +267 -0
- package/src/index.d.ts +14 -0
- package/src/index.js +13 -0
- package/src/ui/emojicategoriesview.d.ts +68 -0
- package/src/ui/emojicategoriesview.js +131 -0
- package/src/ui/emojigridview.d.ts +140 -0
- package/src/ui/emojigridview.js +183 -0
- package/src/ui/emojipickerview.d.ts +91 -0
- package/src/ui/emojipickerview.js +172 -0
- package/src/ui/emojisearchview.d.ts +51 -0
- package/src/ui/emojisearchview.js +89 -0
- package/src/ui/emojitoneview.d.ts +46 -0
- package/src/ui/emojitoneview.js +89 -0
- package/theme/emojicategories.css +29 -0
- package/theme/emojigrid.css +55 -0
- package/theme/emojipicker.css +32 -0
- 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
|
+
}
|
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,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
|
+
}
|