@ckeditor/ckeditor5-mention 41.4.2 → 42.0.0-alpha.0

Sign up to get free protection for your applications and to get access to all the features.
package/README.md CHANGED
@@ -15,6 +15,12 @@ Check out the demo in the [mentions (autocomplete) feature guide](https://ckedit
15
15
 
16
16
  See the [`@ckeditor/ckeditor5-mention` package](https://ckeditor.com/docs/ckeditor5/latest/api/mention.html) page in [CKEditor 5 documentation](https://ckeditor.com/docs/ckeditor5/latest/).
17
17
 
18
+ ## Installation
19
+
20
+ ```bash
21
+ npm install ckeditor5
22
+ ```
23
+
18
24
  ## License
19
25
 
20
26
  Licensed under the terms of [GNU General Public License Version 2 or later](http://www.gnu.org/licenses/gpl.html). For full details about the license, please check the `LICENSE.md` file or [https://ckeditor.com/legal/ckeditor-oss-license](https://ckeditor.com/legal/ckeditor-oss-license).
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@
3
3
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4
4
  */
5
5
  import { Command, Plugin } from '@ckeditor/ckeditor5-core/dist/index.js';
6
- import { CKEditorError, toMap, uid, Rect, keyCodes, logWarning, Collection, env } from '@ckeditor/ckeditor5-utils/dist/index.js';
6
+ import { CKEditorError, toMap, uid, Rect, keyCodes, Collection, logWarning, env } from '@ckeditor/ckeditor5-utils/dist/index.js';
7
7
  import { ListView, View, ListItemView, ContextualBalloon, clickOutsideHandler, ButtonView } from '@ckeditor/ckeditor5-ui/dist/index.js';
8
8
  import { TextWatcher } from '@ckeditor/ckeditor5-typing/dist/index.js';
9
9
  import { debounce } from 'lodash-es';
@@ -13,27 +13,69 @@ const BRACKET_PAIRS = {
13
13
  '[': ']',
14
14
  '{': '}'
15
15
  };
16
- class MentionCommand extends Command {
16
+ /**
17
+ * The mention command.
18
+ *
19
+ * The command is registered by {@link module:mention/mentionediting~MentionEditing} as `'mention'`.
20
+ *
21
+ * To insert a mention into a range, execute the command and specify a mention object with a range to replace:
22
+ *
23
+ * ```ts
24
+ * const focus = editor.model.document.selection.focus;
25
+ *
26
+ * // It will replace one character before the selection focus with the '#1234' text
27
+ * // with the mention attribute filled with passed attributes.
28
+ * editor.execute( 'mention', {
29
+ * marker: '#',
30
+ * mention: {
31
+ * id: '#1234',
32
+ * name: 'Foo',
33
+ * title: 'Big Foo'
34
+ * },
35
+ * range: editor.model.createRange( focus.getShiftedBy( -1 ), focus )
36
+ * } );
37
+ *
38
+ * // It will replace one character before the selection focus with the 'The "Big Foo"' text
39
+ * // with the mention attribute filled with passed attributes.
40
+ * editor.execute( 'mention', {
41
+ * marker: '#',
42
+ * mention: {
43
+ * id: '#1234',
44
+ * name: 'Foo',
45
+ * title: 'Big Foo'
46
+ * },
47
+ * text: 'The "Big Foo"',
48
+ * range: editor.model.createRange( focus.getShiftedBy( -1 ), focus )
49
+ * } );
50
+ * ```
51
+ */ class MentionCommand extends Command {
17
52
  /**
18
- * @inheritDoc
19
- */ refresh() {
53
+ * @inheritDoc
54
+ */ constructor(editor){
55
+ super(editor);
56
+ // Since this command may pass range in execution parameters, it should be checked directly in execute block.
57
+ this._isEnabledBasedOnSelection = false;
58
+ }
59
+ /**
60
+ * @inheritDoc
61
+ */ refresh() {
20
62
  const model = this.editor.model;
21
63
  const doc = model.document;
22
64
  this.isEnabled = model.schema.checkAttributeInSelection(doc.selection, 'mention');
23
65
  }
24
66
  /**
25
- * Executes the command.
26
- *
27
- * @param options Options for the executed command.
28
- * @param options.mention The mention object to insert. When a string is passed, it will be used to create a plain
29
- * object with the name attribute that equals the passed string.
30
- * @param options.marker The marker character (e.g. `'@'`).
31
- * @param options.text The text of the inserted mention. Defaults to the full mention string composed from `marker` and
32
- * `mention` string or `mention.id` if an object is passed.
33
- * @param options.range The range to replace.
34
- * Note that the replaced range might be shorter than the inserted text with the mention attribute.
35
- * @fires execute
36
- */ execute(options) {
67
+ * Executes the command.
68
+ *
69
+ * @param options Options for the executed command.
70
+ * @param options.mention The mention object to insert. When a string is passed, it will be used to create a plain
71
+ * object with the name attribute that equals the passed string.
72
+ * @param options.marker The marker character (e.g. `'@'`).
73
+ * @param options.text The text of the inserted mention. Defaults to the full mention string composed from `marker` and
74
+ * `mention` string or `mention.id` if an object is passed.
75
+ * @param options.range The range to replace.
76
+ * Note that the replaced range might be shorter than the inserted text with the mention attribute.
77
+ * @fires execute
78
+ */ execute(options) {
37
79
  const model = this.editor.model;
38
80
  const document = model.document;
39
81
  const selection = document.selection;
@@ -53,47 +95,47 @@ class MentionCommand extends Command {
53
95
  }, mentionData);
54
96
  if (options.marker.length != 1) {
55
97
  /**
56
- * The marker must be a single character.
57
- *
58
- * Correct markers: `'@'`, `'#'`.
59
- *
60
- * Incorrect markers: `'@@'`, `'[@'`.
61
- *
62
- * See {@link module:mention/mentionconfig~MentionConfig}.
63
- *
64
- * @error mentioncommand-incorrect-marker
65
- */ throw new CKEditorError('mentioncommand-incorrect-marker', this);
98
+ * The marker must be a single character.
99
+ *
100
+ * Correct markers: `'@'`, `'#'`.
101
+ *
102
+ * Incorrect markers: `'@@'`, `'[@'`.
103
+ *
104
+ * See {@link module:mention/mentionconfig~MentionConfig}.
105
+ *
106
+ * @error mentioncommand-incorrect-marker
107
+ */ throw new CKEditorError('mentioncommand-incorrect-marker', this);
66
108
  }
67
109
  if (mentionID.charAt(0) != options.marker) {
68
110
  /**
69
- * The feed item ID must start with the marker character.
70
- *
71
- * Correct mention feed setting:
72
- *
73
- * ```ts
74
- * mentions: [
75
- * {
76
- * marker: '@',
77
- * feed: [ '@Ann', '@Barney', ... ]
78
- * }
79
- * ]
80
- * ```
81
- *
82
- * Incorrect mention feed setting:
83
- *
84
- * ```ts
85
- * mentions: [
86
- * {
87
- * marker: '@',
88
- * feed: [ 'Ann', 'Barney', ... ]
89
- * }
90
- * ]
91
- * ```
92
- *
93
- * See {@link module:mention/mentionconfig~MentionConfig}.
94
- *
95
- * @error mentioncommand-incorrect-id
96
- */ throw new CKEditorError('mentioncommand-incorrect-id', this);
111
+ * The feed item ID must start with the marker character.
112
+ *
113
+ * Correct mention feed setting:
114
+ *
115
+ * ```ts
116
+ * mentions: [
117
+ * {
118
+ * marker: '@',
119
+ * feed: [ '@Ann', '@Barney', ... ]
120
+ * }
121
+ * ]
122
+ * ```
123
+ *
124
+ * Incorrect mention feed setting:
125
+ *
126
+ * ```ts
127
+ * mentions: [
128
+ * {
129
+ * marker: '@',
130
+ * feed: [ 'Ann', 'Barney', ... ]
131
+ * }
132
+ * ]
133
+ * ```
134
+ *
135
+ * See {@link module:mention/mentionconfig~MentionConfig}.
136
+ *
137
+ * @error mentioncommand-incorrect-id
138
+ */ throw new CKEditorError('mentioncommand-incorrect-id', this);
97
139
  }
98
140
  model.change((writer)=>{
99
141
  const currentAttributes = toMap(selection.getAttributes());
@@ -120,24 +162,23 @@ class MentionCommand extends Command {
120
162
  }
121
163
  });
122
164
  }
123
- /**
124
- * @inheritDoc
125
- */ constructor(editor){
126
- super(editor);
127
- // Since this command may pass range in execution parameters, it should be checked directly in execute block.
128
- this._isEnabledBasedOnSelection = false;
129
- }
130
165
  }
131
166
 
132
- class MentionEditing extends Plugin {
167
+ /**
168
+ * The mention editing feature.
169
+ *
170
+ * It introduces the {@link module:mention/mentioncommand~MentionCommand command} and the `mention`
171
+ * attribute in the {@link module:engine/model/model~Model model} which renders in the {@link module:engine/view/view view}
172
+ * as a `<span class="mention" data-mention="@mention">`.
173
+ */ class MentionEditing extends Plugin {
133
174
  /**
134
- * @inheritDoc
135
- */ static get pluginName() {
175
+ * @inheritDoc
176
+ */ static get pluginName() {
136
177
  return 'MentionEditing';
137
178
  }
138
179
  /**
139
- * @inheritDoc
140
- */ init() {
180
+ * @inheritDoc
181
+ */ init() {
141
182
  const editor = this.editor;
142
183
  const model = editor.model;
143
184
  const doc = model.document;
@@ -341,39 +382,56 @@ class MentionEditing extends Plugin {
341
382
  return false;
342
383
  }
343
384
 
344
- class MentionsView extends ListView {
385
+ /**
386
+ * The mention ui view.
387
+ */ class MentionsView extends ListView {
388
+ selected;
389
+ position;
345
390
  /**
346
- * {@link #select Selects} the first item.
347
- */ selectFirst() {
391
+ * @inheritDoc
392
+ */ constructor(locale){
393
+ super(locale);
394
+ this.extendTemplate({
395
+ attributes: {
396
+ class: [
397
+ 'ck-mentions'
398
+ ],
399
+ tabindex: '-1'
400
+ }
401
+ });
402
+ }
403
+ /**
404
+ * {@link #select Selects} the first item.
405
+ */ selectFirst() {
348
406
  this.select(0);
349
407
  }
350
408
  /**
351
- * Selects next item to the currently {@link #select selected}.
352
- *
353
- * If the last item is already selected, it will select the first item.
354
- */ selectNext() {
409
+ * Selects next item to the currently {@link #select selected}.
410
+ *
411
+ * If the last item is already selected, it will select the first item.
412
+ */ selectNext() {
355
413
  const item = this.selected;
356
414
  const index = this.items.getIndex(item);
357
415
  this.select(index + 1);
358
416
  }
359
417
  /**
360
- * Selects previous item to the currently {@link #select selected}.
361
- *
362
- * If the first item is already selected, it will select the last item.
363
- */ selectPrevious() {
418
+ * Selects previous item to the currently {@link #select selected}.
419
+ *
420
+ * If the first item is already selected, it will select the last item.
421
+ */ selectPrevious() {
364
422
  const item = this.selected;
365
423
  const index = this.items.getIndex(item);
366
424
  this.select(index - 1);
367
425
  }
368
426
  /**
369
- * Marks item at a given index as selected.
370
- *
371
- * Handles selection cycling when passed index is out of bounds:
372
- * - if the index is lower than 0, it will select the last item,
373
- * - if the index is higher than the last item index, it will select the first item.
374
- *
375
- * @param index Index of an item to be marked as selected.
376
- */ select(index) {
427
+ * Marks item at a given index as selected.
428
+ *
429
+ * Handles selection cycling when passed index is out of bounds:
430
+ * - if the index is lower than 0, it will select the last item,
431
+ * - if the index is higher than the last item index, it will select the first item.
432
+ *
433
+ * @param index Index of an item to be marked as selected.
434
+ */ select(index) {
377
435
  let indexToGet = 0;
378
436
  if (index > 0 && index < this.items.length) {
379
437
  indexToGet = index;
@@ -397,51 +455,34 @@ class MentionsView extends ListView {
397
455
  }
398
456
  }
399
457
  /**
400
- * Triggers the `execute` event on the {@link #select selected} item.
401
- */ executeSelected() {
458
+ * Triggers the `execute` event on the {@link #select selected} item.
459
+ */ executeSelected() {
402
460
  this.selected.fire('execute');
403
461
  }
404
462
  /**
405
- * Checks if an item is visible in the scrollable area.
406
- *
407
- * The item is considered visible when:
408
- * - its top boundary is inside the scrollable rect
409
- * - its bottom boundary is inside the scrollable rect (the whole item must be visible)
410
- */ _isItemVisibleInScrolledArea(item) {
463
+ * Checks if an item is visible in the scrollable area.
464
+ *
465
+ * The item is considered visible when:
466
+ * - its top boundary is inside the scrollable rect
467
+ * - its bottom boundary is inside the scrollable rect (the whole item must be visible)
468
+ */ _isItemVisibleInScrolledArea(item) {
411
469
  return new Rect(this.element).contains(new Rect(item.element));
412
470
  }
413
- /**
414
- * @inheritDoc
415
- */ constructor(locale){
416
- super(locale);
417
- this.extendTemplate({
418
- attributes: {
419
- class: [
420
- 'ck-mentions'
421
- ],
422
- tabindex: '-1'
423
- }
424
- });
425
- }
426
471
  }
427
472
 
428
- class DomWrapperView extends View {
429
- /**
430
- * @inheritDoc
431
- */ render() {
432
- super.render();
433
- this.element = this.domElement;
434
- }
473
+ /**
474
+ * This class wraps DOM element as a CKEditor5 UI View.
475
+ *
476
+ * It allows to render any DOM element and use it in mentions list.
477
+ */ class DomWrapperView extends View {
435
478
  /**
436
- * Focuses the DOM element.
437
- */ focus() {
438
- this.domElement.focus();
439
- }
479
+ * The DOM element for which wrapper was created.
480
+ */ domElement;
440
481
  /**
441
- * Creates an instance of {@link module:mention/ui/domwrapperview~DomWrapperView} class.
442
- *
443
- * Also see {@link #render}.
444
- */ constructor(locale, domElement){
482
+ * Creates an instance of {@link module:mention/ui/domwrapperview~DomWrapperView} class.
483
+ *
484
+ * Also see {@link #render}.
485
+ */ constructor(locale, domElement){
445
486
  super(locale);
446
487
  // Disable template rendering on this view.
447
488
  this.template = undefined;
@@ -464,9 +505,22 @@ class DomWrapperView extends View {
464
505
  this.fire('execute');
465
506
  });
466
507
  }
508
+ /**
509
+ * @inheritDoc
510
+ */ render() {
511
+ super.render();
512
+ this.element = this.domElement;
513
+ }
514
+ /**
515
+ * Focuses the DOM element.
516
+ */ focus() {
517
+ this.domElement.focus();
518
+ }
467
519
  }
468
520
 
469
521
  class MentionListItemView extends ListItemView {
522
+ item;
523
+ marker;
470
524
  highlight() {
471
525
  const child = this.children.first;
472
526
  child.isOn = true;
@@ -489,22 +543,49 @@ const defaultCommitKeyCodes = [
489
543
  keyCodes.enter,
490
544
  keyCodes.tab
491
545
  ];
492
- class MentionUI extends Plugin {
546
+ /**
547
+ * The mention UI feature.
548
+ */ class MentionUI extends Plugin {
549
+ /**
550
+ * The mention view.
551
+ */ _mentionsView;
552
+ /**
553
+ * Stores mention feeds configurations.
554
+ */ _mentionsConfigurations;
555
+ /**
556
+ * The contextual balloon plugin instance.
557
+ */ _balloon;
558
+ _items = new Collection();
559
+ _lastRequested;
560
+ /**
561
+ * Debounced feed requester. It uses `lodash#debounce` method to delay function call.
562
+ */ _requestFeedDebounced;
493
563
  /**
494
- * @inheritDoc
495
- */ static get pluginName() {
564
+ * @inheritDoc
565
+ */ static get pluginName() {
496
566
  return 'MentionUI';
497
567
  }
498
568
  /**
499
- * @inheritDoc
500
- */ static get requires() {
569
+ * @inheritDoc
570
+ */ static get requires() {
501
571
  return [
502
572
  ContextualBalloon
503
573
  ];
504
574
  }
505
575
  /**
506
- * @inheritDoc
507
- */ init() {
576
+ * @inheritDoc
577
+ */ constructor(editor){
578
+ super(editor);
579
+ this._mentionsView = this._createMentionView();
580
+ this._mentionsConfigurations = new Map();
581
+ this._requestFeedDebounced = debounce(this._requestFeed, 100);
582
+ editor.config.define('mention', {
583
+ feeds: []
584
+ });
585
+ }
586
+ /**
587
+ * @inheritDoc
588
+ */ init() {
508
589
  const editor = this.editor;
509
590
  const commitKeys = editor.config.get('mention.commitKeys') || defaultCommitKeyCodes;
510
591
  const handledKeyCodes = defaultHandledKeyCodes.concat(commitKeys);
@@ -544,17 +625,17 @@ class MentionUI extends Plugin {
544
625
  const { feed, marker, dropdownLimit } = mentionDescription;
545
626
  if (!isValidMentionMarker(marker)) {
546
627
  /**
547
- * The marker must be a single character.
548
- *
549
- * Correct markers: `'@'`, `'#'`.
550
- *
551
- * Incorrect markers: `'$$'`, `'[@'`.
552
- *
553
- * See {@link module:mention/mentionconfig~MentionConfig}.
554
- *
555
- * @error mentionconfig-incorrect-marker
556
- * @param marker Configured marker
557
- */ throw new CKEditorError('mentionconfig-incorrect-marker', null, {
628
+ * The marker must be a single character.
629
+ *
630
+ * Correct markers: `'@'`, `'#'`.
631
+ *
632
+ * Incorrect markers: `'$$'`, `'[@'`.
633
+ *
634
+ * See {@link module:mention/mentionconfig~MentionConfig}.
635
+ *
636
+ * @error mentionconfig-incorrect-marker
637
+ * @param marker Configured marker
638
+ */ throw new CKEditorError('mentionconfig-incorrect-marker', null, {
558
639
  marker
559
640
  });
560
641
  }
@@ -575,27 +656,27 @@ class MentionUI extends Plugin {
575
656
  this.on('requestFeed:response', (evt, data)=>this._handleFeedResponse(data));
576
657
  this.on('requestFeed:error', ()=>this._hideUIAndRemoveMarker());
577
658
  /**
578
- * Checks if a given key code is handled by the mention UI.
579
- */ function isHandledKey(keyCode) {
659
+ * Checks if a given key code is handled by the mention UI.
660
+ */ function isHandledKey(keyCode) {
580
661
  return handledKeyCodes.includes(keyCode);
581
662
  }
582
663
  }
583
664
  /**
584
- * @inheritDoc
585
- */ destroy() {
665
+ * @inheritDoc
666
+ */ destroy() {
586
667
  super.destroy();
587
668
  // Destroy created UI components as they are not automatically destroyed (see ckeditor5#1341).
588
669
  this._mentionsView.destroy();
589
670
  }
590
671
  /**
591
- * Returns true when {@link #_mentionsView} is in the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon} and it is
592
- * currently visible.
593
- */ get _isUIVisible() {
672
+ * Returns true when {@link #_mentionsView} is in the {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon} and it is
673
+ * currently visible.
674
+ */ get _isUIVisible() {
594
675
  return this._balloon.visibleView === this._mentionsView;
595
676
  }
596
677
  /**
597
- * Creates the {@link #_mentionsView}.
598
- */ _createMentionView() {
678
+ * Creates the {@link #_mentionsView}.
679
+ */ _createMentionView() {
599
680
  const locale = this.editor.locale;
600
681
  const mentionsView = new MentionsView(locale);
601
682
  mentionsView.items.bindTo(this._items).using((data)=>{
@@ -642,14 +723,14 @@ class MentionUI extends Plugin {
642
723
  return mentionsView;
643
724
  }
644
725
  /**
645
- * Returns item renderer for the marker.
646
- */ _getItemRenderer(marker) {
726
+ * Returns item renderer for the marker.
727
+ */ _getItemRenderer(marker) {
647
728
  const { itemRenderer } = this._mentionsConfigurations.get(marker);
648
729
  return itemRenderer;
649
730
  }
650
731
  /**
651
- * Requests a feed from a configured callbacks.
652
- */ _requestFeed(marker, feedText) {
732
+ * Requests a feed from a configured callbacks.
733
+ */ _requestFeed(marker, feedText) {
653
734
  // @if CK_DEBUG_MENTION // console.log( '%c[Feed]%c Requesting for', 'color: blue', 'color: black', `"${ feedText }"` );
654
735
  // Store the last requested feed - it is used to discard any out-of order requests.
655
736
  this._lastRequested = feedText;
@@ -688,18 +769,18 @@ class MentionUI extends Plugin {
688
769
  error
689
770
  });
690
771
  /**
691
- * The callback used for obtaining mention autocomplete feed thrown and error and the mention UI was hidden or
692
- * not displayed at all.
693
- *
694
- * @error mention-feed-callback-error
695
- */ logWarning('mention-feed-callback-error', {
772
+ * The callback used for obtaining mention autocomplete feed thrown and error and the mention UI was hidden or
773
+ * not displayed at all.
774
+ *
775
+ * @error mention-feed-callback-error
776
+ */ logWarning('mention-feed-callback-error', {
696
777
  marker
697
778
  });
698
779
  });
699
780
  }
700
781
  /**
701
- * Registers a text watcher for the marker.
702
- */ _setupTextWatcher(feeds) {
782
+ * Registers a text watcher for the marker.
783
+ */ _setupTextWatcher(feeds) {
703
784
  const editor = this.editor;
704
785
  const feedsWithPattern = feeds.map((feed)=>({
705
786
  ...feed,
@@ -756,8 +837,8 @@ class MentionUI extends Plugin {
756
837
  return watcher;
757
838
  }
758
839
  /**
759
- * Handles the feed response event data.
760
- */ _handleFeedResponse(data) {
840
+ * Handles the feed response event data.
841
+ */ _handleFeedResponse(data) {
761
842
  const { feed, marker } = data;
762
843
  // eslint-disable-next-line max-len
763
844
  // @if CK_DEBUG_MENTION // console.log( `%c[Feed]%c Response for "${ data.feedText }" (${ feed.length })`, 'color: blue', 'color: black', feed );
@@ -786,8 +867,8 @@ class MentionUI extends Plugin {
786
867
  }
787
868
  }
788
869
  /**
789
- * Shows the mentions balloon. If the panel is already visible, it will reposition it.
790
- */ _showOrUpdateUI(markerMarker) {
870
+ * Shows the mentions balloon. If the panel is already visible, it will reposition it.
871
+ */ _showOrUpdateUI(markerMarker) {
791
872
  if (this._isUIVisible) {
792
873
  // @if CK_DEBUG_MENTION // console.log( '%c[UI]%c Updating position.', 'color: green', 'color: black' );
793
874
  // Update balloon position as the mention list view may change its size.
@@ -804,8 +885,8 @@ class MentionUI extends Plugin {
804
885
  this._mentionsView.selectFirst();
805
886
  }
806
887
  /**
807
- * Hides the mentions balloon and removes the 'mention' marker from the markers collection.
808
- */ _hideUIAndRemoveMarker() {
888
+ * Hides the mentions balloon and removes the 'mention' marker from the markers collection.
889
+ */ _hideUIAndRemoveMarker() {
809
890
  // Remove the mention view from balloon before removing marker - it is used by balloon position target().
810
891
  if (this._balloon.hasView(this._mentionsView)) {
811
892
  // @if CK_DEBUG_MENTION // console.log( '%c[UI]%c Hiding the UI.', 'color: green', 'color: black' );
@@ -820,8 +901,8 @@ class MentionUI extends Plugin {
820
901
  this._mentionsView.position = undefined;
821
902
  }
822
903
  /**
823
- * Renders a single item in the autocomplete list.
824
- */ _renderItem(item, marker) {
904
+ * Renders a single item in the autocomplete list.
905
+ */ _renderItem(item, marker) {
825
906
  const editor = this.editor;
826
907
  let view;
827
908
  let label = item.id;
@@ -843,11 +924,11 @@ class MentionUI extends Plugin {
843
924
  return view;
844
925
  }
845
926
  /**
846
- * Creates a position options object used to position the balloon panel.
847
- *
848
- * @param mentionMarker
849
- * @param preferredPosition The name of the last matched position name.
850
- */ _getBalloonPanelPositionData(mentionMarker, preferredPosition) {
927
+ * Creates a position options object used to position the balloon panel.
928
+ *
929
+ * @param mentionMarker
930
+ * @param preferredPosition The name of the last matched position name.
931
+ */ _getBalloonPanelPositionData(mentionMarker, preferredPosition) {
851
932
  const editor = this.editor;
852
933
  const editing = editor.editing;
853
934
  const domConverter = editing.view.domConverter;
@@ -877,18 +958,6 @@ class MentionUI extends Plugin {
877
958
  positions: getBalloonPanelPositions(preferredPosition, uiLanguageDirection)
878
959
  };
879
960
  }
880
- /**
881
- * @inheritDoc
882
- */ constructor(editor){
883
- super(editor);
884
- this._items = new Collection();
885
- this._mentionsView = this._createMentionView();
886
- this._mentionsConfigurations = new Map();
887
- this._requestFeedDebounced = debounce(this._requestFeed, 100);
888
- editor.config.define('mention', {
889
- feeds: []
890
- });
891
- }
892
961
  }
893
962
  /**
894
963
  * Returns the balloon positions data callbacks.
@@ -1085,18 +1154,22 @@ class MentionUI extends Plugin {
1085
1154
  return editor.model.markers.has('mention');
1086
1155
  }
1087
1156
 
1088
- class Mention extends Plugin {
1157
+ /**
1158
+ * The mention plugin.
1159
+ *
1160
+ * For a detailed overview, check the {@glink features/mentions Mention feature} guide.
1161
+ */ class Mention extends Plugin {
1089
1162
  toMentionAttribute(viewElement, data) {
1090
1163
  return _toMentionAttribute(viewElement, data);
1091
1164
  }
1092
1165
  /**
1093
- * @inheritDoc
1094
- */ static get pluginName() {
1166
+ * @inheritDoc
1167
+ */ static get pluginName() {
1095
1168
  return 'Mention';
1096
1169
  }
1097
1170
  /**
1098
- * @inheritDoc
1099
- */ static get requires() {
1171
+ * @inheritDoc
1172
+ */ static get requires() {
1100
1173
  return [
1101
1174
  MentionEditing,
1102
1175
  MentionUI