UNPKG

3.33 kBJavaScriptView Raw
1/**
2 * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.
3 * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
4 */
5
6import { first } from 'ckeditor5/src/utils';
7
8/**
9 * @module image/imagestyle/converters
10 */
11
12/**
13 * Returns a converter for the `imageStyle` attribute. It can be used for adding, changing and removing the attribute.
14 *
15 * @param {Array.<module:image/imagestyle~ImageStyleOptionDefinition>} styles
16 * An array containing available image style options.
17 * @returns {Function} A model-to-view attribute converter.
18 */
19export function modelToViewStyleAttribute( styles ) {
20 return ( evt, data, conversionApi ) => {
21 if ( !conversionApi.consumable.consume( data.item, evt.name ) ) {
22 return;
23 }
24
25 // Check if there is class name associated with given value.
26 const newStyle = getStyleDefinitionByName( data.attributeNewValue, styles );
27 const oldStyle = getStyleDefinitionByName( data.attributeOldValue, styles );
28
29 const viewElement = conversionApi.mapper.toViewElement( data.item );
30 const viewWriter = conversionApi.writer;
31
32 if ( oldStyle ) {
33 viewWriter.removeClass( oldStyle.className, viewElement );
34 }
35
36 if ( newStyle ) {
37 viewWriter.addClass( newStyle.className, viewElement );
38 }
39 };
40}
41
42/**
43 * Returns a view-to-model converter converting image CSS classes to a proper value in the model.
44 *
45 * @param {Array.<module:image/imagestyle~ImageStyleOptionDefinition>} styles
46 * Image style options for which the converter is created.
47 * @returns {Function} A view-to-model converter.
48 */
49export function viewToModelStyleAttribute( styles ) {
50 // Convert only non–default styles.
51 const nonDefaultStyles = {
52 imageInline: styles.filter( style => !style.isDefault && style.modelElements.includes( 'imageInline' ) ),
53 imageBlock: styles.filter( style => !style.isDefault && style.modelElements.includes( 'imageBlock' ) )
54 };
55
56 return ( evt, data, conversionApi ) => {
57 if ( !data.modelRange ) {
58 return;
59 }
60
61 const viewElement = data.viewItem;
62 const modelImageElement = first( data.modelRange.getItems() );
63
64 // Run this converter only if an image has been found in the model.
65 // In some cases it may not be found (for example if we run this on a figure with different type than image).
66 if ( !modelImageElement ) {
67 return;
68 }
69
70 // ...and the `imageStyle` attribute is allowed for that element, otherwise stop conversion early.
71 if ( !conversionApi.schema.checkAttribute( modelImageElement, 'imageStyle' ) ) {
72 return;
73 }
74
75 // Convert styles one by one.
76 for ( const style of nonDefaultStyles[ modelImageElement.name ] ) {
77 // Try to consume class corresponding with the style.
78 if ( conversionApi.consumable.consume( viewElement, { classes: style.className } ) ) {
79 // And convert this style to model attribute.
80 conversionApi.writer.setAttribute( 'imageStyle', style.name, modelImageElement );
81 }
82 }
83 };
84}
85
86// Returns the style with a given `name` from an array of styles.
87//
88// @param {String} name
89// @param {Array.<module:image/imagestyle~ImageStyleOptionDefinition> } styles
90// @returns {module:image/imagestyle~ImageStyleOptionDefinition|undefined}
91function getStyleDefinitionByName( name, styles ) {
92 for ( const style of styles ) {
93 if ( style.name === name ) {
94 return style;
95 }
96 }
97}