Преглед изворни кода

Fixed: `conversion.downcast-converters.downcastAttributeToElement` should let specify from what element the model attribute will be converted.

Szymon Cofalik пре 7 година
родитељ
комит
c3cde8daa1

+ 24 - 0
packages/ckeditor5-engine/src/conversion/conversion.js

@@ -224,6 +224,30 @@ export default class Conversion {
 	 *			}
 	 *		} );
 	 *
+	 *		// Use `config.model.name` to define conversion only from given node type, `$text` in this case.
+	 *		// The same attribute on different elements may be then handled by a different converter.
+	 *		conversion.attributeToElement( {
+	 *			model: {
+	 *				key: 'textDecoration',
+	 *				values: [ 'underline', 'lineThrough' ],
+	 *				name: '$text'
+	 *			},
+	 *			view: {
+	 *				underline: {
+	 *					name: 'span',
+	 *					style: {
+	 *						'text-decoration': 'underline'
+	 *					}
+	 *				},
+	 *				lineThrough: {
+	 *					name: 'span',
+	 *					style: {
+	 *						'text-decoration': 'line-through'
+	 *					}
+	 *				}
+	 *			}
+	 *		} );
+	 *
 	 *		// Use `upcastAlso` to define other view elements that should be also converted to `bold` attribute.
 	 *		conversion.attributeToElement( {
 	 *			model: 'bold',

+ 16 - 1
packages/ckeditor5-engine/src/conversion/downcast-converters.js

@@ -105,6 +105,16 @@ export function downcastElementToElement( config ) {
  * 			}
  * 		} );
  *
+ *		downcastAttributeToElement( {
+ *			model: {
+ *				key: 'color',
+ *				name: '$text'
+ *			},
+ *			view: ( modelAttributeValue, viewWriter ) => {
+ *				return viewWriter.createAttributeElement( 'span', { style: 'color:' + modelAttributeValue } );
+ *			}
+ *		} );
+ *
  * See {@link module:engine/conversion/conversion~Conversion#for} to learn how to add converter to conversion process.
  *
  * @param {Object} config Conversion configuration.
@@ -120,6 +130,11 @@ export function downcastAttributeToElement( config ) {
 	config = cloneDeep( config );
 
 	const modelKey = config.model.key ? config.model.key : config.model;
+	let eventName = 'attribute:' + modelKey;
+
+	if ( config.model.name ) {
+		eventName += ':' + config.model.name;
+	}
 
 	if ( config.model.values ) {
 		for ( const modelValue of config.model.values ) {
@@ -132,7 +147,7 @@ export function downcastAttributeToElement( config ) {
 	const elementCreator = _getFromAttributeCreator( config );
 
 	return dispatcher => {
-		dispatcher.on( 'attribute:' + modelKey, wrap( elementCreator ), { priority: config.priority || 'normal' } );
+		dispatcher.on( eventName, wrap( elementCreator ), { priority: config.priority || 'normal' } );
 	};
 }
 

+ 43 - 0
packages/ckeditor5-engine/tests/conversion/conversion.js

@@ -407,6 +407,49 @@ describe( 'Conversion', () => {
 					'<p>Foo bar</p>'
 				);
 			} );
+
+			it( 'config.model.name is given', () => {
+				schema.extend( '$text', {
+					allowAttributes: [ 'textDecoration' ]
+				} );
+
+				conversion.attributeToElement( {
+					model: {
+						key: 'textDecoration',
+						values: [ 'underline', 'lineThrough' ],
+						name: '$text'
+					},
+					view: {
+						underline: {
+							name: 'span',
+							style: {
+								'text-decoration': 'underline'
+							}
+						},
+						lineThrough: {
+							name: 'span',
+							style: {
+								'text-decoration': 'line-through'
+							}
+						}
+					}
+				} );
+
+				test(
+					'<p><span style="text-decoration:underline">Foo</span></p>',
+					'<paragraph><$text textDecoration="underline">Foo</$text></paragraph>'
+				);
+
+				test(
+					'<p><span style="text-decoration:line-through">Foo</span></p>',
+					'<paragraph><$text textDecoration="lineThrough">Foo</$text></paragraph>'
+				);
+
+				test(
+					'<p><span style="text-decoration:underline">Foo</span></p>',
+					'<paragraph><$text textDecoration="underline">Foo</$text></paragraph>'
+				);
+			} );
 		} );
 
 		describe( 'attributeToAttribute', () => {

+ 31 - 0
packages/ckeditor5-engine/tests/conversion/downcast-converters.js

@@ -209,6 +209,37 @@ describe( 'downcast-helpers', () => {
 
 			expectResult( '<span style="font-weight:500">foo</span>' );
 		} );
+
+		it( 'config.model.name is given', () => {
+			const helper = downcastAttributeToElement( {
+				model: {
+					key: 'color',
+					name: '$text'
+				},
+				view: ( modelAttributeValue, viewWriter ) => {
+					return viewWriter.createAttributeElement( 'span', { style: 'color:' + modelAttributeValue } );
+				}
+			} );
+
+			conversion.for( 'downcast' )
+				.add( helper )
+				.add( downcastElementToElement( {
+					model: 'smiley',
+					view: ( modelElement, viewWriter ) => {
+						return viewWriter.createEmptyElement( 'img', {
+							src: 'smile.jpg',
+							class: 'smiley'
+						} );
+					}
+				} ) );
+
+			model.change( writer => {
+				writer.insertText( 'foo', { color: '#FF0000' }, modelRoot, 0 );
+				writer.insertElement( 'smiley', { color: '#FF0000' }, modelRoot, 3 );
+			} );
+
+			expectResult( '<span style="color:#FF0000">foo</span><img class="smiley" src="smile.jpg"></img>' );
+		} );
 	} );
 
 	describe( 'downcastAttributeToAttribute', () => {