浏览代码

Introduce conversion.for( 'downcast' ).elementToElement() helper.

Maciej Gołaszewski 7 年之前
父节点
当前提交
8a84ac0646

+ 2 - 1
packages/ckeditor5-engine/src/conversion/conversion.js

@@ -100,7 +100,8 @@ export default class Conversion {
 
 		const group = {
 			name: options.name,
-			dispatchers: Array.isArray( options.dispatcher ) ? options.dispatcher : [ options.dispatcher ]
+			dispatchers: Array.isArray( options.dispatcher ) ? options.dispatcher : [ options.dispatcher ],
+			helpers: options.helpers
 		};
 
 		this._dispatchersGroups.set( options.name, group );

+ 62 - 33
packages/ckeditor5-engine/src/conversion/downcast-converters.js

@@ -36,10 +36,10 @@ import { cloneDeep } from 'lodash-es';
  *			}
  *		} );
  *
- * 		downcastElementToElement( {
- * 			model: 'heading',
- * 			view: ( modelElement, viewWriter ) => viewWriter.createContainerElement( 'h' + modelElement.getAttribute( 'level' ) )
- * 		} );
+ *		downcastElementToElement( {
+ *			model: 'heading',
+ *			view: ( modelElement, viewWriter ) => viewWriter.createContainerElement( 'h' + modelElement.getAttribute( 'level' ) )
+ *		} );
  *
  * See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter
  * to the conversion process.
@@ -100,12 +100,12 @@ export function downcastElementToElement( config ) {
  *			}
  *		} );
  *
- * 		downcastAttributeToElement( {
- * 			model: 'bold',
- * 			view: ( modelAttributeValue, viewWriter ) => {
- * 				return viewWriter.createAttributeElement( 'span', { style: 'font-weight:' + modelAttributeValue } );
- * 			}
- * 		} );
+ *		downcastAttributeToElement( {
+ *			model: 'bold',
+ *				view: ( modelAttributeValue, viewWriter ) => {
+ *				return viewWriter.createAttributeElement( 'span', { style: 'font-weight:' + modelAttributeValue } );
+ *			}
+ *		} );
  *
  *		downcastAttributeToElement( {
  *			model: {
@@ -255,12 +255,12 @@ export function downcastAttributeToAttribute( config ) {
  *			}
  *		} );
  *
- * 		downcastMarkerToElement( {
- * 			model: 'search',
- * 			view: ( markerData, viewWriter ) => {
- *	 			return viewWriter.createUIElement( 'span', { 'data-marker': 'search', 'data-start': markerData.isOpening } );
- * 			}
- * 		} );
+ *		downcastMarkerToElement( {
+ *			model: 'search',
+ *			view: ( markerData, viewWriter ) => {
+ *			return viewWriter.createUIElement( 'span', { 'data-marker': 'search', 'data-start': markerData.isOpening } );
+ *			}
+ *		} );
  *
  * If a function is passed as the `config.view` parameter, it will be used to generate both boundary elements. The function
  * receives the `data` object as a parameter and should return an instance of the
@@ -314,17 +314,17 @@ export function downcastMarkerToElement( config ) {
  *
  *		downcastMarkerToHighlight( { model: 'comment', view: { classes: 'new-comment' }, converterPriority: 'high' } );
  *
- * 		downcastMarkerToHighlight( {
- * 			model: 'comment',
- * 			view: data => {
- * 				// Assuming that the marker name is in a form of comment:commentType.
- *	 			const commentType = data.markerName.split( ':' )[ 1 ];
+ *		downcastMarkerToHighlight( {
+ *			model: 'comment',
+ *			view: data => {
+ *				// Assuming that the marker name is in a form of comment:commentType.
+ *				const commentType = data.markerName.split( ':' )[ 1 ];
  *
- *	 			return {
- *	 				classes: [ 'comment', 'comment-' + commentType ]
- *	 			};
- * 			}
- * 		} );
+ *				return {
+ *					classes: [ 'comment', 'comment-' + commentType ]
+ *				};
+ *			}
+ *		} );
  *
  * If a function is passed as the `config.view` parameter, it will be used to generate the highlight descriptor. The function
  * receives the `data` object as a parameter and should return a
@@ -1107,13 +1107,42 @@ export function createViewElementFromHighlightDescriptor( descriptor ) {
 /**
  * Downcast conversion helper functions.
  *
- * @typedef {Object} DowncastHelpers
+ * @interface module:engine/conversion/downcast-converters~DowncastHelpers
  */
 export const helpers = {
-	elementToElement: downcastElementToElement,
-	attributeToElement: downcastAttributeToElement,
-	attributeToAttribute: downcastAttributeToAttribute,
-	markerToElement: downcastMarkerToElement,
-	markerToHighlight: downcastMarkerToHighlight,
-	createViewElementFromHighlightDescriptor
+	/**
+	 * Model element to view element conversion helper.
+	 *
+	 * This conversion results in creating a view element. For example, model `<paragraph>Foo</paragraph>` becomes `<p>Foo</p>` in the view.
+	 *
+	 *		editor.conversion.for( 'downcast' ).elementToElement( { model: 'paragraph', view: 'p' } );
+	 *
+	 *		editor.conversion.for( 'downcast' ).elementToElement( { model: 'paragraph', view: 'div', converterPriority: 'high' } );
+	 *
+	 *		editor.conversion.for( 'downcast' ).elementToElement( {
+	 *			model: 'fancyParagraph',
+	 *			view: {
+	 *				name: 'p',
+	 *				classes: 'fancy'
+	 *			}
+	 *		} );
+	 *
+	 *		editor.conversion.for( 'downcast' ).elementToElement( {
+	 *			model: 'heading',
+	 *			view: ( modelElement, viewWriter ) => viewWriter.createContainerElement( 'h' + modelElement.getAttribute( 'level' ) )
+	 *		} );
+	 *
+	 * See {@link module:engine/conversion/conversion~Conversion#for `conversion.for()`} to learn how to add a converter
+	 * to the conversion process.
+	 *
+	 * @method #elementToElement
+	 * @param {Object} config Conversion configuration.
+	 * @param {String} config.model The name of the model element to convert.
+	 * @param {module:engine/view/elementdefinition~ElementDefinition|Function} config.view A view element definition or a function
+	 * that takes the model element and {@link module:engine/view/downcastwriter~DowncastWriter view downcast writer}
+	 * as parameters and returns a view container element.
+	 */
+	elementToElement( config ) {
+		return this.add( downcastElementToElement( config ) );
+	}
 };

+ 20 - 3
packages/ckeditor5-engine/tests/conversion/conversion.js

@@ -14,8 +14,9 @@ import EditingController from '../../src/controller/editingcontroller';
 
 import Model from '../../src/model/model';
 
-import { stringify as viewStringify, parse as viewParse } from '../../src/dev-utils/view';
-import { stringify as modelStringify } from '../../src/dev-utils/model';
+import { parse as viewParse, stringify as viewStringify } from '../../src/dev-utils/view';
+import { setData, stringify as modelStringify } from '../../src/dev-utils/model';
+import { helpers as downcastHelpers } from '../../src/conversion/downcast-converters';
 
 describe( 'Conversion', () => {
 	let conversion, dispA, dispB;
@@ -114,7 +115,7 @@ describe( 'Conversion', () => {
 
 			conversion = new Conversion();
 			conversion.register( { name: 'upcast', dispatcher: [ viewDispatcher ] } );
-			conversion.register( { name: 'downcast', dispatcher: [ controller.downcastDispatcher ] } );
+			conversion.register( { name: 'downcast', dispatcher: [ controller.downcastDispatcher ], helpers: downcastHelpers } );
 		} );
 
 		describe( 'elementToElement', () => {
@@ -627,6 +628,22 @@ describe( 'Conversion', () => {
 			} );
 		} );
 
+		describe( 'for( \'downcast\' )', () => {
+			describe( 'elementToElement()', () => {
+				it( 'adds downcast converter', () => {
+					conversion.for( 'downcast' ).elementToElement( { model: 'paragraph', view: 'p' } );
+
+					testDowncast( '<paragraph>foo</paragraph>', '<p>foo</p>' );
+				} );
+			} );
+		} );
+
+		function testDowncast( input, expectedView ) {
+			setData( model, input );
+
+			expect( viewStringify( viewRoot, null, { ignoreRoot: true } ) ).to.equal( expectedView );
+		}
+
 		function test( input, expectedModel, expectedView = null ) {
 			loadData( input );