2025-05-03 17:48:22 +03:00
|
|
|
import { Command, Mention, Plugin, Range, type Selectable } from "ckeditor5";
|
2024-11-09 14:09:50 +02:00
|
|
|
|
2025-05-03 17:48:22 +03:00
|
|
|
/**
|
|
|
|
* Overrides the actions taken by the Mentions plugin (triggered by `@` in the text editor, or `~` & `#` in the attribute editor):
|
|
|
|
*
|
|
|
|
* - Auto-completes attributes and relations in the attribute editor.
|
|
|
|
* - Triggers the modal to create notes.
|
|
|
|
* - Inserts a reference link when a mention is selected.
|
|
|
|
*/
|
2024-11-09 14:09:50 +02:00
|
|
|
export default class MentionCustomization extends Plugin {
|
2025-05-03 17:48:22 +03:00
|
|
|
|
|
|
|
static get requires() {
|
|
|
|
return [ Mention ];
|
|
|
|
}
|
|
|
|
|
2024-11-09 14:09:50 +02:00
|
|
|
afterInit() {
|
|
|
|
const editor = this.editor;
|
|
|
|
// override standard mention command (see https://github.com/ckeditor/ckeditor5/issues/6470)
|
|
|
|
editor.commands.add('mention', new CustomMentionCommand(editor));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-05-03 17:48:22 +03:00
|
|
|
interface MentionOpts {
|
|
|
|
mention: string | {
|
|
|
|
id: string;
|
|
|
|
[key: string]: unknown;
|
|
|
|
};
|
|
|
|
marker: string;
|
|
|
|
text?: string;
|
|
|
|
range?: Range;
|
|
|
|
}
|
|
|
|
|
|
|
|
interface MentionAttribute {
|
|
|
|
id: string;
|
|
|
|
action?: "create-note";
|
|
|
|
noteTitle: string;
|
|
|
|
notePath: string;
|
|
|
|
}
|
|
|
|
|
2024-11-09 14:09:50 +02:00
|
|
|
class CustomMentionCommand extends Command {
|
2025-05-03 17:48:22 +03:00
|
|
|
|
|
|
|
override execute(options: MentionOpts) {
|
2024-11-09 14:09:50 +02:00
|
|
|
const {model} = this.editor;
|
|
|
|
const {document} = model;
|
|
|
|
const {selection} = document;
|
2025-05-03 17:48:22 +03:00
|
|
|
const mention = options.mention as unknown as MentionAttribute;
|
|
|
|
const range = (options.range || selection.getFirstRange()) as Selectable;
|
2024-11-09 14:09:50 +02:00
|
|
|
|
|
|
|
if (mention.id.startsWith('#') || mention.id.startsWith('~')) {
|
|
|
|
model.change(writer => {
|
|
|
|
// Replace a range with the text with a mention.
|
|
|
|
model.insertContent( writer.createText( mention.id, {} ), range );
|
|
|
|
});
|
|
|
|
}
|
|
|
|
else if (mention.action === 'create-note') {
|
|
|
|
const editorEl = this.editor.editing.view.getDomRoot();
|
2025-05-03 17:48:22 +03:00
|
|
|
const component = glob.getComponentByEl<EditorComponent>(editorEl);
|
2024-11-09 14:09:50 +02:00
|
|
|
|
|
|
|
component.createNoteForReferenceLink(mention.noteTitle).then(notePath => {
|
|
|
|
this.insertReference(range, notePath);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
else {
|
2025-05-03 17:48:22 +03:00
|
|
|
this.insertReference(range, mention.notePath);
|
2024-11-09 14:09:50 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-05-03 17:48:22 +03:00
|
|
|
insertReference(range: Selectable, notePath: string) {
|
2024-11-09 14:09:50 +02:00
|
|
|
const {model} = this.editor;
|
|
|
|
|
|
|
|
model.change(writer => {
|
|
|
|
// override the selection or at least the beginning @ character
|
|
|
|
model.insertContent(writer.createText('', {}), range);
|
|
|
|
|
|
|
|
this.editor.execute('referenceLink', {href: '#' + notePath});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|