@ckeditor/ckeditor5-image
Version:
Image feature for CKEditor 5.
80 lines (79 loc) • 3.25 kB
JavaScript
/**
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/
import { first } from 'ckeditor5/src/utils';
/**
* @module image/imagestyle/converters
*/
/**
* Returns a converter for the `imageStyle` attribute. It can be used for adding, changing and removing the attribute.
*
* @param styles An array containing available image style options.
* @returns A model-to-view attribute converter.
*/
export function modelToViewStyleAttribute(styles) {
return (evt, data, conversionApi) => {
if (!conversionApi.consumable.consume(data.item, evt.name)) {
return;
}
// Check if there is class name associated with given value.
const newStyle = getStyleDefinitionByName(data.attributeNewValue, styles);
const oldStyle = getStyleDefinitionByName(data.attributeOldValue, styles);
const viewElement = conversionApi.mapper.toViewElement(data.item);
const viewWriter = conversionApi.writer;
if (oldStyle) {
viewWriter.removeClass(oldStyle.className, viewElement);
}
if (newStyle) {
viewWriter.addClass(newStyle.className, viewElement);
}
};
}
/**
* Returns a view-to-model converter converting image CSS classes to a proper value in the model.
*
* @param styles Image style options for which the converter is created.
* @returns A view-to-model converter.
*/
export function viewToModelStyleAttribute(styles) {
// Convert only non–default styles.
const nonDefaultStyles = {
imageInline: styles.filter(style => !style.isDefault && style.modelElements.includes('imageInline')),
imageBlock: styles.filter(style => !style.isDefault && style.modelElements.includes('imageBlock'))
};
return (evt, data, conversionApi) => {
if (!data.modelRange) {
return;
}
const viewElement = data.viewItem;
const modelImageElement = first(data.modelRange.getItems());
// Run this converter only if an image has been found in the model.
// In some cases it may not be found (for example if we run this on a figure with different type than image).
if (!modelImageElement) {
return;
}
// ...and the `imageStyle` attribute is allowed for that element, otherwise stop conversion early.
if (!conversionApi.schema.checkAttribute(modelImageElement, 'imageStyle')) {
return;
}
// Convert styles one by one.
for (const style of nonDefaultStyles[modelImageElement.name]) {
// Try to consume class corresponding with the style.
if (conversionApi.consumable.consume(viewElement, { classes: style.className })) {
// And convert this style to model attribute.
conversionApi.writer.setAttribute('imageStyle', style.name, modelImageElement);
}
}
};
}
/**
* Returns the style with a given `name` from an array of styles.
*/
function getStyleDefinitionByName(name, styles) {
for (const style of styles) {
if (style.name === name) {
return style;
}
}
}