Browse Source

Hide the toolbar on editable blur.

Oskar Wróbel 7 years ago
parent
commit
0ce3aef731

+ 13 - 12
packages/ckeditor5-ui/src/toolbar/balloon/balloontoolbar.js

@@ -119,10 +119,11 @@ export default class BalloonToolbar extends Plugin {
 	_handleFocusChange() {
 	_handleFocusChange() {
 		const editor = this.editor;
 		const editor = this.editor;
 
 
-		// Hide the panel View when editor loses focus but no the other way around.
-		this.listenTo( editor.ui.focusTracker, 'change:isFocused', ( evt, name, isFocused ) => {
-			if ( this._balloon.visibleView === this.toolbarView && !isFocused ) {
+		this.listenTo( editor.editing.view.document, 'change:isFocused', ( evt, name, isFocused ) => {
+			if ( !isFocused && this._balloon.visibleView === this.toolbarView ) {
 				this.hide();
 				this.hide();
+			} else if ( isFocused ) {
+				this.show();
 			}
 			}
 		} );
 		} );
 	}
 	}
@@ -130,20 +131,14 @@ export default class BalloonToolbar extends Plugin {
 	/**
 	/**
 	 * Handles {@link module:engine/model/document~Document#selection} change and show or hide toolbar.
 	 * Handles {@link module:engine/model/document~Document#selection} change and show or hide toolbar.
 	 *
 	 *
-	 * Note that in this case it's better to listen to {@link module:engine/model/document~Document model document}
-	 * selection instead of {@link module:engine/view/document~Document view document} selection because the first one
-	 * doesn't fire `change` event after text style change (like bold or italic) and toolbar doesn't blink.
-	 *
 	 * @private
 	 * @private
 	 */
 	 */
 	_handleSelectionChange() {
 	_handleSelectionChange() {
 		const selection = this.editor.model.document.selection;
 		const selection = this.editor.model.document.selection;
-		const viewDocument = this.editor.editing.view.document;
 
 
+		// Hide the toolbar when the selection is changed by a direct change or has changed to collapsed.
 		this.listenTo( selection, 'change:range', ( evt, data ) => {
 		this.listenTo( selection, 'change:range', ( evt, data ) => {
-			// When the selection is not changed by a collaboration and when is not collapsed.
 			if ( data.directChange || selection.isCollapsed ) {
 			if ( data.directChange || selection.isCollapsed ) {
-				// Hide the toolbar when the selection starts changing.
 				this.hide();
 				this.hide();
 			}
 			}
 
 
@@ -153,8 +148,7 @@ export default class BalloonToolbar extends Plugin {
 
 
 		// Hide the toolbar when the selection stops changing.
 		// Hide the toolbar when the selection stops changing.
 		this.listenTo( this, '_selectionChangeDebounced', () => {
 		this.listenTo( this, '_selectionChangeDebounced', () => {
-			// This implementation assumes that only non–collapsed selections gets the contextual toolbar.
-			if ( viewDocument.isFocused && !viewDocument.selection.isCollapsed ) {
+			if ( this.editor.editing.view.document.isFocused ) {
 				this.show();
 				this.show();
 			}
 			}
 		} );
 		} );
@@ -166,11 +160,18 @@ export default class BalloonToolbar extends Plugin {
 	 * Fires {@link #event:show} event which can be stopped to prevent the toolbar from showing up.
 	 * Fires {@link #event:show} event which can be stopped to prevent the toolbar from showing up.
 	 */
 	 */
 	show() {
 	show() {
+		const editor = this.editor;
+
 		// Do not add the toolbar to the balloon stack twice.
 		// Do not add the toolbar to the balloon stack twice.
 		if ( this._balloon.hasView( this.toolbarView ) ) {
 		if ( this._balloon.hasView( this.toolbarView ) ) {
 			return;
 			return;
 		}
 		}
 
 
+		// Do not show the toolbar when the selection is collapsed.
+		if ( editor.model.document.selection.isCollapsed ) {
+			return;
+		}
+
 		// Don not show the toolbar when all components inside are disabled
 		// Don not show the toolbar when all components inside are disabled
 		// see https://github.com/ckeditor/ckeditor5-ui/issues/269.
 		// see https://github.com/ckeditor/ckeditor5-ui/issues/269.
 		if ( Array.from( this.toolbarView.items ).every( item => item.isEnabled !== undefined && !item.isEnabled ) ) {
 		if ( Array.from( this.toolbarView.items ).every( item => item.isEnabled !== undefined && !item.isEnabled ) ) {

+ 14 - 12
packages/ckeditor5-ui/tests/toolbar/balloon/balloontoolbar.js

@@ -297,6 +297,13 @@ describe( 'BalloonToolbar', () => {
 			sinon.assert.calledOnce( balloonAddSpy );
 			sinon.assert.calledOnce( balloonAddSpy );
 		} );
 		} );
 
 
+		it( 'should not add #toolbarView to the #_balloon when the selection is collapsed', () => {
+			setData( model, '<paragraph>b[]ar</paragraph>' );
+
+			balloonToolbar.show();
+			sinon.assert.notCalled( balloonAddSpy );
+		} );
+
 		it( 'should not add #toolbarView to the #_balloon when all components inside #toolbarView are disabled', () => {
 		it( 'should not add #toolbarView to the #_balloon when all components inside #toolbarView are disabled', () => {
 			Array.from( balloonToolbar.toolbarView.items ).forEach( item => {
 			Array.from( balloonToolbar.toolbarView.items ).forEach( item => {
 				item.isEnabled = false;
 				item.isEnabled = false;
@@ -327,24 +334,19 @@ describe( 'BalloonToolbar', () => {
 				showSpy = sandbox.spy( balloonToolbar, 'show' );
 				showSpy = sandbox.spy( balloonToolbar, 'show' );
 			} );
 			} );
 
 
-			it( 'should not be called when the editor is not focused', () => {
+			it( 'should not be called when the editable is not focused', () => {
 				setData( model, '<paragraph>b[a]r</paragraph>' );
 				setData( model, '<paragraph>b[a]r</paragraph>' );
 				editingView.document.isFocused = false;
 				editingView.document.isFocused = false;
+				balloonToolbar.toolbarView.focusTracker.isFocused = false;
 
 
 				balloonToolbar.fire( '_selectionChangeDebounced' );
 				balloonToolbar.fire( '_selectionChangeDebounced' );
 				sinon.assert.notCalled( showSpy );
 				sinon.assert.notCalled( showSpy );
 			} );
 			} );
 
 
-			it( 'should not be called when the selection is collapsed', () => {
-				setData( model, '<paragraph>b[]ar</paragraph>' );
-
-				balloonToolbar.fire( '_selectionChangeDebounced' );
-				sinon.assert.notCalled( showSpy );
-			} );
-
-			it( 'should be called when the selection is not collapsed and editor is focused', () => {
+			it( 'should be called when the editable is focused', () => {
 				setData( model, '<paragraph>b[a]r</paragraph>' );
 				setData( model, '<paragraph>b[a]r</paragraph>' );
 				editingView.document.isFocused = true;
 				editingView.document.isFocused = true;
+				balloonToolbar.toolbarView.focusTracker.isFocused = false;
 
 
 				balloonToolbar.fire( '_selectionChangeDebounced' );
 				balloonToolbar.fire( '_selectionChangeDebounced' );
 				sinon.assert.calledOnce( showSpy );
 				sinon.assert.calledOnce( showSpy );
@@ -472,8 +474,8 @@ describe( 'BalloonToolbar', () => {
 			sinon.assert.calledOnce( hidePanelSpy );
 			sinon.assert.calledOnce( hidePanelSpy );
 		} );
 		} );
 
 
-		it( 'should hide if the editor loses focus', () => {
-			editor.ui.focusTracker.isFocused = true;
+		it( 'should hide when the editable loses focus', () => {
+			editor.editing.view.document.isFocused = true;
 
 
 			balloonToolbar.fire( '_selectionChangeDebounced' );
 			balloonToolbar.fire( '_selectionChangeDebounced' );
 
 
@@ -482,7 +484,7 @@ describe( 'BalloonToolbar', () => {
 			sinon.assert.calledOnce( showPanelSpy );
 			sinon.assert.calledOnce( showPanelSpy );
 			sinon.assert.notCalled( hidePanelSpy );
 			sinon.assert.notCalled( hidePanelSpy );
 
 
-			editor.ui.focusTracker.isFocused = false;
+			editor.editing.view.document.isFocused = false;
 
 
 			sinon.assert.calledOnce( showPanelSpy );
 			sinon.assert.calledOnce( showPanelSpy );
 			sinon.assert.calledOnce( hidePanelSpy );
 			sinon.assert.calledOnce( hidePanelSpy );