Selaa lähdekoodia

Moved more UIElement handling to DOM converter.

Szymon Kupś 8 vuotta sitten
vanhempi
commit
63e7074f8c

+ 17 - 8
packages/ckeditor5-engine/src/view/domconverter.js

@@ -354,8 +354,10 @@ export default class DomConverter {
 		}
 
 		// When node is inside UIElement it has no representation in the view.
-		if ( this.isDomInsideUIlement( domNode ) ) {
-			return null;
+		const uiElement = this.getParentUIElement( domNode, this._domToViewMapping );
+
+		if ( uiElement ) {
+			return uiElement;
 		}
 
 		if ( this.isText( domNode ) ) {
@@ -577,7 +579,7 @@ export default class DomConverter {
 	 * @returns {module:engine/view/element~Element|null} Corresponding element or `null` if no element was bound.
 	 */
 	getCorrespondingViewElement( domElement ) {
-		return this._domToViewMapping.get( domElement );
+		return this.getParentUIElement( domElement ) || this._domToViewMapping.get( domElement );
 	}
 
 	/**
@@ -615,6 +617,12 @@ export default class DomConverter {
 			return null;
 		}
 
+		const uiElement = this.getParentUIElement( domText );
+
+		if ( uiElement ) {
+			return uiElement;
+		}
+
 		const previousSibling = domText.previousSibling;
 
 		// Try to use previous sibling to find the corresponding text node.
@@ -838,12 +846,13 @@ export default class DomConverter {
 	}
 
 	/**
-	 * Returns true if `domNode` is placed inside {@link module:engine/view/uielement~UIElement}/
+	 * Returns parent {@link module:engine/view/uielement~UIElement} for provided DOM node. Returns null if there is no
+	 * parent UIElement.
 	 *
 	 * @param {Node} domNode
-	 * @return {Boolean}
+	 * @return {module:engine/view/uielement~UIElement|null}
 	 */
-	isDomInsideUIlement( domNode ) {
+	getParentUIElement( domNode ) {
 		const ancestors = getAncestors( domNode );
 
 		// Remove domNode from the list.
@@ -854,11 +863,11 @@ export default class DomConverter {
 			const viewNode = this._domToViewMapping.get( domNode );
 
 			if ( viewNode && viewNode.is( 'uiElement' ) ) {
-				return true;
+				return viewNode;
 			}
 		}
 
-		return false;
+		return null;
 	}
 
 	/**

+ 1 - 4
packages/ckeditor5-engine/src/view/observer/domeventobserver.js

@@ -75,10 +75,7 @@ export default class DomEventObserver extends Observer {
 
 		types.forEach( type => {
 			this.listenTo( domElement, type, ( eventInfo, domEvent ) => {
-				const domConverter = this.document.domConverter;
-
-				// Block all events if observer is disabled and events from inside of UIElement.
-				if ( this.isEnabled && !domConverter.isDomInsideUIlement( domEvent.target ) ) {
+				if ( this.isEnabled ) {
 					this.onDomEvent( domEvent );
 				}
 			}, { useCapture: this.useCapture } );

+ 5 - 7
packages/ckeditor5-engine/tests/view/domconverter/dom-to-view.js

@@ -176,7 +176,7 @@ describe( 'DomConverter', () => {
 			expect( converter.domToView( comment ) ).to.be.null;
 		} );
 
-		it( 'should return null for nodes inside UIElement', () => {
+		it( 'should return UIElement for nodes inside', () => {
 			class MyUIElement extends ViewUIElement {
 				render( doc ) {
 					const root = super.render( doc );
@@ -192,12 +192,10 @@ describe( 'DomConverter', () => {
 			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;
+			expect( converter.domToView( domParagraph ) ).to.equal( uiElement );
+			expect( converter.domToView( domSpan ) ).to.be.equal( uiElement );
+			expect( converter.domToView( domParagraph.childNodes[ 0 ] ) ).equal( uiElement );
+			expect( converter.domToView( domSpan.childNodes[ 0 ] ) ).equal( uiElement );
 		} );
 
 		describe( 'it should clear whitespaces', () => {

+ 11 - 5
packages/ckeditor5-engine/tests/view/observer/domeventobserver.js

@@ -155,7 +155,7 @@ describe( 'DomEventObserver', () => {
 	} );
 
 	describe( 'integration with UIElement', () => {
-		let domRoot, domEvent, evtSpy;
+		let domRoot, domEvent, evtSpy, uiElement;
 
 		class MyUIElement extends UIElement {
 			render( domDocument ) {
@@ -169,7 +169,7 @@ describe( 'DomEventObserver', () => {
 		beforeEach( () => {
 			domRoot = document.createElement( 'div' );
 			const viewRoot = viewDocument.createRoot( domRoot, 'root' );
-			const uiElement = new MyUIElement( 'p' );
+			uiElement = new MyUIElement( 'p' );
 			viewRoot.appendChildren( uiElement );
 			viewDocument.render();
 
@@ -183,14 +183,20 @@ describe( 'DomEventObserver', () => {
 			const domUiElement = domRoot.childNodes[ 0 ];
 			domUiElement.dispatchEvent( domEvent );
 
-			expect( evtSpy.calledOnce ).to.be.true;
+			const data = evtSpy.args[ 0 ][ 1 ];
+
+			sinon.assert.calledOnce( evtSpy );
+			expect( data.target ).to.equal( uiElement );
 		} );
 
-		it( 'should block events from inside of UIElement', () => {
+		it( 'events from inside of UIElement should target UIElement', () => {
 			const domUiElementChild = domRoot.querySelector( 'span' );
 			domUiElementChild.dispatchEvent( domEvent );
 
-			expect( evtSpy.calledOnce ).to.be.false;
+			const data = evtSpy.args[ 0 ][ 1 ];
+
+			sinon.assert.calledOnce( evtSpy );
+			expect( data.target ).to.equal( uiElement );
 		} );
 	} );