Jelajahi Sumber

Other: Initial implementation of unified converters from ViewElementDefinition interface.

Maciej Gołaszewski 8 tahun lalu
induk
melakukan
f5637c2a36

+ 78 - 0
packages/ckeditor5-engine/src/conversion/attributeconverters.js

@@ -0,0 +1,78 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+import AttributeElement from '../view/attributeelement';
+import buildModelConverter from './buildmodelconverter';
+import buildViewConverter from './buildviewconverter';
+
+export function viewToModelAttribute( attributeName, attributeValue, view, dispatchers ) {
+	const viewDefinitions = view.from ? view.from : [ view ];
+
+	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 );
+		} );
+}
+
+function toStylesString( stylesObject ) {
+	const styles = [];
+
+	for ( const key in stylesObject ) {
+		styles.push( key + ':' + stylesObject[ key ] );
+	}
+
+	return styles.join( ';' );
+}

+ 52 - 0
packages/ckeditor5-engine/src/conversion/elementconverters.js

@@ -0,0 +1,52 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+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;
+
+	const attributes = {};
+
+	if ( viewDefinition.class ) {
+		attributes.class = viewDefinition.class;
+	}
+
+	if ( viewDefinition.style ) {
+		attributes.style = viewDefinition.style;
+	}
+
+	if ( viewDefinition.attribute ) {
+		attributes.attribute = viewDefinition.attribute;
+	}
+
+	buildModelConverter().for( ...dispatchers )
+		.fromElement( modelElement )
+		.toElement( () => {
+			// TODO: create method from definition
+			return new ViewContainerElement( viewDefinition.name, attributes );
+		} );
+}
+
+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 );
+
+		if ( viewDefinition.priority ) {
+			converter.withPriority( viewDefinition.priority );
+		}
+	}
+
+	converter.toElement( element );
+}

+ 14 - 0
packages/ckeditor5-engine/src/view/matcher.js

@@ -378,3 +378,17 @@ function matchStyles( patterns, element ) {
 
 	return match;
 }
+
+/**
+ * @typedef {Object} @module engine/view/matcher~Pattern
+ *
+ * @param {String|RegExp} [name] Name or regular expression to match element's name.
+ * @param {Object} [attribute] Object with key-value pairs representing attributes to match. Each object key
+ * represents attribute name. Value under that key can be either a string or a regular expression and it will be
+ * used to match attribute value.
+ * @param {String|RegExp|Array} [class] Class name or array of class names to match. Each name can be
+ * provided in a form of string or regular expression.
+ * @param {Object} [style] Object with key-value pairs representing styles to match. Each object key
+ * represents style name. Value under that key can be either a string or a regular expression and it will be used
+ * to match style value.
+ */

+ 22 - 0
packages/ckeditor5-engine/src/view/viewelementdefinition.jsdoc

@@ -0,0 +1,22 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/**
+ * @module engine/view/viewelementdefinition
+ */
+
+/**
+ * An object defining view element used for defining elements for conversion.
+ *
+ * @typedef {Object} module:engine/view/viewelementdefinition~ViewElementDefinition
+ *
+ * @property {String} name View element attribute name.
+ * @property {String|Array.<String>} [class] Class name or array of class names to match. Each name can be
+ * provided in a form of string.
+ * @property {Object} [style] Object with key-value pairs representing styles to match. Each object key
+ * represents style name. Value under that key must be a string.
+ * @property {Object} [attribute] Object with key-value pairs representing attributes to match. Each object key
+ * represents attribute name. Value under that key must be a string.
+ */