import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; import {toWidget} from '@ckeditor/ckeditor5-widget/src/utils'; import Widget from '@ckeditor/ckeditor5-widget/src/widget'; import Command from '@ckeditor/ckeditor5-core/src/command'; import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview'; import noteIcon from './icons/note.svg'; export default class IncludeNote extends Plugin { static get requires() { return [ IncludeNoteEditing, IncludeNoteUI ]; } } class IncludeNoteUI extends Plugin { init() { const editor = this.editor; const t = editor.t; // The "includeNote" button must be registered among the UI components of the editor // to be displayed in the toolbar. editor.ui.componentFactory.add( 'includeNote', locale => { // The state of the button will be bound to the widget command. const command = editor.commands.get( 'insertIncludeNote' ); // The button will be an instance of ButtonView. const buttonView = new ButtonView( locale ); buttonView.set( { // The t() function helps localize the editor. All strings enclosed in t() can be // translated and change when the language of the editor changes. label: t( 'Include note' ), icon: noteIcon, tooltip: true } ); // Bind the state of the button to the command. buttonView.bind( 'isOn', 'isEnabled' ).to( command, 'value', 'isEnabled' ); // Execute the command when the button is clicked (executed). this.listenTo( buttonView, 'execute', () => editor.execute( 'insertIncludeNote' ) ); return buttonView; } ); } } class IncludeNoteEditing extends Plugin { static get requires() { return [ Widget ]; } init() { this._defineSchema(); this._defineConverters(); this.editor.commands.add( 'insertIncludeNote', new InsertIncludeNoteCommand( this.editor ) ); } _defineSchema() { const schema = this.editor.model.schema; schema.register( 'includeNote', { // Behaves like a self-contained object (e.g. an image). isObject: true, allowAttributes: [ 'noteId', 'boxSize' ], // Allow in places where other blocks are allowed (e.g. directly in the root). allowWhere: '$block' } ); } _defineConverters() { const editor = this.editor; const conversion = editor.conversion; // converters conversion.for( 'upcast' ).elementToElement( { model: ( viewElement, { writer: modelWriter } ) => { return modelWriter.createElement( 'includeNote', { noteId: viewElement.getAttribute( 'data-note-id' ), boxSize: viewElement.getAttribute( 'data-box-size' ), } ); }, view: { name: 'section', classes: 'include-note' } } ); conversion.for( 'dataDowncast' ).elementToElement( { model: 'includeNote', view: ( modelElement, { writer: viewWriter } ) => { // it would make sense here to downcast to