Browse Source

Introduced methods for creating document fragment, element and text in UpcastWriter.

Krzysztof Krztoń 7 years ago
parent
commit
826ef40b5e

+ 3 - 0
packages/ckeditor5-engine/src/view/documentfragment.js

@@ -20,6 +20,9 @@ export default class DocumentFragment {
 	/**
 	 * Creates new DocumentFragment instance.
 	 *
+	 * **Note:** Constructor of this class shouldn't be used directly in the code. Use the
+	 * {@link module:engine/view/upcastwriter~UpcastWriter#createDocumentFragment} method instead.
+	 *
 	 * @protected
 	 * @param {module:engine/view/node~Node|Iterable.<module:engine/view/node~Node>} [children] List of nodes to be inserted into
 	 * created document fragment.

+ 3 - 2
packages/ckeditor5-engine/src/view/element.js

@@ -53,8 +53,9 @@ export default class Element extends Node {
 	 * {@link module:engine/view/downcastwriter~DowncastWriter#createAttributeElement} for inline element,
 	 * {@link module:engine/view/downcastwriter~DowncastWriter#createContainerElement} for block element,
 	 * {@link module:engine/view/downcastwriter~DowncastWriter#createEditableElement} for editable element,
-	 * {@link module:engine/view/downcastwriter~DowncastWriter#createEmptyElement} for empty element or
-	 * {@link module:engine/view/downcastwriter~DowncastWriter#createUIElement} for UI element instead.
+	 * {@link module:engine/view/downcastwriter~DowncastWriter#createEmptyElement} for empty element,
+	 * {@link module:engine/view/downcastwriter~DowncastWriter#createUIElement} for UI element instead or
+	 * {@link module:engine/view/upcastwriter~UpcastWriter#createElement} for general element creation.
 	 *
 	 * @protected
 	 * @param {String} name Node name.

+ 2 - 1
packages/ckeditor5-engine/src/view/text.js

@@ -19,7 +19,8 @@ export default class Text extends Node {
 	 * Creates a tree view text node.
 	 *
 	 * **Note:** Constructor of this class shouldn't be used directly in the code.
-	 * Use the {@link module:engine/view/downcastwriter~DowncastWriter#createText} method instead.
+	 * Use the {@link module:engine/view/downcastwriter~DowncastWriter#createText} or
+	 * {@link module:engine/view/upcastwriter~UpcastWriter#createText} method instead.
 	 *
 	 * @protected
 	 * @param {String} data Text.

+ 45 - 0
packages/ckeditor5-engine/src/view/upcastwriter.js

@@ -7,7 +7,9 @@
  * @module module:engine/view/upcastwriter
  */
 
+import DocumentFragment from './documentfragment';
 import Element from './element';
+import Text from './text';
 import { isPlainObject } from 'lodash-es';
 
 /**
@@ -18,6 +20,49 @@ import { isPlainObject } from 'lodash-es';
  */
 export default class UpcastWriter {
 	/**
+	 * Creates new {@link module:engine/view/documentfragment~DocumentFragment}.
+	 *
+	 * @see module:engine/view/documentfragment~DocumentFragment#constructor
+	 * @param {module:engine/view/node~Node|Iterable.<module:engine/view/node~Node>} [children]
+	 * List of nodes to be inserted into created document fragment.
+	 * @returns {module:engine/view/documentfragment~DocumentFragment} Created document fragment.
+	 */
+	createDocumentFragment( children ) {
+		return new DocumentFragment( children );
+	}
+
+	/**
+	 * Creates new {@link module:engine/view/element~Element}.
+	 *
+	 * Attributes can be passed in various formats:
+	 *
+	 *		new Element( 'div', { 'class': 'editor', 'contentEditable': 'true' } ); // object
+	 *		new Element( 'div', [ [ 'class', 'editor' ], [ 'contentEditable', 'true' ] ] ); // map-like iterator
+	 *		new Element( 'div', mapOfAttributes ); // map
+	 *
+	 * @see module:engine/view/element~Element#constructor
+	 * @param {String} name Node name.
+	 * @param {Object|Iterable} [attrs] Collection of attributes.
+	 * @param {module:engine/view/node~Node|Iterable.<module:engine/view/node~Node>} [children]
+	 * List of nodes to be inserted into created element.
+	 * @returns {module:engine/view/element~Element} Created element.
+	 */
+	createElement( name, attrs, children ) {
+		return new Element( name, attrs, children );
+	}
+
+	/**
+	 * Creates new {@link module:engine/view/text~Text}.
+	 *
+	 * @see module:engine/view/text~Text#constructor
+	 * @param {String} data Text
+	 * @returns {module:engine/view/text~Text} Created text.
+	 */
+	createText( data ) {
+		return new Text( data );
+	}
+
+	/**
 	 * Clones provided element.
 	 *
 	 * @see module:engine/view/element~Element#_clone

+ 67 - 0
packages/ckeditor5-engine/tests/view/upcastwriter.js

@@ -3,7 +3,9 @@
  * For licensing, see LICENSE.md.
  */
 
+import DocumentFragment from '../../src/view/documentfragment';
 import Element from '../../src/view/element';
+import Text from '../../src/view/text';
 import UpcastWriter from '../../src/view/upcastwriter';
 import HtmlDataProcessor from '../../src/dataprocessor/htmldataprocessor';
 
@@ -29,6 +31,71 @@ describe( 'UpcastWriter', () => {
 		view = dataprocessor.toView( html );
 	} );
 
+	describe( 'createDocumentFragment', () => {
+		it( 'should create empty document fragment', () => {
+			const df = writer.createDocumentFragment();
+
+			expect( df ).to.instanceOf( DocumentFragment );
+			expect( df.childCount ).to.equal( 0 );
+		} );
+
+		it( 'should create document fragment with children', () => {
+			const df = writer.createDocumentFragment( [ view.getChild( 0 ), view.getChild( 1 ) ] );
+
+			expect( df ).to.instanceOf( DocumentFragment );
+			expect( df.childCount ).to.equal( 2 );
+		} );
+	} );
+
+	describe( 'createElement', () => {
+		it( 'should create empty element', () => {
+			const el = writer.createElement( 'p' );
+
+			expect( el ).to.instanceOf( Element );
+			expect( el.name ).to.equal( 'p' );
+			expect( Array.from( el.getAttributes() ).length ).to.equal( 0 );
+			expect( el.childCount ).to.equal( 0 );
+		} );
+
+		it( 'should create element with attributes', () => {
+			const el = writer.createElement( 'a', { 'class': 'editor', 'contentEditable': 'true' } );
+
+			expect( el ).to.instanceOf( Element );
+			expect( el.name ).to.equal( 'a' );
+			expect( Array.from( el.getAttributes() ).length ).to.equal( 2 );
+			expect( el.childCount ).to.equal( 0 );
+		} );
+
+		it( 'should create element with children', () => {
+			const el = writer.createElement( 'div', null, [ view.getChild( 0 ) ] );
+
+			expect( el ).to.instanceOf( Element );
+			expect( el.name ).to.equal( 'div' );
+			expect( Array.from( el.getAttributes() ).length ).to.equal( 0 );
+			expect( el.childCount ).to.equal( 1 );
+		} );
+
+		it( 'should create element with attributes and children', () => {
+			const el = writer.createElement( 'blockquote',
+				{ 'class': 'editor', 'contentEditable': 'true' },
+				view.getChild( 2 ) );
+
+			expect( el ).to.instanceOf( Element );
+			expect( el.name ).to.equal( 'blockquote' );
+			expect( Array.from( el.getAttributes() ).length ).to.equal( 2 );
+			expect( el.childCount ).to.equal( 1 );
+		} );
+	} );
+
+	describe( 'createText', () => {
+		it( 'should create text', () => {
+			const text = writer.createText( 'FooBar' );
+
+			expect( text ).to.instanceOf( Text );
+			expect( text.data ).to.equal( 'FooBar' );
+		} );
+	} );
+
 	describe( 'clone', () => {
 		it( 'should clone simple element', () => {
 			const el = view.getChild( 0 );