Browse Source

Returning parsed node or DocumentFragment in model utilities.

Szymon Kupś 9 years ago
parent
commit
9d6a45e94a

+ 18 - 4
packages/ckeditor5-engine/tests/_utils-tests/model.js

@@ -308,15 +308,15 @@ describe( 'model test utils', () => {
 		test( 'sets elements attributes', {
 			data: '<a foo=1 bar=true car="x y"><b x="y"></b></a>',
 			output: '<a bar=true car="x y" foo=1><b x="y"></b></a>',
-			check( root ) {
-				expect( root.getChild( 0 ).getAttribute( 'car' ) ).to.equal( 'x y' );
+			check( a ) {
+				expect( a.getAttribute( 'car' ) ).to.equal( 'x y' );
 			}
 		} );
 
 		test( 'sets complex attributes', {
 			data: '<a foo={"a":1,"b":"c"}></a>',
-			check( root ) {
-				expect( root.getChild( 0 ).getAttribute( 'foo' ) ).to.have.property( 'a', 1 );
+			check( a ) {
+				expect( a.getAttribute( 'foo' ) ).to.have.property( 'a', 1 );
 			}
 		} );
 
@@ -329,6 +329,20 @@ describe( 'model test utils', () => {
 			}
 		} );
 
+		test( 'returns single parsed element', {
+			data: '<paragraph></paragraph>',
+			check( p ) {
+				expect( p instanceof Element ).to.be.true;
+			}
+		} );
+
+		test( 'returns DocumentFragment for multiple parsed elements', {
+			data: '<paragraph></paragraph><paragraph></paragraph>',
+			check( fragment ) {
+				expect( fragment instanceof DocumentFragment ).to.be.true;
+			}
+		} );
+
 		it( 'throws when unexpected closing tag', () => {
 			expect( () => {
 				parse( '<a><b></a></b>' );

+ 22 - 10
packages/ckeditor5-engine/tests/_utils/model.js

@@ -83,7 +83,13 @@ export function stringify( node, selectionOrPositionOrRange = null ) {
 		document = node.document;
 	} else if ( node instanceof Element || node instanceof Text ) {
 		// If root is Element or Text - wrap it with DocumentFragment.
-		node = new DocumentFragment( node );
+
+		// If parent node is already a DocumentFragment - use it.
+		if ( node.parent instanceof DocumentFragment ) {
+			node = node.parent;
+		} else {
+			node = new DocumentFragment( node );
+		}
 	}
 
 	document = document || new Document();
@@ -136,17 +142,18 @@ export function stringify( node, selectionOrPositionOrRange = null ) {
  * and `selection` when selection ranges were included in data to parse.
  */
 export function parse( data, options = {} ) {
-	let document, root;
+	let root, selection;
 	let withSelection = false;
 	const rootName = options.rootName || 'main';
 
 	if ( options.document ) {
-		document = options.document;
+		const document = options.document;
 		root = document.getRoot( rootName );
 		root.removeChildren( 0, root.getChildCount() );
+		selection = document.selection;
 	} else {
-		document = new Document();
-		root = document.createRoot( '$root', rootName );
+		root = new DocumentFragment();
+		selection = new Selection();
 	}
 
 	const path = [];
@@ -189,8 +196,8 @@ export function parse( data, options = {} ) {
 
 		collapsedSelection( token ) {
 			withSelection = true;
-			document.selection.collapse( root, 'END' );
-			document.selection.setAttributesTo( token.attributes );
+			selection.collapse( root, 'END' );
+			selection.setAttributesTo( token.attributes );
 		},
 
 		selectionStart( token ) {
@@ -206,14 +213,14 @@ export function parse( data, options = {} ) {
 			withSelection = true;
 			selectionEnd = Position.createFromParentAndOffset( root, root.getChildCount() );
 
-			document.selection.setRanges(
+			selection.setRanges(
 				[ new Range( selectionStart, selectionEnd ) ],
 				selectionAttributes.backward
 			);
 
 			delete selectionAttributes.backward;
 
-			document.selection.setAttributesTo( selectionAttributes );
+			selection.setAttributesTo( selectionAttributes );
 		}
 	};
 
@@ -229,10 +236,15 @@ export function parse( data, options = {} ) {
 		throw new Error( 'Parse error - missing selection end.' );
 	}
 
+	// If root DocumentFragment contains only one element - return that element.
+	if ( root instanceof DocumentFragment && root.getChildCount() == 1 ) {
+		root = root.getChild( 0 );
+	}
+
 	if ( withSelection ) {
 		return {
 			model: root,
-			selection: document.selection
+			selection: selection
 		};
 	}