@ckeditor/ckeditor5-mention 47.6.1 → 48.0.0-alpha.1

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.
@@ -5,8 +5,8 @@
5
5
  /**
6
6
  * @module mention/mention
7
7
  */
8
- import { Plugin } from 'ckeditor5/src/core.js';
9
- import type { ModelElement } from 'ckeditor5/src/engine.js';
8
+ import { Plugin } from '@ckeditor/ckeditor5-core';
9
+ import type { ModelElement } from '@ckeditor/ckeditor5-engine';
10
10
  import { MentionEditing } from './mentionediting.js';
11
11
  import { MentionUI } from './mentionui.js';
12
12
  import '../theme/mention.css';
@@ -5,8 +5,8 @@
5
5
  /**
6
6
  * @module mention/mentioncommand
7
7
  */
8
- import { Command, type Editor } from 'ckeditor5/src/core.js';
9
- import type { ModelRange } from 'ckeditor5/src/engine.js';
8
+ import { Command, type Editor } from '@ckeditor/ckeditor5-core';
9
+ import type { ModelRange } from '@ckeditor/ckeditor5-engine';
10
10
  /**
11
11
  * The mention command.
12
12
  *
@@ -5,8 +5,8 @@
5
5
  /**
6
6
  * @module mention/mentionediting
7
7
  */
8
- import { Plugin } from 'ckeditor5/src/core.js';
9
- import type { ModelElement } from 'ckeditor5/src/engine.js';
8
+ import { Plugin } from '@ckeditor/ckeditor5-core';
9
+ import type { ModelElement } from '@ckeditor/ckeditor5-engine';
10
10
  import type { MentionAttribute } from './mention.js';
11
11
  /**
12
12
  * The mention editing feature.
@@ -5,8 +5,8 @@
5
5
  /**
6
6
  * @module mention/mentionui
7
7
  */
8
- import { Plugin, type Editor } from 'ckeditor5/src/core.js';
9
- import { ContextualBalloon } from 'ckeditor5/src/ui.js';
8
+ import { Plugin, type Editor } from '@ckeditor/ckeditor5-core';
9
+ import { ContextualBalloon } from '@ckeditor/ckeditor5-ui';
10
10
  /**
11
11
  * The mention UI feature.
12
12
  */
@@ -5,8 +5,8 @@
5
5
  /**
6
6
  * @module mention/ui/domwrapperview
7
7
  */
8
- import { View } from 'ckeditor5/src/ui.js';
9
- import type { Locale } from 'ckeditor5/src/utils.js';
8
+ import { View } from '@ckeditor/ckeditor5-ui';
9
+ import type { Locale } from '@ckeditor/ckeditor5-utils';
10
10
  /**
11
11
  * This class wraps DOM element as a CKEditor5 UI View.
12
12
  *
@@ -5,7 +5,7 @@
5
5
  /**
6
6
  * @module mention/ui/mentionlistitemview
7
7
  */
8
- import { ListItemView } from 'ckeditor5/src/ui.js';
8
+ import { ListItemView } from '@ckeditor/ckeditor5-ui';
9
9
  import type { MentionFeedItem } from '../mentionconfig.js';
10
10
  export declare class MentionListItemView extends ListItemView {
11
11
  item: MentionFeedItem;
@@ -5,8 +5,8 @@
5
5
  /**
6
6
  * @module mention/ui/mentionsview
7
7
  */
8
- import { ListView } from 'ckeditor5/src/ui.js';
9
- import { type Locale } from 'ckeditor5/src/utils.js';
8
+ import { ListView } from '@ckeditor/ckeditor5-ui';
9
+ import { type Locale } from '@ckeditor/ckeditor5-utils';
10
10
  import { type MentionListItemView } from './mentionlistitemview.js';
11
11
  import '../../theme/mentionui.css';
12
12
  /**
package/package.json CHANGED
@@ -1,64 +1,42 @@
1
1
  {
2
2
  "name": "@ckeditor/ckeditor5-mention",
3
- "version": "47.6.1",
3
+ "version": "48.0.0-alpha.1",
4
4
  "description": "Mention feature for CKEditor 5.",
5
+ "license": "SEE LICENSE IN LICENSE.md",
6
+ "author": "CKSource (http://cksource.com/)",
7
+ "homepage": "https://ckeditor.com/ckeditor-5",
8
+ "bugs": "https://github.com/ckeditor/ckeditor5/issues",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "https://github.com/ckeditor/ckeditor5.git",
12
+ "directory": "packages/ckeditor5-mention"
13
+ },
5
14
  "keywords": [
6
15
  "ckeditor",
7
16
  "ckeditor5",
8
17
  "ckeditor 5",
9
18
  "ckeditor5-feature",
10
- "ckeditor5-plugin",
11
- "ckeditor5-dll"
19
+ "ckeditor5-plugin"
12
20
  ],
13
21
  "type": "module",
14
- "main": "src/index.js",
15
- "dependencies": {
16
- "@ckeditor/ckeditor5-core": "47.6.1",
17
- "@ckeditor/ckeditor5-typing": "47.6.1",
18
- "@ckeditor/ckeditor5-ui": "47.6.1",
19
- "@ckeditor/ckeditor5-utils": "47.6.1",
20
- "ckeditor5": "47.6.1",
21
- "es-toolkit": "1.39.5"
22
+ "main": "./dist/index.js",
23
+ "exports": {
24
+ ".": "./dist/index.js",
25
+ "./dist/*": "./dist/*",
26
+ "./package.json": "./package.json"
22
27
  },
23
- "author": "CKSource (http://cksource.com/)",
24
- "license": "SEE LICENSE IN LICENSE.md",
25
- "homepage": "https://ckeditor.com/ckeditor-5",
26
- "bugs": "https://github.com/ckeditor/ckeditor5/issues",
27
- "repository": {
28
- "type": "git",
29
- "url": "https://github.com/ckeditor/ckeditor5.git",
30
- "directory": "packages/ckeditor5-mention"
28
+ "dependencies": {
29
+ "@ckeditor/ckeditor5-core": "48.0.0-alpha.1",
30
+ "@ckeditor/ckeditor5-engine": "48.0.0-alpha.1",
31
+ "@ckeditor/ckeditor5-typing": "48.0.0-alpha.1",
32
+ "@ckeditor/ckeditor5-ui": "48.0.0-alpha.1",
33
+ "@ckeditor/ckeditor5-utils": "48.0.0-alpha.1",
34
+ "es-toolkit": "1.45.1"
31
35
  },
32
36
  "files": [
33
37
  "dist",
34
- "lang",
35
- "src/**/*.js",
36
- "src/**/*.d.ts",
37
- "theme",
38
- "build",
39
38
  "ckeditor5-metadata.json",
40
39
  "CHANGELOG.md"
41
40
  ],
42
- "types": "src/index.d.ts",
43
- "exports": {
44
- ".": {
45
- "types": "./src/index.d.ts",
46
- "import": "./src/index.js",
47
- "default": "./src/index.js"
48
- },
49
- "./dist/*": {
50
- "types": "./src/index.d.ts",
51
- "import": "./dist/*",
52
- "default": "./dist/*"
53
- },
54
- "./src/*": {
55
- "types": "./src/*.d.ts",
56
- "import": "./src/*",
57
- "default": "./src/*"
58
- },
59
- "./build/*": "./build/*",
60
- "./theme/*": "./theme/*",
61
- "./ckeditor5-metadata.json": "./ckeditor5-metadata.json",
62
- "./package.json": "./package.json"
63
- }
41
+ "types": "./dist/index.d.ts"
64
42
  }
package/build/mention.js DELETED
@@ -1,4 +0,0 @@
1
- /*!
2
- * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
3
- * For licensing, see LICENSE.md.
4
- */(()=>{var e={33:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});var i=n(792),o=n.n(i),r=n(305),s=n.n(r)()(o());s.push([e.id,":root{--ck-content-color-mention-background:rgba(153,0,48,.1);--ck-content-color-mention-text:#990030}.ck-content .mention{background:var(--ck-content-color-mention-background);color:var(--ck-content-color-mention-text)}",""]);const a=s},159:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});var i=n(792),o=n.n(i),r=n(305),s=n.n(r)()(o());s.push([e.id,":root{--ck-mention-list-max-height:300px}.ck.ck-mentions{max-height:var(--ck-mention-list-max-height);overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain}.ck.ck-mentions>.ck-list__item{flex-shrink:0;overflow:hidden}div.ck.ck-balloon-panel.ck-mention-balloon{z-index:calc(var( --ck-z-dialog ) + 1)}",""]);const a=s},163:e=>{"use strict";e.exports=function(e){var t=document.createElement("style");return e.setAttributes(t,e.attributes),e.insert(t,e.options),t}},237:e=>{"use strict";e.exports=CKEditor5.dll},305:e=>{"use strict";e.exports=function(e){var t=[];return t.toString=function(){return this.map(function(t){var n="",i=void 0!==t[5];return t[4]&&(n+="@supports (".concat(t[4],") {")),t[2]&&(n+="@media ".concat(t[2]," {")),i&&(n+="@layer".concat(t[5].length>0?" ".concat(t[5]):""," {")),n+=e(t),i&&(n+="}"),t[2]&&(n+="}"),t[4]&&(n+="}"),n}).join("")},t.i=function(e,n,i,o,r){"string"==typeof e&&(e=[[null,e,void 0]]);var s={};if(i)for(var a=0;a<this.length;a++){var c=this[a][0];null!=c&&(s[c]=!0)}for(var l=0;l<e.length;l++){var d=[].concat(e[l]);i&&s[d[0]]||(void 0!==r&&(void 0===d[5]||(d[1]="@layer".concat(d[5].length>0?" ".concat(d[5]):""," {").concat(d[1],"}")),d[5]=r),n&&(d[2]?(d[1]="@media ".concat(d[2]," {").concat(d[1],"}"),d[2]=n):d[2]=n),o&&(d[4]?(d[1]="@supports (".concat(d[4],") {").concat(d[1],"}"),d[4]=o):d[4]="".concat(o)),t.push(d))}},t}},311:(e,t,n)=>{e.exports=n(237)("./src/ui.js")},424:e=>{"use strict";var t={};e.exports=function(e,n){var i=function(e){if(void 0===t[e]){var n=document.querySelector(e);if(window.HTMLIFrameElement&&n instanceof window.HTMLIFrameElement)try{n=n.contentDocument.head}catch(e){n=null}t[e]=n}return t[e]}(e);if(!i)throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.");i.appendChild(n)}},517:e=>{"use strict";e.exports=function(e,t){Object.keys(t).forEach(function(n){e.setAttribute(n,t[n])})}},584:(e,t,n)=>{e.exports=n(237)("./src/utils.js")},719:e=>{"use strict";var t=[];function n(e){for(var n=-1,i=0;i<t.length;i++)if(t[i].identifier===e){n=i;break}return n}function i(e,i){for(var r={},s=[],a=0;a<e.length;a++){var c=e[a],l=i.base?c[0]+i.base:c[0],d=r[l]||0,u="".concat(l," ").concat(d);r[l]=d+1;var m=n(u),h={css:c[1],media:c[2],sourceMap:c[3],supports:c[4],layer:c[5]};if(-1!==m)t[m].references++,t[m].updater(h);else{var f=o(h,i);i.byIndex=a,t.splice(a,0,{identifier:u,updater:f,references:1})}s.push(u)}return s}function o(e,t){var n=t.domAPI(t);n.update(e);return function(t){if(t){if(t.css===e.css&&t.media===e.media&&t.sourceMap===e.sourceMap&&t.supports===e.supports&&t.layer===e.layer)return;n.update(e=t)}else n.remove()}}e.exports=function(e,o){var r=i(e=e||[],o=o||{});return function(e){e=e||[];for(var s=0;s<r.length;s++){var a=n(r[s]);t[a].references--}for(var c=i(e,o),l=0;l<r.length;l++){var d=n(r[l]);0===t[d].references&&(t[d].updater(),t.splice(d,1))}r=c}}},782:(e,t,n)=>{e.exports=n(237)("./src/core.js")},792:e=>{"use strict";e.exports=function(e){return e[1]}},834:(e,t,n)=>{e.exports=n(237)("./src/typing.js")},863:e=>{"use strict";var t,n=(t=[],function(e,n){return t[e]=n,t.filter(Boolean).join("\n")});function i(e,t,i,o){var r;if(i)r="";else{r="",o.supports&&(r+="@supports (".concat(o.supports,") {")),o.media&&(r+="@media ".concat(o.media," {"));var s=void 0!==o.layer;s&&(r+="@layer".concat(o.layer.length>0?" ".concat(o.layer):""," {")),r+=o.css,s&&(r+="}"),o.media&&(r+="}"),o.supports&&(r+="}")}if(e.styleSheet)e.styleSheet.cssText=n(t,r);else{var a=document.createTextNode(r),c=e.childNodes;c[t]&&e.removeChild(c[t]),c.length?e.insertBefore(a,c[t]):e.appendChild(a)}}var o={singleton:null,singletonCounter:0};e.exports=function(e){if("undefined"==typeof document)return{update:function(){},remove:function(){}};var t=o.singletonCounter++,n=o.singleton||(o.singleton=e.insertStyleElement(e));return{update:function(e){i(n,t,!1,e)},remove:function(e){i(n,t,!0,e)}}}}},t={};function n(i){var o=t[i];if(void 0!==o)return o.exports;var r=t[i]={id:i,exports:{}};return e[i](r,r.exports,n),r.exports}n.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return n.d(t,{a:t}),t},n.d=(e,t)=>{for(var i in t)n.o(t,i)&&!n.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:t[i]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),n.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var i={};(()=>{"use strict";n.r(i),n.d(i,{Mention:()=>D,MentionCommand:()=>r,MentionDomWrapperView:()=>V,MentionEditing:()=>s,MentionListItemView:()=>R,MentionUI:()=>S,MentionsView:()=>E,_addMentionAttributes:()=>a,_createMentionMarkerRegExp:()=>U,_toMentionAttribute:()=>c});var e=n(782),t=n(584);const o={"(":")","[":"]","{":"}"};class r extends e.Command{constructor(e){super(e),this._isEnabledBasedOnSelection=!1}refresh(){const e=this.editor.model,t=e.document;this.isEnabled=e.schema.checkAttributeInSelection(t.selection,"mention")}execute(e){const n=this.editor.model,i=n.document.selection,r="string"==typeof e.mention?{id:e.mention}:e.mention,s=r.id,c=e.range||i.getFirstRange();if(!n.canEditAt(c))return;const l=e.text||s,d=a({_text:l,id:s},r);if(!s.startsWith(e.marker))throw new t.CKEditorError("mentioncommand-incorrect-id",this);n.change(e=>{const r=(0,t.toMap)(i.getAttributes()),s=new Map(r.entries());s.set("mention",d);const a=n.insertContent(e.createText(l,s),c),u=a.start.nodeBefore,m=a.end.nodeAfter,h=m&&m.is("$text")&&m.data.startsWith(" ");let f=!1;if(u&&m&&u.is("$text")&&m.is("$text")){const e=u.data.slice(-1),t=e in o,n=t&&m.data.startsWith(o[e]);f=t&&n}f||h||n.insertContent(e.createText(" ",r),c.start.getShiftedBy(l.length))})}}class s extends e.Plugin{static get pluginName(){return"MentionEditing"}static get isOfficialPlugin(){return!0}init(){const e=this.editor,t=e.model,n=t.document;t.schema.extend("$text",{allowAttributes:"mention"}),e.conversion.for("upcast").elementToAttribute({view:{name:"span",attributes:"data-mention",classes:"mention"},model:{key:"mention",value:e=>c(e)}}),e.conversion.for("downcast").attributeToElement({model:"mention",view:d}),e.conversion.for("downcast").add(l),n.registerPostFixer(e=>function(e,t,n){const i=t.differ.getChanges();let o=!1;for(const t of i){if("attribute"==t.type)continue;const i=t.position;if("$text"==t.name){const t=i.textNode&&i.textNode.nextSibling;o=m(i.textNode,e)||o,o=m(t,e)||o,o=m(i.nodeBefore,e)||o,o=m(i.nodeAfter,e)||o}if("$text"!=t.name&&"insert"==t.type){const t=i.nodeAfter;for(const n of e.createRangeIn(t).getItems())o=m(n,e)||o}if("insert"==t.type&&n.isInline(t.name)){const t=i.nodeAfter&&i.nodeAfter.nextSibling;o=m(i.nodeBefore,e)||o,o=m(t,e)||o}}return o}(e,n,t.schema)),n.registerPostFixer(e=>function(e,t){const n=t.differ.getChanges();let i=!1;for(const t of n)if("attribute"===t.type&&"mention"!=t.attributeKey){const n=t.range.start.nodeBefore,o=t.range.end.nodeAfter;for(const r of[n,o])u(r)&&r.getAttribute(t.attributeKey)!=t.attributeNewValue&&(e.setAttribute(t.attributeKey,t.attributeNewValue,r),i=!0)}return i}(e,n)),n.registerPostFixer(e=>function(e,t){const n=t.selection,i=n.focus;if(n.isCollapsed&&n.hasAttribute("mention")&&function(e){const t=e.isAtStart;return e.nodeBefore&&e.nodeBefore.is("$text")||t}(i))return e.removeSelectionAttribute("mention"),!0;return!1}(e,n)),e.commands.add("mention",new r(e))}}function a(e,n){return Object.assign({uid:(0,t.uid)()},e,n||{})}function c(e,t){const n=e.getAttribute("data-mention"),i=e.getChild(0);if(!i)return;return a({id:n,_text:i.data},t)}function l(e){e.on("attribute:mention",(e,t,n)=>{const i=t.attributeNewValue;if(!t.item.is("$textProxy")||!i)return;const o=t.range.start;(o.textNode||o.nodeAfter).data!=i._text&&n.consumable.consume(t.item,e.name)},{priority:"highest"})}function d(e,{writer:t}){if(!e)return;const n={class:"mention","data-mention":e.id},i={id:e.uid,priority:20};return t.createAttributeElement("span",n,i)}function u(e){if(!e||!e.is("$text")&&!e.is("$textProxy")||!e.hasAttribute("mention"))return!1;return e.data!=e.getAttribute("mention")._text}function m(e,t){return!!u(e)&&(t.removeAttribute("mention",e),!0)}var h=n(311),f=n(834);function g(e,t,{signal:n,edges:i}={}){let o,r=null;const s=null!=i&&i.includes("leading"),a=null==i||i.includes("trailing"),c=()=>{null!==r&&(e.apply(o,r),o=void 0,r=null)};let l=null;const d=()=>{null!=l&&clearTimeout(l),l=setTimeout(()=>{l=null,a&&c(),m()},t)},u=()=>{null!==l&&(clearTimeout(l),l=null)},m=()=>{u(),o=void 0,r=null},h=function(...e){if(n?.aborted)return;o=this,r=e;const t=null==l;d(),s&&t&&c()};return h.schedule=d,h.cancel=m,h.flush=()=>{u(),c()},n?.addEventListener("abort",m,{once:!0}),h}var p=n(719),w=n.n(p),v=n(863),b=n.n(v),x=n(424),_=n.n(x),k=n(517),y=n.n(k),A=n(163),C=n.n(A),M=n(159),I={attributes:{"data-cke":!0}};I.setAttributes=y(),I.insert=_().bind(null,"head"),I.domAPI=b(),I.insertStyleElement=C();w()(M.A,I);M.A&&M.A.locals&&M.A.locals;class E extends h.ListView{selected;position;constructor(e){super(e),this.extendTemplate({attributes:{class:["ck-mentions"],tabindex:"-1"}})}selectFirst(){this.select(0)}selectNext(){const e=this.selected,t=this.items.getIndex(e);this.select(t+1)}selectPrevious(){const e=this.selected,t=this.items.getIndex(e);this.select(t-1)}select(e){let t=0;e>0&&e<this.items.length?t=e:e<0&&(t=this.items.length-1);const n=this.items.get(t);this.selected!==n&&(this.selected&&this.selected.removeHighlight(),n.highlight(),this.selected=n,this._isItemVisibleInScrolledArea(n)||(this.element.scrollTop=n.element.offsetTop))}executeSelected(){this.selected.fire("execute")}_isItemVisibleInScrolledArea(e){return new t.Rect(this.element).contains(new t.Rect(e.element))}}class V extends h.View{domElement;constructor(e,t){super(e),this.template=void 0,this.domElement=t,this.domElement.classList.add("ck-button"),this.set("isOn",!1),this.on("change:isOn",(e,t,n)=>{n?(this.domElement.classList.add("ck-on"),this.domElement.classList.remove("ck-off")):(this.domElement.classList.add("ck-off"),this.domElement.classList.remove("ck-on"))}),this.listenTo(this.domElement,"click",()=>{this.fire("execute")})}render(){super.render(),this.element=this.domElement}focus(){this.domElement.focus()}}class R extends h.ListItemView{item;marker;highlight(){this.children.first.isOn=!0}removeHighlight(){this.children.first.isOn=!1}}const P=[t.keyCodes.arrowup,t.keyCodes.arrowdown,t.keyCodes.esc],T=[t.keyCodes.enter,t.keyCodes.tab];class S extends e.Plugin{_mentionsView;_mentionsConfigurations;_balloon;_items=new t.Collection;_lastRequested;_requestFeedDebounced;static get pluginName(){return"MentionUI"}static get isOfficialPlugin(){return!0}static get requires(){return[h.ContextualBalloon]}constructor(e){super(e),this._mentionsView=this._createMentionView(),this._mentionsConfigurations=new Map,this._requestFeedDebounced=function(e,t=0,n={}){"object"!=typeof n&&(n={});const{leading:i=!1,trailing:o=!0,maxWait:r}=n,s=Array(2);let a;i&&(s[0]="leading"),o&&(s[1]="trailing");let c=null;const l=g(function(...t){a=e.apply(this,t),c=null},t,{edges:s}),d=function(...t){return null!=r&&(null===c&&(c=Date.now()),Date.now()-c>=r)?(a=e.apply(this,t),c=Date.now(),l.cancel(),l.schedule(),a):(l.apply(this,t),a)};return d.cancel=l.cancel,d.flush=()=>(l.flush(),a),d}(this._requestFeed,100),e.config.define("mention",{feeds:[]})}init(){const e=this.editor,n=e.config.get("mention.commitKeys")||T,i=P.concat(n);this._balloon=e.plugins.get(h.ContextualBalloon),e.editing.view.document.on("keydown",(e,o)=>{var r;r=o.keyCode,i.includes(r)&&this._isUIVisible&&(o.preventDefault(),e.stop(),o.keyCode==t.keyCodes.arrowdown&&this._mentionsView.selectNext(),o.keyCode==t.keyCodes.arrowup&&this._mentionsView.selectPrevious(),n.includes(o.keyCode)&&this._mentionsView.executeSelected(),o.keyCode==t.keyCodes.esc&&this._hideUIAndRemoveMarker())},{priority:"highest"}),(0,h.clickOutsideHandler)({emitter:this._mentionsView,activator:()=>this._isUIVisible,contextElements:()=>[this._balloon.view.element],callback:()=>this._hideUIAndRemoveMarker()});const o=e.config.get("mention.feeds");for(const e of o){const{feed:n,marker:i,dropdownLimit:o}=e;if(!B(i))throw new t.CKEditorError("mentionconfig-incorrect-marker",null,{marker:i});const r={marker:i,feedCallback:"function"==typeof n?n.bind(this.editor):$(n),itemRenderer:e.itemRenderer,dropdownLimit:o};this._mentionsConfigurations.set(i,r)}this._setupTextWatcher(o),this.listenTo(e,"change:isReadOnly",()=>{this._hideUIAndRemoveMarker()}),this.on("requestFeed:response",(e,t)=>this._handleFeedResponse(t)),this.on("requestFeed:error",()=>this._hideUIAndRemoveMarker())}destroy(){super.destroy(),this._mentionsView.destroy()}get _isUIVisible(){return this._balloon.visibleView===this._mentionsView}_createMentionView(){const e=this.editor.locale,t=new E(e);return t.items.bindTo(this._items).using(n=>{const{item:i,marker:o}=n,{dropdownLimit:r}=this._mentionsConfigurations.get(o),s=r||this.editor.config.get("mention.dropdownLimit")||10;if(t.items.length>=s)return null;const a=new R(e),c=this._renderItem(i,o);return c.delegate("execute").to(a),a.children.add(c),a.item=i,a.marker=o,a.on("execute",()=>{t.fire("execute",{item:i,marker:o})}),a}),t.on("execute",(e,t)=>{const n=this.editor,i=n.model,o=t.item,r=t.marker,s=n.model.markers.get("mention"),a=i.createPositionAt(i.document.selection.focus),c=i.createPositionAt(s.getStart()),l=i.createRange(c,a);this._hideUIAndRemoveMarker(),n.execute("mention",{mention:o,text:o.text,marker:r,range:l}),n.editing.view.focus()}),t}_getItemRenderer(e){const{itemRenderer:t}=this._mentionsConfigurations.get(e);return t}_requestFeed(e,n){this._lastRequested=n;const{feedCallback:i}=this._mentionsConfigurations.get(e),o=i(n);o instanceof Promise?o.then(t=>{this._lastRequested==n?this.fire("requestFeed:response",{feed:t,marker:e,feedText:n}):this.fire("requestFeed:discarded",{feed:t,marker:e,feedText:n})}).catch(n=>{this.fire("requestFeed:error",{error:n}),(0,t.logWarning)("mention-feed-callback-error",{marker:e})}):this.fire("requestFeed:response",{feed:o,marker:e,feedText:n})}_setupTextWatcher(e){const t=this.editor,n=e.map(e=>({...e,pattern:U(e.marker,e.minimumCharacters||0)})),i=new f.TextWatcher(t.model,function(e){const t=t=>{const n=F(e,t);if(!n)return!1;let i=0;0!==n.position&&(i=n.position-1);const o=t.substring(i);return n.pattern.test(o)};return t}(n));i.on("matched",(e,i)=>{const o=F(n,i.text),r=t.model.document.selection.focus,s=t.model.createPositionAt(r.parent,o.position);if(function(e){const t=e.textNode&&e.textNode.hasAttribute("mention"),n=e.nodeBefore;return t||n&&n.is("$text")&&n.hasAttribute("mention")}(r)||function(e){const t=e.nodeAfter;return t&&t.is("$text")&&t.hasAttribute("mention")}(s))return void this._hideUIAndRemoveMarker();const a=function(e,t){let n=0;0!==e.position&&(n=e.position-1);const i=U(e.marker,0),o=t.substring(n);return o.match(i)[2]}(o,i.text),c=o.marker.length+a.length,l=r.getShiftedBy(-c),d=r.getShiftedBy(-a.length),u=t.model.createRange(l,d);if(L(t)){const e=t.model.markers.get("mention");t.model.change(t=>{t.updateMarker(e,{range:u})})}else t.model.change(e=>{e.addMarker("mention",{range:u,usingOperation:!1,affectsData:!1})});this._requestFeedDebounced(o.marker,a)}),i.on("unmatched",()=>{this._hideUIAndRemoveMarker()});const o=t.commands.get("mention");return i.bind("isEnabled").to(o),i}_handleFeedResponse(e){const{feed:t,marker:n}=e;if(!L(this.editor))return;this._items.clear();for(const e of t){const t="object"!=typeof e?{id:e,text:e}:e;this._items.add({item:t,marker:n})}const i=this.editor.model.markers.get("mention");this._items.length?this._showOrUpdateUI(i):this._hideUIAndRemoveMarker()}_showOrUpdateUI(e){this._isUIVisible?this._balloon.updatePosition(this._getBalloonPanelPositionData(e,this._mentionsView.position)):this._balloon.add({view:this._mentionsView,position:this._getBalloonPanelPositionData(e,this._mentionsView.position),singleViewMode:!0,balloonClassName:"ck-mention-balloon"}),this._mentionsView.position=this._balloon.view.position,this._mentionsView.selectFirst()}_hideUIAndRemoveMarker(){this._balloon.hasView(this._mentionsView)&&this._balloon.remove(this._mentionsView),L(this.editor)&&this.editor.model.change(e=>e.removeMarker("mention")),this._mentionsView.position=void 0}_renderItem(e,t){const n=this.editor;let i,o=e.id;const r=this._getItemRenderer(t);if(r){const t=r(e);"string"!=typeof t?i=new V(n.locale,t):o=t}if(!i){const e=new h.ButtonView(n.locale);e.label=o,e.withText=!0,i=e}return i}_getBalloonPanelPositionData(e,n){const i=this.editor,o=i.editing,r=o.view.domConverter,s=o.mapper;return{target:()=>{let n=e.getRange();"$graveyard"==n.start.root.rootName&&(n=i.model.document.selection.getFirstRange());const o=s.toViewRange(n);return t.Rect.getDomRangeRects(r.viewRangeToDom(o)).pop()},limiter:()=>{const e=this.editor.editing.view,t=e.document.selection.editableElement;return t?e.domConverter.mapViewToDom(t.root):null},positions:O(n,i.locale.uiLanguageDirection)}}}function O(e,t){const n={caret_se:e=>({top:e.bottom+3,left:e.right,name:"caret_se",config:{withArrow:!1}}),caret_ne:(e,t)=>({top:e.top-t.height-3,left:e.right,name:"caret_ne",config:{withArrow:!1}}),caret_sw:(e,t)=>({top:e.bottom+3,left:e.right-t.width,name:"caret_sw",config:{withArrow:!1}}),caret_nw:(e,t)=>({top:e.top-t.height-3,left:e.right-t.width,name:"caret_nw",config:{withArrow:!1}})};return Object.prototype.hasOwnProperty.call(n,e)?[n[e]]:"rtl"!==t?[n.caret_se,n.caret_sw,n.caret_ne,n.caret_nw]:[n.caret_sw,n.caret_se,n.caret_nw,n.caret_ne]}function F(e,t){let n;for(const i of e){const e=t.lastIndexOf(i.marker);e>0&&!t.substring(e-1).match(i.pattern)||(!n||e>=n.position)&&(n={marker:i.marker,position:e,minimumCharacters:i.minimumCharacters,pattern:i.pattern})}return n}function U(e,n){const i=0==n?"*":`{${n},}`,o=t.env.features.isRegExpUnicodePropertySupported?"\\p{Ps}\\p{Pi}\"'":"\\(\\[{\"'";e=e.replace(/[.*+?^${}()\-|[\]\\]/g,"\\$&");return new RegExp(`(?:^|[ ${o}])(${e})(.${i})$`,"u")}function $(e){return t=>e.filter(e=>("string"==typeof e?e:String(e.id)).toLowerCase().includes(t.toLowerCase()))}function B(e){return!!e}function L(e){return e.model.markers.has("mention")}var N=n(33),q={attributes:{"data-cke":!0}};q.setAttributes=y(),q.insert=_().bind(null,"head"),q.domAPI=b(),q.insertStyleElement=C();w()(N.A,q);N.A&&N.A.locals&&N.A.locals;class D extends e.Plugin{toMentionAttribute(e,t){return c(e,t)}static get pluginName(){return"Mention"}static get isOfficialPlugin(){return!0}static get requires(){return[s,S]}}})(),(window.CKEditor5=window.CKEditor5||{}).mention=i})();
@@ -1,5 +0,0 @@
1
- /**
2
- * @license Copyright (c) 2003-2026, 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/index.js DELETED
@@ -1,17 +0,0 @@
1
- /**
2
- * @license Copyright (c) 2003-2026, 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 mention
7
- */
8
- export { Mention } from './mention.js';
9
- export { MentionEditing } from './mentionediting.js';
10
- export { MentionUI } from './mentionui.js';
11
- export { MentionsView } from './ui/mentionsview.js';
12
- export { MentionListItemView } from './ui/mentionlistitemview.js';
13
- export { MentionDomWrapperView } from './ui/domwrapperview.js';
14
- export { MentionCommand } from './mentioncommand.js';
15
- export { createRegExp as _createMentionMarkerRegExp } from './mentionui.js';
16
- export { _addMentionAttributes as _addMentionAttributes, _toMentionAttribute as _toMentionAttribute } from './mentionediting.js';
17
- import './augmentation.js';
package/src/mention.js DELETED
@@ -1,39 +0,0 @@
1
- /**
2
- * @license Copyright (c) 2003-2026, 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 mention/mention
7
- */
8
- import { Plugin } from 'ckeditor5/src/core.js';
9
- import { MentionEditing, _toMentionAttribute } from './mentionediting.js';
10
- import { MentionUI } from './mentionui.js';
11
- import '../theme/mention.css';
12
- /**
13
- * The mention plugin.
14
- *
15
- * For a detailed overview, check the {@glink features/mentions Mention feature} guide.
16
- */
17
- export class Mention extends Plugin {
18
- toMentionAttribute(viewElement, data) {
19
- return _toMentionAttribute(viewElement, data);
20
- }
21
- /**
22
- * @inheritDoc
23
- */
24
- static get pluginName() {
25
- return 'Mention';
26
- }
27
- /**
28
- * @inheritDoc
29
- */
30
- static get isOfficialPlugin() {
31
- return true;
32
- }
33
- /**
34
- * @inheritDoc
35
- */
36
- static get requires() {
37
- return [MentionEditing, MentionUI];
38
- }
39
- }
@@ -1,152 +0,0 @@
1
- /**
2
- * @license Copyright (c) 2003-2026, 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 mention/mentioncommand
7
- */
8
- import { Command } from 'ckeditor5/src/core.js';
9
- import { CKEditorError, toMap } from 'ckeditor5/src/utils.js';
10
- import { _addMentionAttributes } from './mentionediting.js';
11
- const BRACKET_PAIRS = {
12
- '(': ')',
13
- '[': ']',
14
- '{': '}'
15
- };
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
- */
52
- export class MentionCommand extends Command {
53
- /**
54
- * @inheritDoc
55
- */
56
- constructor(editor) {
57
- super(editor);
58
- // Since this command may pass range in execution parameters, it should be checked directly in execute block.
59
- this._isEnabledBasedOnSelection = false;
60
- }
61
- /**
62
- * @inheritDoc
63
- */
64
- refresh() {
65
- const model = this.editor.model;
66
- const doc = model.document;
67
- this.isEnabled = model.schema.checkAttributeInSelection(doc.selection, 'mention');
68
- }
69
- /**
70
- * Executes the command.
71
- *
72
- * @param options Options for the executed command.
73
- * @param options.mention The mention object to insert. When a string is passed, it will be used to create a plain
74
- * object with the name attribute that equals the passed string.
75
- * @param options.marker The marker character (e.g. `'@'`).
76
- * @param options.text The text of the inserted mention. Defaults to the full mention string composed from `marker` and
77
- * `mention` string or `mention.id` if an object is passed.
78
- * @param options.range The range to replace.
79
- * Note that the replaced range might be shorter than the inserted text with the mention attribute.
80
- * @fires execute
81
- */
82
- execute(options) {
83
- const model = this.editor.model;
84
- const document = model.document;
85
- const selection = document.selection;
86
- const mentionData = typeof options.mention == 'string' ? { id: options.mention } : options.mention;
87
- const mentionID = mentionData.id;
88
- const range = options.range || selection.getFirstRange();
89
- // Don't execute command if range is in non-editable place.
90
- if (!model.canEditAt(range)) {
91
- return;
92
- }
93
- const mentionText = options.text || mentionID;
94
- const mention = _addMentionAttributes({ _text: mentionText, id: mentionID }, mentionData);
95
- if (!mentionID.startsWith(options.marker)) {
96
- /**
97
- * The feed item ID must start with the marker character(s).
98
- *
99
- * Correct mention feed setting:
100
- *
101
- * ```ts
102
- * mentions: [
103
- * {
104
- * marker: '@',
105
- * feed: [ '@Ann', '@Barney', ... ]
106
- * }
107
- * ]
108
- * ```
109
- *
110
- * Incorrect mention feed setting:
111
- *
112
- * ```ts
113
- * mentions: [
114
- * {
115
- * marker: '@',
116
- * feed: [ 'Ann', 'Barney', ... ]
117
- * }
118
- * ]
119
- * ```
120
- *
121
- * See {@link module:mention/mentionconfig~MentionConfig}.
122
- *
123
- * @error mentioncommand-incorrect-id
124
- */
125
- throw new CKEditorError('mentioncommand-incorrect-id', this);
126
- }
127
- model.change(writer => {
128
- const currentAttributes = toMap(selection.getAttributes());
129
- const attributesWithMention = new Map(currentAttributes.entries());
130
- attributesWithMention.set('mention', mention);
131
- // Replace a range with the text with a mention.
132
- const insertionRange = model.insertContent(writer.createText(mentionText, attributesWithMention), range);
133
- const nodeBefore = insertionRange.start.nodeBefore;
134
- const nodeAfter = insertionRange.end.nodeAfter;
135
- const isFollowedByWhiteSpace = nodeAfter && nodeAfter.is('$text') && nodeAfter.data.startsWith(' ');
136
- let isInsertedInBrackets = false;
137
- if (nodeBefore && nodeAfter && nodeBefore.is('$text') && nodeAfter.is('$text')) {
138
- const precedingCharacter = nodeBefore.data.slice(-1);
139
- const isPrecededByOpeningBracket = precedingCharacter in BRACKET_PAIRS;
140
- const isFollowedByBracketClosure = isPrecededByOpeningBracket && nodeAfter.data.startsWith(BRACKET_PAIRS[precedingCharacter]);
141
- isInsertedInBrackets = isPrecededByOpeningBracket && isFollowedByBracketClosure;
142
- }
143
- // Don't add a white space if either of the following is true:
144
- // * there's already one after the mention;
145
- // * the mention was inserted in the empty matching brackets.
146
- // https://github.com/ckeditor/ckeditor5/issues/4651
147
- if (!isInsertedInBrackets && !isFollowedByWhiteSpace) {
148
- model.insertContent(writer.createText(' ', currentAttributes), range.start.getShiftedBy(mentionText.length));
149
- }
150
- });
151
- }
152
- }
@@ -1,5 +0,0 @@
1
- /**
2
- * @license Copyright (c) 2003-2026, 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 {};