Browse Source

Other: Unify ViewElement converters for attribute and element.

Maciej Gołaszewski 8 năm trước cách đây
mục cha
commit
af2fcd9872

+ 11 - 55
packages/ckeditor5-engine/src/conversion/attributeconverters.js

@@ -5,74 +5,30 @@
 
 import AttributeElement from '../view/attributeelement';
 import buildModelConverter from './buildmodelconverter';
-import buildViewConverter from './buildviewconverter';
+import { defineConverter, parseDefinition } from './utils';
 
-export function viewToModelAttribute( attributeName, attributeValue, view, dispatchers ) {
-	const viewDefinitions = view.from ? view.from : [ view ];
+export function modelAttributeToView( attributeName, definition, dispatchers ) {
+	const { model: attributeValue, viewDefinition } = parseDefinition( definition );
 
-	for ( const viewDefinition of viewDefinitions ) {
-		const element = viewDefinition.name;
-		const classes = viewDefinition.class;
-		const styles = viewDefinition.style;
-
-		const pattern = { name: element };
-
-		if ( classes ) {
-			pattern.class = classes;
-		}
-
-		if ( styles ) {
-			pattern.style = styles;
-		}
-
-		buildViewConverter()
-			.for( ...dispatchers )
-			.from( pattern )
-			.toAttribute( () => ( {
-				key: attributeName,
-				value: attributeValue
-			} ) );
-	}
-}
-
-export function modelAttributeToView( attributeName, attributeValue, view, dispatchers ) {
 	buildModelConverter()
 		.for( ...dispatchers )
 		.fromAttribute( attributeName )
 		.toElement( value => {
-			// TODO: string vs numeric values
 			if ( value != attributeValue ) {
 				return;
 			}
 
-			const viewDefinition = view.to ? view.to : view;
-			// TODO: AttributeElement.fromDefinition() ?
-
-			const classes = viewDefinition.class;
-			const styles = viewDefinition.style;
-
-			const attributes = {};
-
-			// TODO: AttributeElement does no accept Array
-			if ( classes ) {
-				attributes.class = Array.isArray( classes ) ? classes.join( ' ' ) : classes;
-			}
-
-			// TODO: Attribute element does not accept Object
-			if ( styles ) {
-				attributes.style = typeof styles === 'string' ? styles : toStylesString( styles );
-			}
-
-			return new AttributeElement( viewDefinition.name, attributes );
+			return AttributeElement.fromViewDefinition( viewDefinition );
 		} );
 }
 
-function toStylesString( stylesObject ) {
-	const styles = [];
+export function viewToModelAttribute( attributeName, definition, dispatchers ) {
+	const { model: attributeValue, viewDefinitions } = parseDefinition( definition );
 
-	for ( const key in stylesObject ) {
-		styles.push( key + ':' + stylesObject[ key ] );
-	}
+	const converter = defineConverter( dispatchers, viewDefinitions );
 
-	return styles.join( ';' );
+	converter.toAttribute( () => ( {
+		key: attributeName,
+		value: attributeValue
+	} ) );
 }

+ 10 - 36
packages/ckeditor5-engine/src/conversion/elementconverters.js

@@ -4,49 +4,23 @@
  */
 
 import buildModelConverter from './buildmodelconverter';
-import buildViewConverter from './buildviewconverter';
 import ViewContainerElement from '../view/containerelement';
 
-export function modelElementToView( modelElement, view, dispatchers ) {
-	const viewDefinition = view.to ? view.to : view;
+import { defineConverter, parseDefinition } from './utils';
 
-	const attributes = {};
+export function modelElementToView( definition, dispatchers ) {
+	const { model: modelElement, viewDefinition } = parseDefinition( definition );
 
-	if ( viewDefinition.class ) {
-		attributes.class = viewDefinition.class;
-	}
-
-	if ( viewDefinition.style ) {
-		attributes.style = viewDefinition.style;
-	}
-
-	if ( viewDefinition.attribute ) {
-		attributes.attribute = viewDefinition.attribute;
-	}
-
-	buildModelConverter().for( ...dispatchers )
+	buildModelConverter()
+		.for( ...dispatchers )
 		.fromElement( modelElement )
-		.toElement( () => {
-			// TODO: create method from definition
-			return new ViewContainerElement( viewDefinition.name, attributes );
-		} );
+		.toElement( () => ViewContainerElement.fromViewDefinition( viewDefinition ) );
 }
 
-export function viewToModelElement( element, view, dispatchers ) {
-	// TODO: support multiple definitions
-	// { name: option.view.name }
-
-	const viewDefinitions = view.from ? view.from : [ view ];
-
-	const converter = buildViewConverter().for( ...dispatchers );
-
-	for ( const viewDefinition of viewDefinitions ) {
-		converter.from( viewDefinition );
+export function viewToModelElement( definition, dispatchers ) {
+	const { model: modelElement, viewDefinitions } = parseDefinition( definition );
 
-		if ( viewDefinition.priority ) {
-			converter.withPriority( viewDefinition.priority );
-		}
-	}
+	const converter = defineConverter( dispatchers, viewDefinitions );
 
-	converter.toElement( element );
+	converter.toElement( modelElement );
 }

+ 54 - 0
packages/ckeditor5-engine/src/conversion/utils.js

@@ -0,0 +1,54 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+import buildViewConverter from './buildviewconverter';
+
+export function parseDefinition( definition ) {
+	const model = definition.model;
+	const view = definition.view;
+	const viewDefinition = typeof view == 'string' ? { name: view } : view;
+
+	const viewDefinitions = definition.acceptsAlso ? definition.acceptsAlso : [];
+
+	viewDefinitions.push( viewDefinition );
+
+	return { model, viewDefinition, viewDefinitions };
+}
+
+export function definitionToPattern( viewDefinition ) {
+	const name = viewDefinition.name;
+	const classes = viewDefinition.class;
+	const styles = viewDefinition.style;
+	const attributes = viewDefinition.attribute;
+
+	const pattern = { name };
+
+	if ( classes ) {
+		pattern.class = classes;
+	}
+
+	if ( styles ) {
+		pattern.style = styles;
+	}
+
+	if ( attributes ) {
+		pattern.attribute = attributes;
+	}
+
+	return pattern;
+}
+
+export function defineConverter( dispatchers, viewDefinitions ) {
+	const converter = buildViewConverter().for( ...dispatchers );
+
+	for ( const viewDefinition of viewDefinitions ) {
+		converter.from( definitionToPattern( viewDefinition ) );
+
+		if ( viewDefinition.priority ) {
+			converter.withPriority( viewDefinition.priority );
+		}
+	}
+	return converter;
+}

+ 30 - 0
packages/ckeditor5-engine/src/view/element.js

@@ -712,6 +712,36 @@ export default class Element extends Node {
 			( attributes == '' ? '' : ` ${ attributes }` );
 	}
 
+	static fromViewDefinition( viewDefinition ) {
+		const attributes = {};
+
+		const classes = viewDefinition.class;
+
+		if ( viewDefinition.class ) {
+			attributes.class = Array.isArray( classes ) ? classes.join( ' ' ) : classes;
+		}
+
+		if ( viewDefinition.style ) {
+			attributes.style = toStylesString( viewDefinition.style );
+		}
+
+		if ( viewDefinition.attribute ) {
+			attributes.attribute = viewDefinition.attribute;
+		}
+
+		return new this( viewDefinition.name, attributes );
+
+		function toStylesString( stylesObject ) {
+			const styles = [];
+
+			for ( const key in stylesObject ) {
+				styles.push( key + ':' + stylesObject[ key ] );
+			}
+
+			return styles.join( ';' );
+		}
+	}
+
 	/**
 	 * Returns block {@link module:engine/view/filler filler} offset or `null` if block filler is not needed.
 	 *