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

Other: Initial support fo ViewElementDefinition interface.

Maciej Gołaszewski пре 8 година
родитељ
комит
994109832f

+ 125 - 70
packages/ckeditor5-font/src/fontsize/fontsizeediting.js

@@ -39,57 +39,15 @@ export default class FontSizeEditing extends Plugin {
 		const data = editor.data;
 		const data = editor.data;
 		const editing = editor.editing;
 		const editing = editor.editing;
 
 
+		// Covert view to model
 		for ( const item of this.configuredItems ) {
 		for ( const item of this.configuredItems ) {
-			const viewDefinition = item.view;
-			const element = viewDefinition.name;
-			const classes = viewDefinition.classes;
-			const styles = viewDefinition.styles;
-
-			const pattern = { name: element };
-
-			if ( classes ) {
-				pattern.class = classes;
-			}
-
-			if ( styles ) {
-				pattern.style = styles;
-			}
-
-			buildViewConverter()
-				.for( data.viewToModel )
-				.from( pattern )
-				.toAttribute( () => ( {
-					key: 'fontSize',
-					value: item.model
-				} ) );
+			viewToAttribute( item.view, [ data.viewToModel ], 'fontSize', item.model );
 		}
 		}
 
 
 		// Convert model to view
 		// Convert model to view
-		buildModelConverter().for( data.modelToView, editing.modelToView )
-			.fromAttribute( 'fontSize' )
-			.toElement( data => {
-				const definition = this._getDefinition( data );
-
-				if ( !definition ) {
-					return;
-				}
-
-				const viewDefinition = definition.view;
-				const classes = viewDefinition.classes;
-				const styles = viewDefinition.styles;
+		const items = this.configuredItems;
 
 
-				const attributes = {};
-
-				if ( classes ) {
-					attributes.class = Array.isArray( classes ) ? classes.join( ' ' ) : classes;
-				}
-
-				if ( styles ) {
-					attributes.style = typeof styles === 'string' ? styles : toStylesString( styles );
-				}
-
-				return new AttributeElement( viewDefinition.name, attributes );
-			} );
+		attributeToView( [ data.modelToView, editing.modelToView ], 'fontSize', items );
 	}
 	}
 
 
 	get configuredItems() {
 	get configuredItems() {
@@ -126,57 +84,39 @@ export default class FontSizeEditing extends Plugin {
 		// Temporary workaround. See https://github.com/ckeditor/ckeditor5/issues/477.
 		// Temporary workaround. See https://github.com/ckeditor/ckeditor5/issues/477.
 		editor.document.schema.allow( { name: '$inline', attributes: 'fontSize', inside: '$clipboardHolder' } );
 		editor.document.schema.allow( { name: '$inline', attributes: 'fontSize', inside: '$clipboardHolder' } );
 	}
 	}
-
-	_getDefinition( name ) {
-		const stringName = String( name );
-
-		for ( const item of this.configuredItems ) {
-			if ( item.model === stringName ) {
-				return item;
-			}
-		}
-	}
 }
 }
 
 
 const namedPresets = {
 const namedPresets = {
 	tiny: {
 	tiny: {
 		label: 'Tiny',
 		label: 'Tiny',
 		model: 'text-tiny',
 		model: 'text-tiny',
-		// stopValue: .7
-		// stopUnit: 'em'
 		view: {
 		view: {
 			name: 'span',
 			name: 'span',
-			classes: 'text-tiny'
+			class: 'text-tiny'
 		}
 		}
 	},
 	},
 	small: {
 	small: {
 		label: 'Small',
 		label: 'Small',
 		model: 'text-small',
 		model: 'text-small',
-		// stopValue: .85
-		// stopUnit: 'em',
 		view: {
 		view: {
 			name: 'span',
 			name: 'span',
-			classes: 'text-small'
+			class: 'text-small'
 		}
 		}
 	},
 	},
 	big: {
 	big: {
 		label: 'Big',
 		label: 'Big',
 		model: 'text-big',
 		model: 'text-big',
-		// stopValue: 1.4
-		// stopUnit: 'em',
 		view: {
 		view: {
 			name: 'span',
 			name: 'span',
-			classes: 'text-big'
+			class: 'text-big'
 		}
 		}
 	},
 	},
 	huge: {
 	huge: {
 		label: 'Huge',
 		label: 'Huge',
 		model: 'text-huge',
 		model: 'text-huge',
-		// stopValue: 1.8
-		// stopUnit: 'em',
 		view: {
 		view: {
 			name: 'span',
 			name: 'span',
-			classes: 'text-huge'
+			class: 'text-huge'
 		}
 		}
 	}
 	}
 };
 };
@@ -211,10 +151,9 @@ function generatePixelPreset( size ) {
 	return {
 	return {
 		label: sizeName,
 		label: sizeName,
 		model: sizeName,
 		model: sizeName,
-		stopValue: size,
 		view: {
 		view: {
 			name: 'span',
 			name: 'span',
-			styles: {
+			style: {
 				'font-size': `${ size }px`
 				'font-size': `${ size }px`
 			}
 			}
 		}
 		}
@@ -230,3 +169,119 @@ function toStylesString( stylesObject ) {
 
 
 	return styles.join( ';' );
 	return styles.join( ';' );
 }
 }
+
+function viewToAttribute( view, dispatchers, attributeName, attributeValue ) {
+	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
+			} ) );
+	}
+}
+
+function attributeToView( dispatchers, attributeName, items ) {
+	buildModelConverter()
+		.for( ...dispatchers )
+		.fromAttribute( attributeName )
+		.toElement( attributeValue => {
+			const definition = _getDefinition( attributeValue );
+
+			if ( !definition ) {
+				return;
+			}
+
+			const viewDefinition = definition.view.to ? definition.view.to : definition.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 _getDefinition( name ) {
+		const stringName = String( name );
+
+		for ( const item of items ) {
+			if ( item.model === stringName ) {
+				return item;
+			}
+		}
+	}
+}
+
+/**
+ * Font size option descriptor.
+ *
+ * @typedef {Object} module:font/fontsize/fontsizeediting~FontSizeOption
+ *
+ * @property {String} label TODO me
+ * @property {String} model TODO me
+ * @property {module:engine/view/viewelementdefinition~ViewElementDefinition} view View element configuration.
+ */
+
+/**
+ * The configuration of the heading feature. Introduced by the {@link module:font/fontsize/fontsizeediting~FontSizeEditing} feature.
+ *
+ * Read more in {@link module:font/fontsize/fontsizeediting~FontSizeConfig}.
+ *
+ * @member {module:font/fontsize/fontsizeediting~FontSizeConfig} module:core/editor/editorconfig~EditorConfig#fontSize
+ */
+
+/**
+ * The configuration of the font size feature.
+ * The option is used by the {@link module:font/fontsize/fontsizeediting~FontSizeEditing} feature.
+ *
+ *        ClassicEditor
+ *            .create( {
+ * 				fontSize: ... // Font size feature config.
+ *			} )
+ *            .then( ... )
+ *            .catch( ... );
+ *
+ * See {@link module:core/editor/editorconfig~EditorConfig all editor options}.
+ *
+ * @interface module:font/fontsize/fontsizeediting~FontSizeConfig
+ */
+
+/**
+ * Available font size options. Defined either as array of strings.
+ *
+ * The default value is
+ * TODO code
+ * which configures
+ *
+ * @member {Array.<String|Number|module:font/fontsize/fontsizeediting~FontSizeOption>}
+ *  module:font/fontsize/fontsizeediting~FontSizeConfig#items
+ */

+ 49 - 16
packages/ckeditor5-font/tests/fontsize/fontsizeediting.js

@@ -65,7 +65,7 @@ describe( 'FontSizeEditing', () => {
 				.create( {
 				.create( {
 					plugins: [ FontSizeEditing ],
 					plugins: [ FontSizeEditing ],
 					fontSize: {
 					fontSize: {
-						items: [ { label: 'My Size', model: 'my-size', view: { name: 'span', styles: 'font-size: 12em;' } } ]
+						items: [ { label: 'My Size', model: 'my-size', view: { name: 'span', style: 'font-size: 12em;' } } ]
 					}
 					}
 				} )
 				} )
 				.then( newEditor => {
 				.then( newEditor => {
@@ -77,7 +77,7 @@ describe( 'FontSizeEditing', () => {
 						{
 						{
 							label: 'My Size',
 							label: 'My Size',
 							model: 'my-size',
 							model: 'my-size',
-							view: { name: 'span', styles: 'font-size: 12em;' }
+							view: { name: 'span', style: 'font-size: 12em;' }
 						}
 						}
 					] );
 					] );
 				} );
 				} );
@@ -98,10 +98,10 @@ describe( 'FontSizeEditing', () => {
 						const plugin = editor.plugins.get( FontSizeEditing );
 						const plugin = editor.plugins.get( FontSizeEditing );
 
 
 						expect( plugin.configuredItems ).to.deep.equal( [
 						expect( plugin.configuredItems ).to.deep.equal( [
-							{ label: 'Tiny', model: 'text-tiny', view: { name: 'span', classes: 'text-tiny' } },
-							{ label: 'Small', model: 'text-small', view: { name: 'span', classes: 'text-small' } },
-							{ label: 'Big', model: 'text-big', view: { name: 'span', classes: 'text-big' } },
-							{ label: 'Huge', model: 'text-huge', view: { name: 'span', classes: 'text-huge' } }
+							{ label: 'Tiny', model: 'text-tiny', view: { name: 'span', class: 'text-tiny' } },
+							{ label: 'Small', model: 'text-small', view: { name: 'span', class: 'text-small' } },
+							{ label: 'Big', model: 'text-big', view: { name: 'span', class: 'text-big' } },
+							{ label: 'Huge', model: 'text-huge', view: { name: 'span', class: 'text-huge' } }
 						] );
 						] );
 					} );
 					} );
 			} );
 			} );
@@ -122,10 +122,10 @@ describe( 'FontSizeEditing', () => {
 						const plugin = editor.plugins.get( FontSizeEditing );
 						const plugin = editor.plugins.get( FontSizeEditing );
 
 
 						expect( plugin.configuredItems ).to.deep.equal( [
 						expect( plugin.configuredItems ).to.deep.equal( [
-							{ label: '10', model: '10', stopValue: 10, view: { name: 'span', styles: { 'font-size': '10px' } } },
-							{ label: '12', model: '12', stopValue: 12, view: { name: 'span', styles: { 'font-size': '12px' } } },
-							{ label: '14', model: '14', stopValue: 14, view: { name: 'span', styles: { 'font-size': '14px' } } },
-							{ label: '18', model: '18', stopValue: 18, view: { name: 'span', styles: { 'font-size': '18px' } } }
+							{ label: '10', model: '10', view: { name: 'span', style: { 'font-size': '10px' } } },
+							{ label: '12', model: '12', view: { name: 'span', style: { 'font-size': '12px' } } },
+							{ label: '14', model: '14', view: { name: 'span', style: { 'font-size': '14px' } } },
+							{ label: '18', model: '18', view: { name: 'span', style: { 'font-size': '18px' } } }
 						] );
 						] );
 					} );
 					} );
 			} );
 			} );
@@ -143,8 +143,8 @@ describe( 'FontSizeEditing', () => {
 							model: 'my',
 							model: 'my',
 							view: {
 							view: {
 								name: 'mark',
 								name: 'mark',
-								styles: 'font-size: 30px',
-								classes: 'my-style'
+								style: 'font-size: 30px',
+								class: 'my-style'
 							}
 							}
 						} ]
 						} ]
 					}
 					}
@@ -196,17 +196,30 @@ describe( 'FontSizeEditing', () => {
 								model: 'my',
 								model: 'my',
 								view: {
 								view: {
 									name: 'mark',
 									name: 'mark',
-									styles: { 'font-size': '30px' },
-									classes: 'my-style'
+									style: { 'font-size': '30px' },
+									class: 'my-style'
 								}
 								}
 							},
 							},
 							{
 							{
 								label: 'Big multiple classes',
 								label: 'Big multiple classes',
 								model: 'big-multiple',
 								model: 'big-multiple',
-								// TODO: define ViewElementConfigDefinition interface (wheter strings or arrays to use)?
 								view: {
 								view: {
 									name: 'span',
 									name: 'span',
-									classes: [ 'foo', 'foo-big' ]
+									class: [ 'foo', 'foo-big' ]
+								}
+							},
+							{
+								label: 'Hybrid',
+								model: 'complex',
+								view: {
+									to: {
+										name: 'span',
+										class: [ 'text-complex' ]
+									},
+									from: [
+										{ name: 'span', style: { 'font-size': '77em' } },
+										{ name: 'span', attribute: { 'data-size': '77em' } }
+									]
 								}
 								}
 							}
 							}
 						]
 						]
@@ -268,5 +281,25 @@ describe( 'FontSizeEditing', () => {
 
 
 			expect( editor.getData() ).to.equal( data );
 			expect( editor.getData() ).to.equal( data );
 		} );
 		} );
+
+		it( 'should convert from complex definitions', () => {
+			editor.setData(
+				'<p>f<span style="font-size: 77em;">o</span>o</p>' +
+				'<p>b<span data-size="77em">a</span>r</p>' +
+				'<p>b<span class="text-complex">a</span>z</p>'
+			);
+
+			expect( getModelData( doc ) ).to.equal(
+				'<paragraph>[]f<$text fontSize="complex">o</$text>o</paragraph>' +
+				'<paragraph>b<$text fontSize="complex">a</$text>r</paragraph>' +
+				'<paragraph>b<$text fontSize="complex">a</$text>z</paragraph>'
+			);
+
+			expect( editor.getData() ).to.equal(
+				'<p>f<span class="text-complex">o</span>o</p>' +
+				'<p>b<span class="text-complex">a</span>r</p>' +
+				'<p>b<span class="text-complex">a</span>z</p>'
+			);
+		} );
 	} );
 	} );
 } );
 } );