This repository has been archived by the owner on Jun 26, 2020. It is now read-only.
/
mentioncommand.js
150 lines (136 loc) · 4.56 KB
/
mentioncommand.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/**
* @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/
/**
* @module mention/mentioncommand
*/
import Command from '@ckeditor/ckeditor5-core/src/command';
import toMap from '@ckeditor/ckeditor5-utils/src/tomap';
import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
import { _addMentionAttributes } from './mentionediting';
/**
* The mention command.
*
* The command is registered by {@link module:mention/mentionediting~MentionEditing} as `'mention'`.
*
* To insert a mention onto a range, execute the command and specify a mention object with a range to replace:
*
* const focus = editor.model.document.selection.focus;
*
* // It will replace one character before the selection focus with the '#1234' text
* // with the mention attribute filled with passed attributes.
* editor.execute( 'mention', {
* marker: '#',
* mention: {
* id: '#1234',
* name: 'Foo',
* title: 'Big Foo'
* },
* range: model.createRange( focus, focus.getShiftedBy( -1 ) )
* } );
*
* // It will replace one character before the selection focus with the 'The "Big Foo"' text
* // with the mention attribute filled with passed attributes.
* editor.execute( 'mention', {
* marker: '#',
* mention: {
* id: '#1234',
* name: 'Foo',
* title: 'Big Foo'
* },
* text: 'The "Big Foo"',
* range: model.createRange( focus, focus.getShiftedBy( -1 ) )
* } );
*
* @extends module:core/command~Command
*/
export default class MentionCommand extends Command {
/**
* @inheritDoc
*/
refresh() {
const model = this.editor.model;
const doc = model.document;
this.isEnabled = model.schema.checkAttributeInSelection( doc.selection, 'mention' );
}
/**
* Executes the command.
*
* @param {Object} [options] Options for the executed command.
* @param {Object|String} options.mention The mention object to insert. When a string is passed, it will be used to create a plain
* object with the name attribute that equals the passed string.
* @param {String} options.marker The marker character (e.g. `'@'`).
* @param {String} [options.text] The text of the inserted mention. Defaults to the full mention string composed from `marker` and
* `mention` string or `mention.id` if an object is passed.
* @param {String} [options.range] The range to replace. Note that the replaced range might be shorter than the inserted text with the
* mention attribute.
* @fires execute
*/
execute( options ) {
const model = this.editor.model;
const document = model.document;
const selection = document.selection;
const mentionData = typeof options.mention == 'string' ? { id: options.mention } : options.mention;
const mentionID = mentionData.id;
const range = options.range || selection.getFirstRange();
const mentionText = options.text || mentionID;
const mention = _addMentionAttributes( { _text: mentionText, id: mentionID }, mentionData );
if ( options.marker.length != 1 ) {
/**
* The marker must be a single character.
*
* Correct markers: `'@'`, `'#'`.
*
* Incorrect markers: `'$$'`, `'[@'`.
*
* See {@link module:mention/mention~MentionConfig}.
*
* @error mentioncommand-incorrect-marker
*/
throw new CKEditorError(
'mentioncommand-incorrect-marker: The marker must be a single character.',
this
);
}
if ( mentionID.charAt( 0 ) != options.marker ) {
/**
* The feed item ID must start with the marker character.
*
* Correct mention feed setting:
*
* mentions: [
* {
* marker: '@',
* feed: [ '@Ann', '@Barney', ... ]
* }
* ]
*
* Incorrect mention feed setting:
*
* mentions: [
* {
* marker: '@',
* feed: [ 'Ann', 'Barney', ... ]
* }
* ]
*
* See {@link module:mention/mention~MentionConfig}.
*
* @error mentioncommand-incorrect-id
*/
throw new CKEditorError(
'mentioncommand-incorrect-id: The item id must start with the marker character.',
this
);
}
model.change( writer => {
const currentAttributes = toMap( selection.getAttributes() );
const attributesWithMention = new Map( currentAttributes.entries() );
attributesWithMention.set( 'mention', mention );
// Replace a range with the text with a mention.
model.insertContent( writer.createText( mentionText, attributesWithMention ), range );
model.insertContent( writer.createText( ' ', currentAttributes ), range.start.getShiftedBy( mentionText.length ) );
} );
}
}