瀏覽代碼

Added view.EmptyElement class.

Szymon Kupś 9 年之前
父節點
當前提交
b5bd478f4a

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

@@ -14,7 +14,7 @@ import isPlainObject from '../../utils/lib/lodash/isPlainObject.js';
  *
  * Editing engine does not define fixed HTML DTD. This is why the type of the {@link engine.view.Element} need to
  * be defined by the feature developer. Creating an element you should use {@link engine.view.ContainerElement}
- * class or {@link engine.view.AttributeElement}.
+ * class, {@link engine.view.AttributeElement} class or {@link engine.view.EmptyElement} class.
  *
  * Note that for view elements which are not created from model, like elements from mutations, paste or
  * {@link engine.controller.DataController#set data.set} it is not possible to define the type of the element, so
@@ -138,7 +138,7 @@ export default class Element extends Node {
 			}
 		}
 
-		// ContainerElement and AttributeElement should be also cloned properly.
+		// ContainerElement, AttributeElement and EmptyElement should be also cloned properly.
 		const cloned = new this.constructor( this.name, this._attrs, childrenClone );
 
 		// Classes and styles are cloned separately - this solution is faster than adding them back to attributes and

+ 48 - 1
packages/ckeditor5-engine/src/view/emptyelement.js

@@ -1,7 +1,54 @@
-import Element from './attributeelement.js';
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
 
+import Element from './element.js';
+import CKEditorError from '../../utils/ckeditorerror.js';
+
+/**
+ * EmptyElement class. It is used to represent elements that cannot contain any child nodes.
+ */
 export default class EmptyElement extends Element {
 	/**
+	 * Creates new instance of EmptyElement.
+	 *
+	 * @param {String} name Node name.
+	 * @param {Object|Iterable} [attributes] Collection of attributes.
+	 */
+	constructor( name, attributes ) {
+		super( name, attributes );
+	}
+
+	/**
+	 * Overrides {@link engine.view.Element#appendChildren} method.
+	 * Throws {@link utils.CKEditorError CKEditorError} `view-emptyelement-cannot-add` to prevent adding any child nodes
+	 * to EmptyElement.
+	 */
+	appendChildren() {
+		/**
+		 * Cannot add children to {@link engine.view.EmptyElement}.
+		 *
+		 * @error view-emptyelement-cannot-add
+		 */
+		throw new CKEditorError( 'view-emptyelement-cannot-add: Cannot add child nodes to EmptyElement instance.' );
+	}
+
+	/**
+	 * Overrides {@link engine.view.Element#insertChildren} method.
+	 * Throws {@link utils.CKEditorError CKEditorError} `view-emptyelement-cannot-add` to prevent adding any child nodes
+	 * to EmptyElement.
+	 */
+	insertChildren() {
+		/**
+		 * Cannot add children to {@link engine.view.EmptyElement}.
+		 *
+		 * @error view-emptyelement-cannot-add
+		 */
+		throw new CKEditorError( 'view-emptyelement-cannot-add: Cannot add child nodes to EmptyElement instance.' );
+	}
+
+	/**
 	 * Returns `null` because block filler is not needed.
 	 *
 	 * @returns {null}

+ 59 - 0
packages/ckeditor5-engine/tests/view/emptyelement.js

@@ -0,0 +1,59 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/* bender-tags: view */
+
+import EmptyElement from '/ckeditor5/engine/view/emptyelement.js';
+import Element from '/ckeditor5/engine/view/element.js';
+import CKEditorError from '/ckeditor5/utils/ckeditorerror.js';
+
+describe( 'EmptyElement', () => {
+	let element, emptyElement;
+
+	beforeEach( () => {
+		element = new Element( 'b' );
+		emptyElement = new EmptyElement( 'img', {
+			alt: 'alternative text',
+			style: 'border: 1px solid red;color: white;',
+			class: 'image big'
+		} );
+	} );
+
+	describe( 'appendChildren', () => {
+		it( 'should throw when try to append new child element', () => {
+			expect( () => {
+				emptyElement.appendChildren( element );
+			} ).to.throw( CKEditorError, 'view-emptyelement-cannot-add: Cannot add child nodes to EmptyElement instance.' );
+		} );
+	} );
+
+	describe( 'insertChildren', () => {
+		it( 'should throw when try to insert new child element', () => {
+			expect( () => {
+				emptyElement.insertChildren( 0, element );
+			} ).to.throw( CKEditorError, 'view-emptyelement-cannot-add: Cannot add child nodes to EmptyElement instance.' );
+		} );
+	} );
+
+	describe( 'clone', () => {
+		it( 'should be cloned properly', () => {
+			const newEmptyElement = emptyElement.clone();
+
+			expect( newEmptyElement.name ).to.equal( 'img' );
+			expect( newEmptyElement.getAttribute( 'alt' ) ).to.equal( 'alternative text' );
+			expect( newEmptyElement.getStyle( 'border' ) ).to.equal( '1px solid red' );
+			expect( newEmptyElement.getStyle( 'color' ) ).to.equal( 'white' );
+			expect( newEmptyElement.hasClass( 'image' ) ).to.be.true;
+			expect( newEmptyElement.hasClass( 'big' ) ).to.be.true;
+			expect( newEmptyElement.isSimilar( emptyElement ) ).to.be.true;
+		} );
+	} );
+
+	describe( 'getFillerOffset', () => {
+		it( 'should return null', () => {
+			expect( emptyElement.getFillerOffset() ).to.be.null;
+		} );
+	} );
+} );