瀏覽代碼

DomConverter.domToView is returning null for items rendered from UIElement.

Szymon Kupś 8 年之前
父節點
當前提交
e02e2847dc

+ 27 - 12
packages/ckeditor5-engine/src/view/domconverter.js

@@ -195,32 +195,24 @@ export default class DomConverter {
 			if ( viewNode.is( 'documentFragment' ) ) {
 			if ( viewNode.is( 'documentFragment' ) ) {
 				// Create DOM document fragment.
 				// Create DOM document fragment.
 				domElement = domDocument.createDocumentFragment();
 				domElement = domDocument.createDocumentFragment();
-
-				if ( options.bind ) {
-					this.bindDocumentFragments( domElement, viewNode );
-				}
 			} else if ( viewNode.is( 'uiElement' ) ) {
 			} else if ( viewNode.is( 'uiElement' ) ) {
 				// UIElement has it's own render() method.
 				// UIElement has it's own render() method.
 				// https://github.com/ckeditor/ckeditor5-engine/issues/799
 				// https://github.com/ckeditor/ckeditor5-engine/issues/799
 				domElement = viewNode.render( domDocument );
 				domElement = viewNode.render( domDocument );
-
-				if ( options.bind ) {
-					this.bindElements( domElement, viewNode );
-				}
 			} else {
 			} else {
 				// Create DOM element.
 				// Create DOM element.
 				domElement = domDocument.createElement( viewNode.name );
 				domElement = domDocument.createElement( viewNode.name );
 
 
-				if ( options.bind ) {
-					this.bindElements( domElement, viewNode );
-				}
-
 				// Copy element's attributes.
 				// Copy element's attributes.
 				for ( const key of viewNode.getAttributeKeys() ) {
 				for ( const key of viewNode.getAttributeKeys() ) {
 					domElement.setAttribute( key, viewNode.getAttribute( key ) );
 					domElement.setAttribute( key, viewNode.getAttribute( key ) );
 				}
 				}
 			}
 			}
 
 
+			if ( options.bind ) {
+				this.bindDocumentFragments( domElement, viewNode );
+			}
+
 			if ( options.withChildren || options.withChildren === undefined ) {
 			if ( options.withChildren || options.withChildren === undefined ) {
 				for ( const child of this.viewChildrenToDom( viewNode, domDocument, options ) ) {
 				for ( const child of this.viewChildrenToDom( viewNode, domDocument, options ) ) {
 					domElement.appendChild( child );
 					domElement.appendChild( child );
@@ -361,6 +353,11 @@ export default class DomConverter {
 			return null;
 			return null;
 		}
 		}
 
 
+		// When node is inside UIElement it should not be converted to view.
+		if ( isInsideUIElement( domNode, this._domToViewMapping ) ) {
+			return null;
+		}
+
 		if ( this.isText( domNode ) ) {
 		if ( this.isText( domNode ) ) {
 			if ( isInlineFiller( domNode ) ) {
 			if ( isInlineFiller( domNode ) ) {
 				return null;
 				return null;
@@ -1097,3 +1094,21 @@ function forEachDomNodeAncestor( node, callback ) {
 		node = node.parentNode;
 		node = node.parentNode;
 	}
 	}
 }
 }
+
+function isInsideUIElement( domNode, domToViewMapping ) {
+	const ancestors = getAncestors( domNode );
+
+	// Remove domNode from the list.
+	ancestors.pop();
+
+	while ( ancestors.length ) {
+		const domNode = ancestors.pop();
+		const viewNode = domToViewMapping.get( domNode );
+
+		if ( viewNode && viewNode.is( 'uiElement' ) ) {
+			return true;
+		}
+	}
+
+	return false;
+}

+ 25 - 0
packages/ckeditor5-engine/tests/view/domconverter/dom-to-view.js

@@ -8,6 +8,7 @@
 import ViewElement from '../../../src/view/element';
 import ViewElement from '../../../src/view/element';
 import ViewRange from '../../../src/view/range';
 import ViewRange from '../../../src/view/range';
 import ViewSelection from '../../../src/view/selection';
 import ViewSelection from '../../../src/view/selection';
+import ViewUIElement from '../../../src/view/uielement';
 import DomConverter from '../../../src/view/domconverter';
 import DomConverter from '../../../src/view/domconverter';
 import ViewDocumentFragment from '../../../src/view/documentfragment';
 import ViewDocumentFragment from '../../../src/view/documentfragment';
 import { INLINE_FILLER, INLINE_FILLER_LENGTH, NBSP_FILLER } from '../../../src/view/filler';
 import { INLINE_FILLER, INLINE_FILLER_LENGTH, NBSP_FILLER } from '../../../src/view/filler';
@@ -175,6 +176,30 @@ describe( 'DomConverter', () => {
 			expect( converter.domToView( comment ) ).to.be.null;
 			expect( converter.domToView( comment ) ).to.be.null;
 		} );
 		} );
 
 
+		it( 'should return null for nodes inside UIElement', () => {
+			class MyUIElement extends ViewUIElement {
+				render( doc ) {
+					const root = super.render( doc );
+					root.innerHTML = '<p>foo</p><span>bar</span>';
+
+					return root;
+				}
+			}
+
+			const uiElement = new MyUIElement( 'div' );
+			const domElement = converter.viewToDom( uiElement, document, { bind: true, withChildren: true } );
+
+			const domParagraph = domElement.childNodes[ 0 ];
+			const domSpan = domElement.childNodes[ 1 ];
+
+			expect( domParagraph.innerHTML ).to.equal( 'foo' );
+			expect( domSpan.innerHTML ).to.equal( 'bar' );
+			expect( converter.domToView( domParagraph ) ).to.be.null;
+			expect( converter.domToView( domSpan ) ).to.be.null;
+			expect( converter.domToView( domParagraph.childNodes[ 0 ] ) ).to.be.null;
+			expect( converter.domToView( domSpan.childNodes[ 0 ] ) ).to.be.null;
+		} );
+
 		describe( 'it should clear whitespaces', () => {
 		describe( 'it should clear whitespaces', () => {
 			it( 'at the beginning of block element', () => {
 			it( 'at the beginning of block element', () => {
 				const domDiv = createElement( document, 'div', {}, [
 				const domDiv = createElement( document, 'div', {}, [