Sfoglia il codice sorgente

Changed format of data returned by DataController.

Oskar Wróbel 9 anni fa
parent
commit
39a0ff49ff

+ 22 - 29
packages/ckeditor5-engine/src/controller/datacontroller.js

@@ -22,6 +22,7 @@ import ViewDocumentFragment from '../view/documentfragment';
 
 import ModelRange from '../model/range';
 import ModelPosition from '../model/position';
+import ModelDocumentFragment from '../model/documentfragment';
 
 import insertContent from './insertcontent';
 import deleteContent from './deletecontent';
@@ -198,28 +199,10 @@ export default class DataController {
 			this.model.selection.removeAllRanges();
 			this.model.selection.clearAttributes();
 
-			// Parse data to model and extract markers from parsed document fragment.
-			const { modelItem, markersData } = this.parse( data );
-
 			// Initial batch should be ignored by features like undo, etc.
-			const batch = this.model.batch( 'transparent' );
-
-			// Replace current editor data by the new one.
-			batch
+			this.model.batch( 'transparent' )
 				.remove( ModelRange.createIn( modelRoot ) )
-				.insert( ModelPosition.createAt( modelRoot, 0 ), modelItem );
-
-			// Add markers to the document.
-			for ( const marker of markersData ) {
-				const markerName = marker[ 0 ];
-				const markerPositionData = marker[ 1 ];
-				const range = new ModelRange(
-					new ModelPosition( modelRoot, markerPositionData.startPath ),
-					markerPositionData.endPath ? new ModelPosition( modelRoot, markerPositionData.endPath ) : null
-				);
-
-				batch.setMarker( markerName, range );
-			}
+				.insert( ModelPosition.createAt( modelRoot, 0 ), this.parse( data ) );
 		} );
 	}
 
@@ -231,7 +214,7 @@ export default class DataController {
 	 * @param {String} data Data to parse.
 	 * @param {String} [context='$root'] Base context in which the view will be converted to the model. See:
 	 * {@link module:engine/conversion/viewconversiondispatcher~ViewConversionDispatcher#convert}.
-	 * @returns {engine/controller/datacontroller~ParsedModelData} Result of parsing view to model.
+	 * @returns {engine/model/documentfragment~DocumentFragment} Model DocumentFragment as a result of view parsing.
 	 */
 	parse( data, context = '$root' ) {
 		// data -> view
@@ -242,7 +225,8 @@ export default class DataController {
 	}
 
 	/**
-	 * Returns result of the given {@link module:engine/view/element~Element view element} or
+	 * Returns wrapped by {engine/model/documentfragment~DocumentFragment} result of the given
+	 * {@link module:engine/view/element~Element view element} or
 	 * {@link module:engine/view/documentfragment~DocumentFragment view document fragment} converted by the
 	 * {@link #viewToModel view to model converters}.
 	 *
@@ -250,15 +234,24 @@ export default class DataController {
 	 * Element or document fragment which content will be converted.
 	 * @param {String} [context='$root'] Base context in which the view will be converted to the model. See:
 	 * {@link module:engine/conversion/viewconversiondispatcher~ViewConversionDispatcher#convert}.
-	 * @returns {engine/controller/datacontroller~ParsedModelData} Result of parsing view to model.
+	 * @returns {engine/model/documentfragment~DocumentFragment} View item converted to Model DocumentFragment.
 	 */
 	toModel( viewElementOrFragment, context = '$root' ) {
-		const conversionData = this.viewToModel.convert( viewElementOrFragment, { context: [ context ] } );
+		const { conversionResult, markers } = this.viewToModel.convert( viewElementOrFragment, { context: [ context ] } );
+		let documentFragment;
+
+		if ( !conversionResult.is( 'documentFragment' ) ) {
+			documentFragment = new ModelDocumentFragment( [ conversionResult ] );
+		} else {
+			documentFragment = conversionResult;
+		}
+
+		// Set markers to the documentFragment.
+		for ( const marker of markers ) {
+			documentFragment.markers.set( marker[ 0 ], marker[ 1 ] );
+		}
 
-		return {
-			modelItem: conversionData.conversionResult,
-			markersData: conversionData.markersData
-		};
+		return documentFragment;
 	}
 
 	/**
@@ -334,7 +327,7 @@ mix( DataController, EmitterMixin );
  * @typedef {Object} {engine/controller/datacontroller~ParsedModelData}
  * @property {module:engine/model/documentfragment~DocumentFragment|module:engine/model/node~Node} modelItem
  * Fragment of parsed model.
- * @property {Map} markersData List of parsed marker stamps in format [ 'markerName', { startPath: [ 1, 1 ], endPath: [ 1, 3 ] } ]
+ * @property {Map<String, module:engine/model/range~Range>} markers List of parsed marker stamps.
  */
 
 /**

+ 53 - 69
packages/ckeditor5-engine/tests/controller/datacontroller.js

@@ -11,12 +11,14 @@ import buildViewConverter  from '../../src/conversion/buildviewconverter';
 import buildModelConverter  from '../../src/conversion/buildmodelconverter';
 
 import ModelDocumentFragment from '../../src/model/documentfragment';
-import ModelElement from '../../src/model/element';
 import ModelText from '../../src/model/text';
 import ModelSelection from '../../src/model/selection';
 import ModelRange from '../../src/model/range';
 
 import ViewDocumentFragment from '../../src/view/documentfragment';
+import ViewContainerElement from '../../src/view/containerelement';
+import ViewAttributeElement from '../../src/view/attributeelement';
+import ViewText from '../../src/view/text';
 
 import { getData, setData, stringify, parse as parseModel } from '../../src/dev-utils/model';
 import { parse as parseView } from '../../src/dev-utils/view';
@@ -123,9 +125,10 @@ describe( 'DataController', () => {
 	describe( 'parse', () => {
 		it( 'should set text', () => {
 			schema.allow( { name: '$text', inside: '$root' } );
-			const { modelItem } = data.parse( '<p>foo<b>bar</b></p>' );
+			const model = data.parse( '<p>foo<b>bar</b></p>' );
 
-			expect( stringify( modelItem ) ).to.equal( 'foobar' );
+			expect( model ).to.instanceof( ModelDocumentFragment );
+			expect( stringify( model ) ).to.equal( 'foobar' );
 		} );
 
 		it( 'should set paragraph', () => {
@@ -133,9 +136,10 @@ describe( 'DataController', () => {
 
 			buildViewConverter().for( data.viewToModel ).fromElement( 'p' ).toElement( 'paragraph' );
 
-			const { modelItem } = data.parse( '<p>foo<b>bar</b></p>' );
+			const model = data.parse( '<p>foo<b>bar</b></p>' );
 
-			expect( stringify( modelItem ) ).to.equal( '<paragraph>foobar</paragraph>' );
+			expect( model ).to.instanceof( ModelDocumentFragment );
+			expect( stringify( model ) ).to.equal( '<paragraph>foobar</paragraph>' );
 		} );
 
 		it( 'should set two paragraphs', () => {
@@ -143,10 +147,10 @@ describe( 'DataController', () => {
 
 			buildViewConverter().for( data.viewToModel ).fromElement( 'p' ).toElement( 'paragraph' );
 
-			const { modelItem } = data.parse( '<p>foo</p><p>bar</p>' );
+			const model = data.parse( '<p>foo</p><p>bar</p>' );
 
-			expect( stringify( modelItem ) ).to.equal(
-				'<paragraph>foo</paragraph><paragraph>bar</paragraph>' );
+			expect( model ).to.instanceof( ModelDocumentFragment );
+			expect( stringify( model ) ).to.equal( '<paragraph>foo</paragraph><paragraph>bar</paragraph>' );
 		} );
 
 		it( 'should set paragraphs with bold', () => {
@@ -156,35 +160,22 @@ describe( 'DataController', () => {
 			buildViewConverter().for( data.viewToModel ).fromElement( 'p' ).toElement( 'paragraph' );
 			buildViewConverter().for( data.viewToModel ).fromElement( 'b' ).toAttribute( 'bold', true );
 
-			const { modelItem } = data.parse( '<p>foo<b>bar</b></p>' );
+			const model = data.parse( '<p>foo<b>bar</b></p>' );
 
-			expect( stringify( modelItem ) ).to.equal(
-				'<paragraph>foo<$text bold="true">bar</$text></paragraph>' );
-		} );
-
-		it( 'should return markers data', () => {
-			schema.registerItem( 'paragraph', '$block' );
-
-			buildViewConverter().for( data.viewToModel ).fromElement( 'p' ).toElement( 'paragraph' );
-			buildViewConverter().for( data.viewToModel ).fromElement( 'marker' ).toMarker();
-
-			const { markersData } = data.parse( '<p>f<marker data-name="search"></marker>oob<marker data-name="search"></marker>ar</p>' );
-
-			expect( markersData ).to.instanceof( Map );
-			expect( markersData.size ).to.equal( 1 );
-			expect( markersData.get( 'search'  ) ).to.deep.equal( { startPath: [ 0, 1 ], endPath: [ 0, 4 ] } );
+			expect( model ).to.instanceof( ModelDocumentFragment );
+			expect( stringify( model ) ).to.equal( '<paragraph>foo<$text bold="true">bar</$text></paragraph>' );
 		} );
 
 		it( 'should parse in the root context by default', () => {
-			const { modelItem } = data.parse( 'foo' );
+			const model = data.parse( 'foo' );
 
-			expect( stringify( modelItem ) ).to.equal( '' );
+			expect( stringify( model ) ).to.equal( '' );
 		} );
 
 		it( 'should accept parsing context', () => {
-			const { modelItem } = data.parse( 'foo', '$block' );
+			const model = data.parse( 'foo', '$block' );
 
-			expect( stringify( modelItem ) ).to.equal( 'foo' );
+			expect( stringify( model ) ).to.equal( 'foo' );
 		} );
 	} );
 
@@ -197,30 +188,50 @@ describe( 'DataController', () => {
 
 		it( 'should convert content of an element #1', () => {
 			const viewElement = parseView( '<p>foo</p>' );
-			const { modelItem } = data.toModel( viewElement );
+			const model = data.toModel( viewElement );
 
-			expect( modelItem ).to.be.instanceOf( ModelElement );
-			expect( stringify( modelItem ) ).to.equal( '<paragraph>foo</paragraph>' );
+			expect( model ).to.instanceof( ModelDocumentFragment );
+			expect( stringify( model ) ).to.equal( '<paragraph>foo</paragraph>' );
 		} );
 
 		it( 'should convert content of an element #2', () => {
 			const viewFragment = parseView( '<p>foo</p><p>bar</p>' );
-			const { modelItem } = data.toModel( viewFragment );
+			const model = data.toModel( viewFragment );
 
-			expect( modelItem ).to.be.instanceOf( ModelDocumentFragment );
-			expect( stringify( modelItem ) ).to.equal( '<paragraph>foo</paragraph><paragraph>bar</paragraph>' );
+			expect( model ).to.be.instanceOf( ModelDocumentFragment );
+			expect( stringify( model ) ).to.equal( '<paragraph>foo</paragraph><paragraph>bar</paragraph>' );
 		} );
 
 		it( 'should convert marker stamps', () => {
-			const viewElement = parseView( '<p>f<marker data-name="search"></marker>o<marker data-name="search"></marker>o</p>' );
+			buildViewConverter().for( data.viewToModel ).fromElement( 'p' ).toElement( 'paragraph' );
+			buildViewConverter().for( data.viewToModel ).fromElement( 'm' ).toMarker();
 
-			buildViewConverter().for( data.viewToModel ).fromElement( 'marker' ).toMarker();
+			const viewFragment = new ViewDocumentFragment( [
+				new ViewContainerElement( 'p', null, [
+					new ViewText( 'Fo' ),
+					new ViewAttributeElement( 'm', { 'data-name': 'search' } ),
+					new ViewText( 'o ba' ),
+					new ViewAttributeElement( 'm', { 'data-name': 'comment' } ),
+					new ViewText( 'r bi' ),
+					new ViewAttributeElement( 'm', { 'data-name': 'search' } ),
+					new ViewText( 'z' )
+				] )
+			] );
 
-			const { markersData } = data.toModel( viewElement );
+			const model = data.toModel( viewFragment );
 
-			expect( markersData ).to.instanceof( Map );
-			expect( markersData.size ).to.equal( 1 );
-			expect( markersData.get( 'search'  ) ).to.deep.equal( { startPath: [ 1 ], endPath: [ 2 ] } );
+			expect( model ).instanceof( ModelDocumentFragment );
+			expect( model.markers.size ).to.equal( 2 );
+
+			const paragraph = model.getChild( 0 );
+			const commentMarkerRange = ModelRange.createFromParentsAndOffsets( paragraph, 6, paragraph, 6 );
+			const searchMarkerRange = ModelRange.createFromParentsAndOffsets( paragraph, 2, paragraph, 10 );
+
+			expect( model.markers.get( 'comment' ) ).to.instanceof( ModelRange );
+			expect( model.markers.get( 'comment' ).isEqual( commentMarkerRange ) ).to.true;
+
+			expect( model.markers.get( 'search' ) ).to.instanceof( ModelRange );
+			expect( model.markers.get( 'search' ).isEqual( searchMarkerRange ) ).to.true;
 		} );
 
 		it( 'should accept parsing context', () => {
@@ -232,10 +243,10 @@ describe( 'DataController', () => {
 			const viewFragment = new ViewDocumentFragment( [ parseView( 'foo' ) ] );
 
 			// Model fragment in root.
-			expect( stringify( data.toModel( viewFragment ).modelItem ) ).to.equal( '' );
+			expect( stringify( data.toModel( viewFragment ) ) ).to.equal( '' );
 
 			// Model fragment in inline root.
-			expect( stringify( data.toModel( viewFragment, 'inlineRoot' ).modelItem ) ).to.equal( 'foo' );
+			expect( stringify( data.toModel( viewFragment, 'inlineRoot' ) ) ).to.equal( 'foo' );
 		} );
 	} );
 
@@ -247,33 +258,6 @@ describe( 'DataController', () => {
 			expect( getData( modelDocument, { withoutSelection: true } ) ).to.equal( 'foo' );
 		} );
 
-		it( 'should set markers to `modelDocument#markers` collection', () => {
-			modelDocument.schema.registerItem( 'paragraph', '$block' );
-			buildViewConverter().for( data.viewToModel ).fromElement( 'p' ).toElement( 'paragraph' );
-			buildViewConverter().for( data.viewToModel ).fromElement( 'm' ).toMarker();
-
-			data.set(
-				'<p>' +
-					'Fo' +
-					'<m data-name="search"></m>' +
-					'o ba' +
-					'<m data-name="comment"></m>' +
-					'r bi' +
-					'<m data-name="search"></m>' +
-					'z' +
-				'</p>'
-			);
-
-			expect( Array.from( modelDocument.markers ).length ).to.equal( 2 );
-
-			const paragraph = modelDocument.getRoot().getChild( 0 );
-			const commentMarkerRange = ModelRange.createFromParentsAndOffsets( paragraph, 6, paragraph, 6 );
-			const searchMarkerRange = ModelRange.createFromParentsAndOffsets( paragraph, 2, paragraph, 10 );
-
-			expect( modelDocument.markers.get( 'comment' ).getRange().isEqual( commentMarkerRange ) ).to.true;
-			expect( modelDocument.markers.get( 'search' ).getRange().isEqual( searchMarkerRange ) ).to.true;
-		} );
-
 		it( 'should create a batch', () => {
 			schema.allow( { name: '$text', inside: '$root' } );
 			data.set( 'foo' );