8
0
Просмотр исходного кода

Renderer removing selection from DOM elements if there is no selection in view.

Szymon Kupś 9 лет назад
Родитель
Сommit
b8e6a3da74

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

@@ -191,7 +191,7 @@ export default class Document {
 		viewRoot.on( 'change:attributes', ( evt, node ) => this.renderer.markToSync( 'attributes', node ) );
 		viewRoot.on( 'change:text', ( evt, node ) => this.renderer.markToSync( 'text', node ) );
 
-		if ( domRoot instanceof HTMLElement ) {
+		if ( this.domConverter.isElement( domRoot ) ) {
 			this.attachDomRoot( domRoot, name );
 		}
 
@@ -217,6 +217,7 @@ export default class Document {
 		this.domConverter.bindElements( domRoot, viewRoot );
 
 		this.renderer.markToSync( 'children', viewRoot );
+		this.renderer.domDocuments.add( domRoot.ownerDocument );
 
 		for ( let observer of this._observers.values() ) {
 			observer.observe( domRoot, name );

+ 29 - 4
packages/ckeditor5-engine/src/view/renderer.js

@@ -40,6 +40,13 @@ export default class Renderer {
 	 * @param {engine.view.Selection} selection View selection.
 	 */
 	constructor( domConverter, selection ) {
+		/**
+		 * Set of DOM Documents instances.
+		 *
+		 * @member {Set.<Document>} engine.view.Renderer#domDocuments
+		 */
+		this.domDocuments = new Set();
+
 		/**
 		 * Converter instance.
 		 *
@@ -93,7 +100,7 @@ export default class Renderer {
 		 * Indicates if view document is focused and selection can be rendered. Selection will not be rendered if
 		 * this is set to `false`.
 		 *
-		 * @type {boolean}
+		 * @member {Boolean} engine.view.Renderer#isFocused
 		 */
 		this.isFocused = false;
 	}
@@ -243,7 +250,7 @@ export default class Renderer {
 		const domFillerNode = domFillerPosition.parent;
 
 		// If there is no filler viewPositionToDom will return parent node, so domFillerNode will be an element.
-		if ( !( domFillerNode instanceof Text ) || !startsWithFiller( domFillerNode ) ) {
+		if ( !( this.domConverter.isText( domFillerNode ) ) || !startsWithFiller( domFillerNode ) ) {
 			/**
 			 * No inline filler on expected position.
 			 *
@@ -364,7 +371,7 @@ export default class Renderer {
 		if ( filler && filler.parent == viewElement ) {
 			const expectedNodeAfterFiller = expectedDomChildren[ filler.offset ];
 
-			if ( expectedNodeAfterFiller instanceof Text ) {
+			if ( this.domConverter.isText( expectedNodeAfterFiller ) ) {
 				expectedNodeAfterFiller.data = INLINE_FILLER + expectedNodeAfterFiller.data;
 			} else {
 				expectedDomChildren.splice( filler.offset, 0, domDocument.createTextNode( INLINE_FILLER ) );
@@ -392,7 +399,7 @@ export default class Renderer {
 				return true;
 			}
 			// Texts.
-			else if ( actualDomChild instanceof Text && expectedDomChild instanceof Text ) {
+			else if ( domConverter.isText( actualDomChild ) && domConverter.isText( expectedDomChild ) ) {
 				return actualDomChild.data === expectedDomChild.data;
 			}
 			// Block fillers.
@@ -416,6 +423,24 @@ export default class Renderer {
 			return;
 		}
 
+		// If there is no selection - remove it from DOM elements that belongs to the editor.
+		if ( this.selection.rangeCount === 0 ) {
+			for ( let doc of this.domDocuments ) {
+				const domSelection = doc.getSelection();
+
+				if ( domSelection.rangeCount ) {
+					const activeDomElement = doc.activeElement;
+					const viewElement = this.domConverter.getCorrespondingViewElement( activeDomElement );
+
+					if ( activeDomElement && viewElement ) {
+						doc.getSelection().removeAllRanges();
+					}
+				}
+			}
+
+			return;
+		}
+
 		const selectedEditable = this.selection.getEditableElement();
 		const domRoot = this.domConverter.getCorrespondingDomElement( selectedEditable );
 

+ 1 - 0
packages/ckeditor5-engine/tests/view/renderer.js

@@ -28,6 +28,7 @@ describe( 'Renderer', () => {
 		selection = new Selection();
 		domConverter = new DomConverter();
 		renderer = new Renderer( domConverter, selection );
+		renderer.domDocuments.add( document );
 	} );
 
 	describe( 'markToSync', () => {