Browse Source

Changed the way custom UIElements are rendered()

Szymon Kupś 8 years ago
parent
commit
4bac5d3714

+ 11 - 0
packages/ckeditor5-engine/src/view/uielement.js

@@ -73,6 +73,17 @@ export default class UIElement extends Element {
 	 * @return {HTMLElement}
 	 */
 	render( domDocument ) {
+		return this.createDomElement( domDocument );
+	}
+
+	/**
+	 * Creates DOM element based on this view UIElement.
+	 * Note that each time this method is called new DOM element is created.
+	 *
+	 * @param {Document} domDocument
+	 * @returns {HTMLElement}
+	 */
+	createDomElement( domDocument ) {
 		const domElement = domDocument.createElement( this.name );
 
 		for ( const key of this.getAttributeKeys() ) {

+ 19 - 13
packages/ckeditor5-engine/tests/view/manual/uielement.js

@@ -17,26 +17,32 @@ import UIElement from '../../../src/view/uielement';
 import Position from '../../../src/view/position';
 import writer from '../../../src/view/writer';
 
-class EndingUIElement extends UIElement {
-	render( domDocument ) {
-		const root = super.render( domDocument );
+function createEndingUIElement() {
+	const element = new UIElement( 'span' );
 
+	element.render = function( domDocument ) {
+		const root = this.createDomElement( domDocument );
 		root.classList.add( 'ui-element' );
 		root.innerHTML = 'END OF PARAGRAPH';
 
 		return root;
-	}
+	};
+
+	return element;
 }
 
-class MiddleUIElement extends UIElement {
-	render( domDocument ) {
-		const root = super.render( domDocument );
+function createMiddleUIElement() {
+	const element = new UIElement( 'span' );
 
+	element.render = function( domDocument ) {
+		const root = this.createDomElement( domDocument );
 		root.classList.add( 'ui-element' );
 		root.innerHTML = 'X';
 
 		return root;
-	}
+	};
+
+	return element;
 }
 
 class UIElementTestPlugin extends Plugin {
@@ -47,7 +53,7 @@ class UIElementTestPlugin extends Plugin {
 		// Add some UIElement to each paragraph.
 		editing.modelToView.on( 'insert:paragraph', ( evt, data, consumable, conversionApi ) => {
 			const viewP = conversionApi.mapper.toViewElement( data.item );
-			viewP.appendChildren( new EndingUIElement( 'span' ) );
+			viewP.appendChildren( createEndingUIElement() );
 		}, { priority: 'lowest' } );
 	}
 }
@@ -65,10 +71,10 @@ ClassicEditor
 		const viewText1 = viewRoot.getChild( 0 ).getChild( 0 );
 		const viewText2 = viewRoot.getChild( 1 ).getChild( 0 );
 
-		writer.insert( new Position( viewText1, 20 ), new MiddleUIElement( 'span' ) );
-		writer.insert( new Position( viewText1, 20 ), new MiddleUIElement( 'span' ) );
-		writer.insert( new Position( viewText2, 0 ), new MiddleUIElement( 'span' ) );
-		writer.insert( new Position( viewText2, 6 ), new MiddleUIElement( 'span' ) );
+		writer.insert( new Position( viewText1, 20 ), createMiddleUIElement() );
+		writer.insert( new Position( viewText1, 20 ), createMiddleUIElement() );
+		writer.insert( new Position( viewText2, 0 ), createMiddleUIElement() );
+		writer.insert( new Position( viewText2, 6 ), createMiddleUIElement() );
 
 		editor.editing.view.render();
 	} )

+ 22 - 0
packages/ckeditor5-engine/tests/view/uielement.js

@@ -122,5 +122,27 @@ describe( 'UIElement', () => {
 				expect( domElement.getAttribute( key ) ).to.equal( uiElement.getAttribute( key ) );
 			}
 		} );
+
+		it( 'should allow to change render() method', () => {
+			uiElement.render = function( domDocument ) {
+				return domDocument.createElement( 'b' );
+			};
+
+			expect( uiElement.render( document ).tagName.toLowerCase() ).to.equal( 'b' );
+		} );
+
+		it( 'should allow to add new elements inside', () => {
+			uiElement.render = function( domDocument ) {
+				const element = this.createDomElement( domDocument );
+				const text = domDocument.createTextNode( 'foo bar' );
+				element.appendChild( text );
+
+				return element;
+			};
+
+			const rendered = uiElement.render( document );
+			expect( rendered.tagName.toLowerCase() ).to.equal( 'span' );
+			expect( rendered.textContent ).to.equal( 'foo bar' );
+		} );
 	} );
 } );