Przeglądaj źródła

Aligned ViewConversionBuilder to latest conversion API.

Oskar Wróbel 8 lat temu
rodzic
commit
8e1e5cb9df

+ 44 - 43
packages/ckeditor5-engine/src/conversion/buildviewconverter.js

@@ -270,12 +270,12 @@ class ViewConverterBuilder {
 	 */
 	toElement( element ) {
 		function eventCallbackGen( from ) {
-			return ( evt, data, consumable, conversionApi ) => {
+			return ( evt, data, conversionApi ) => {
 				const writer = conversionApi.writer;
 
 				// There is one callback for all patterns in the matcher.
 				// This will be usually just one pattern but we support matchers with many patterns too.
-				const matchAll = from.matcher.matchAll( data.input );
+				const matchAll = from.matcher.matchAll( data.viewItem );
 
 				// If there is no match, this callback should not do anything.
 				if ( !matchAll ) {
@@ -285,7 +285,7 @@ class ViewConverterBuilder {
 				// Now, for every match between matcher and actual element, we will try to consume the match.
 				for ( const match of matchAll ) {
 					// Create model element basing on creator function or element name.
-					const modelElement = element instanceof Function ? element( data.input, writer ) : writer.createElement( element );
+					const modelElement = element instanceof Function ? element( data.viewItem, writer ) : writer.createElement( element );
 
 					// Do not convert if element building function returned falsy value.
 					if ( !modelElement ) {
@@ -293,14 +293,14 @@ class ViewConverterBuilder {
 					}
 
 					// When element was already consumed then skip it.
-					if ( !consumable.test( data.input, from.consume || match.match ) ) {
+					if ( !conversionApi.consumable.test( data.viewItem, from.consume || match.match ) ) {
 						continue;
 					}
 
 					// Find allowed parent for element that we are going to insert.
 					// If current parent does not allow to insert element but one of the ancestors does
 					// then split nodes to allowed parent.
-					const splitResult = conversionApi.splitToAllowedParent( modelElement, data.position, conversionApi );
+					const splitResult = conversionApi.splitToAllowedParent( modelElement, data.cursorPosition );
 
 					// When there is no split result it means that we can't insert element to model tree, so let's skip it.
 					if ( !splitResult ) {
@@ -311,36 +311,35 @@ class ViewConverterBuilder {
 					conversionApi.writer.insert( modelElement, splitResult.position );
 
 					// Convert children and insert to element.
-					const childrenOutput = conversionApi.convertChildren( data.input, consumable, Position.createAt( modelElement ) );
+					const childrenResult = conversionApi.convertChildren( data.viewItem, Position.createAt( modelElement ) );
 
 					// Consume appropriate value from consumable values list.
-					consumable.consume( data.input, from.consume || match.match );
-
-					// Prepare conversion output range, we know that range will start before inserted element.
-					const output = new Range( Position.createBefore( modelElement ) );
-
-					// Now we need to check where the output should end.
+					conversionApi.consumable.consume( data.viewItem, from.consume || match.match );
+
+					// Set conversion result range.
+					data.modelRange = new Range(
+						// Range should start before inserted element
+						Position.createBefore( modelElement ),
+						// Should end after but we need to take into consideration that children could split our
+						// element, so we need to move range after parent of the last converted child.
+						// before: <allowed>[]</allowed>
+						// after: <allowed>[<converted><child></child></converted><child></child><converted>]</converted></allowed>
+						Position.createAfter( childrenResult.cursorPosition.parent )
+					);
 
-					// If we had to split parent to insert our element then we want to continue conversion
-					// inside split parent.
+					// Now we need to check where the cursorPosition should be.
+					// If we had to split parent to insert our element then we want to continue conversion inside split parent.
 					//
 					// before: <allowed><notAllowed>[]</notAllowed></allowed>
-					// after:  <allowed><notAllowed></notAllowed>[<converted></converted><notAllowed>]</notAllowed></allowed>
+					// after:  <allowed><notAllowed></notAllowed><converted></converted><notAllowed>[]</notAllowed></allowed>
 					if ( splitResult.cursorParent ) {
-						output.end = Position.createAt( splitResult.cursorParent );
+						data.cursorPosition = Position.createAt( splitResult.cursorParent );
 
-					// When element is converted on target position (without splitting) we need to move range
-					// after this element but we need to take into consideration that children could split our
-					// element, so we need to move range after parent of the last converted child.
-					//
-					// after: <allowed>[]</allowed>
-					// before: <allowed>[<converted><child></child></converted><child></child><converted>]</converted></allowed>
+					// Otherwise just continue after inserted element.
 					} else {
-						output.end = Position.createAfter( childrenOutput.end.parent );
+						data.cursorPosition = data.modelRange.end;
 					}
 
-					data.output = output;
-
 					// Prevent multiple conversion if there are other correct matches.
 					break;
 				}
@@ -369,10 +368,10 @@ class ViewConverterBuilder {
 	 */
 	toAttribute( keyOrCreator, value ) {
 		function eventCallbackGen( from ) {
-			return ( evt, data, consumable, conversionApi ) => {
+			return ( evt, data, conversionApi ) => {
 				// There is one callback for all patterns in the matcher.
 				// This will be usually just one pattern but we support matchers with many patterns too.
-				const matchAll = from.matcher.matchAll( data.input );
+				const matchAll = from.matcher.matchAll( data.viewItem );
 
 				// If there is no match, this callback should not do anything.
 				if ( !matchAll ) {
@@ -382,21 +381,22 @@ class ViewConverterBuilder {
 				// Now, for every match between matcher and actual element, we will try to consume the match.
 				for ( const match of matchAll ) {
 					// Try to consume appropriate values from consumable values list.
-					if ( !consumable.consume( data.input, from.consume || match.match ) ) {
+					if ( !conversionApi.consumable.consume( data.viewItem, from.consume || match.match ) ) {
 						continue;
 					}
 
-					// Since we are converting to attribute we need an output on which we will set the attribute.
-					// If the output is not created yet, we will create it.
-					if ( !data.output ) {
-						data.output = conversionApi.convertChildren( data.input, consumable, data.position );
+					// Since we are converting to attribute we need an range on which we will set the attribute.
+					// If the range is not created yet, we will create it.
+					if ( !data.modelRange ) {
+						// Convert children and set conversion result as a current data.
+						data = Object.assign( data, conversionApi.convertChildren( data.viewItem, data.cursorPosition ) );
 					}
 
 					// Use attribute creator function, if provided.
 					let attribute;
 
 					if ( keyOrCreator instanceof Function ) {
-						attribute = keyOrCreator( data.input );
+						attribute = keyOrCreator( data.viewItem );
 
 						if ( !attribute ) {
 							return;
@@ -404,12 +404,12 @@ class ViewConverterBuilder {
 					} else {
 						attribute = {
 							key: keyOrCreator,
-							value: value ? value : data.input.getAttribute( from.attributeKey )
+							value: value ? value : data.viewItem.getAttribute( from.attributeKey )
 						};
 					}
 
 					// Set attribute on each item in range according to Schema.
-					for ( const node of Array.from( data.output.getItems() ) ) {
+					for ( const node of Array.from( data.modelRange.getItems() ) ) {
 						if ( conversionApi.schema.checkAttribute( node, attribute.key ) ) {
 							conversionApi.writer.setAttribute( attribute.key, attribute.value, node );
 						}
@@ -459,12 +459,12 @@ class ViewConverterBuilder {
 	 */
 	toMarker( creator ) {
 		function eventCallbackGen( from ) {
-			return ( evt, data, consumable, conversionApi ) => {
+			return ( evt, data, conversionApi ) => {
 				const writer = conversionApi.writer;
 
 				// There is one callback for all patterns in the matcher.
 				// This will be usually just one pattern but we support matchers with many patterns too.
-				const matchAll = from.matcher.matchAll( data.input );
+				const matchAll = from.matcher.matchAll( data.viewItem );
 
 				// If there is no match, this callback should not do anything.
 				if ( !matchAll ) {
@@ -475,10 +475,10 @@ class ViewConverterBuilder {
 
 				// When creator is provided then create model element basing on creator function.
 				if ( creator instanceof Function ) {
-					modelElement = creator( data.input );
+					modelElement = creator( data.viewItem );
 				// When there is no creator then create model element basing on data from view element.
 				} else {
-					modelElement = writer.createElement( '$marker', { 'data-name': data.input.getAttribute( 'data-name' ) } );
+					modelElement = writer.createElement( '$marker', { 'data-name': data.viewItem.getAttribute( 'data-name' ) } );
 				}
 
 				// Check if model element is correct (has proper name and property).
@@ -491,18 +491,19 @@ class ViewConverterBuilder {
 				// Now, for every match between matcher and actual element, we will try to consume the match.
 				for ( const match of matchAll ) {
 					// Try to consume appropriate values from consumable values list.
-					if ( !consumable.consume( data.input, from.consume || match.match ) ) {
+					if ( !conversionApi.consumable.consume( data.viewItem, from.consume || match.match ) ) {
 						continue;
 					}
 
 					// Tmp fix because multiple matchers are not properly matched and consumed.
 					// See https://github.com/ckeditor/ckeditor5-engine/issues/1257.
-					if ( data.output ) {
+					if ( data.modelRange ) {
 						continue;
 					}
 
-					writer.insert( modelElement, data.position );
-					data.output = Range.createOn( modelElement );
+					writer.insert( modelElement, data.cursorPosition );
+					data.modelRange = Range.createOn( modelElement );
+					data.cursorPosition = data.modelRange.end;
 
 					// Prevent multiple conversion if there are other correct matches.
 					break;

+ 1 - 1
packages/ckeditor5-engine/tests/conversion/buildviewconverter.js

@@ -110,7 +110,7 @@ describe( 'View converter builder', () => {
 	it( 'should convert from view element to model element', () => {
 		buildViewConverter().for( dispatcher ).fromElement( 'p' ).toElement( 'paragraph' );
 
-		const conversionResult = dispatcher.convert( new ViewContainerElement( 'p', null, new ViewText( 'foo' ) ), context );
+		const conversionResult = dispatcher.convert( new ViewContainerElement( 'p', null, new ViewText( 'foo' ) ) );
 
 		expect( modelToString( conversionResult ) ).to.equal( '<paragraph>foo</paragraph>' );
 	} );