editor_advanced_image-8.x-2.x-dev/js/ckeditor5_plugins/editorAdvancedImage/src/EditorAdvancedImageEditing.js
js/ckeditor5_plugins/editorAdvancedImage/src/EditorAdvancedImageEditing.js
/** * @module editor_advanced_image/editorAdvancedImage/EditorAdvancedImageCommand */ import { Plugin } from "ckeditor5/src/core"; import EditorAdvancedImageCommand from "./EditorAdvancedImageCommand"; /** * The Editor Advanced Image Editing plugin. * * Registers the `EditorAdvancedImage` command. * * @extends module:core/plugin~Plugin * * @internal */ export default class EditorAdvancedImageEditing extends Plugin { /** * @inheritdoc */ static get requires() { return ["ImageUtils"]; } /** * @inheritdoc */ static get pluginName() { return "EditorAdvancedImageEditing"; } init() { const editor = this.editor; // Get the Drupal Configurations. // @see \Drupal\editor_advanced_image\Plugin\CKEditor5Plugin\EditorAdvancedImage::getDynamicPluginConfig const options = editor.config.get(`editorAdvancedImageOptions`); this._defineSchema(); this._defineConverters(); // Declare our command. editor.commands.add( "EditorAdvancedImageCmd", new EditorAdvancedImageCommand(editor, options), ); } /** * Define Schema with allowed attributes that will automatically be used by * Drupal " Limit allowed HTML tags and correct faulty HTML". */ _defineSchema() { const { editor } = this; const { schema } = editor.model; if (schema.isRegistered("imageInline")) { schema.extend("imageInline", { allowAttributes: ["title", "class", "id"], }); } if (schema.isRegistered("imageBlock")) { schema.extend("imageBlock", { allowAttributes: ["title", "class", "id"], }); } } _defineConverters() { const { editor } = this; const { conversion } = this.editor; const { schema } = editor.model; // Upcast Converters: determine how existing HTML is interpreted by the // editor. These trigger when an editor instance loads. conversion.for("upcast").attributeToAttribute({ model: "title", view: "title", }); conversion.for("upcast").attributeToAttribute({ model: "id", view: "id", }); conversion.for("upcast").attributeToAttribute({ model: "class", view: "class", }); // Data Downcast Converters: converts stored model data into HTML. // These trigger when content is saved. conversion .for("downcast") // We can't use 'dataDowncast'.attributeToAttribute as we want to apply attributes on the <img> and // not the <figure> element. .add(modelAttributeToDataAttribute()); } } /** * Generates a callback that saves the attributes value to an attribute on * data downcast. * * @return {function} * Callback that binds an event to it's parameter. * * @private */ function modelAttributeToDataAttribute() { /** * Callback for the attribute:[title|class|id] event. * * Saves the [Title|Class|ID] value to the corresponding attribute. * * @type {converterHandler} */ function converter(event, data, conversionApi) { const { item, attributeKey } = data; const { consumable, writer } = conversionApi; if (!consumable.consume(item, event.name)) { return; } const viewElement = conversionApi.mapper.toViewElement(item); const imageInFigure = Array.from(viewElement.getChildren()).find( (child) => child.name === "img", ); writer.setAttribute( attributeKey, data.attributeNewValue, imageInFigure || viewElement, ); } /** * When the callback must be called. */ return (dispatcher) => { dispatcher.on("attribute:title", converter); dispatcher.on("attribute:class", converter); dispatcher.on("attribute:id", converter); }; }