Skip to content
This repository has been archived by the owner on Jun 26, 2020. It is now read-only.

Commit

Permalink
Merge 58bc3d8 into a44c67c
Browse files Browse the repository at this point in the history
  • Loading branch information
oskarwrobel committed Jul 2, 2018
2 parents a44c67c + 58bc3d8 commit c010c95
Show file tree
Hide file tree
Showing 5 changed files with 203 additions and 102 deletions.
118 changes: 60 additions & 58 deletions src/toolbar/balloon/balloontoolbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,31 +40,21 @@ export default class BalloonToolbar extends Plugin {
/**
* @inheritDoc
*/
init() {
const editor = this.editor;
constructor( editor ) {
super( editor );

/**
* The toolbar view displayed in the balloon.
*
* @member {module:ui/toolbar/toolbarview~ToolbarView}
* @type {module:ui/toolbar/toolbarview~ToolbarView}
*/
this.toolbarView = new ToolbarView( editor.locale );

this.toolbarView.extendTemplate( {
attributes: {
class: [
'ck-toolbar_floating'
]
}
} );

this.toolbarView.render();
this.toolbarView = this._createToolbarView();

/**
* The contextual balloon plugin instance.
*
* @private
* @member {module:ui/panel/balloon/contextualballoon~ContextualBalloon}
* @type {module:ui/panel/balloon/contextualballoon~ContextualBalloon}
*/
this._balloon = editor.plugins.get( ContextualBalloon );

Expand All @@ -75,19 +65,53 @@ export default class BalloonToolbar extends Plugin {
* trailing debounced invocation on destroy.
*
* @private
* @member {Function}
* @type {Function}
*/
this._fireSelectionChangeDebounced = debounce( () => this.fire( '_selectionChangeDebounced' ), 200 );

// Attach lifecycle actions.
this._handleSelectionChange();
this._handleFocusChange();

// The appearance of the BalloonToolbar method is event–driven.
// It is possible to stop the #show event and this prevent the toolbar from showing up.
this.decorate( 'show' );
}

/**
* @inheritDoc
*/
init() {
const editor = this.editor;
const selection = editor.model.document.selection;

// Show/hide the toolbar on editable focus/blur.
this.listenTo( editor.editing.view.document, 'change:isFocused', ( evt, name, isEditableFocused ) => {
const isToolbarFocused = this.toolbarView.focusTracker.isFocused;
const isToolbarVisible = this._balloon.visibleView === this.toolbarView;

if ( !isEditableFocused && !isToolbarFocused && isToolbarVisible ) {
this.hide();
} else if ( isEditableFocused ) {
this.show();
}
} );

// Hide the toolbar when the selection is changed by a direct change or has changed to collapsed.
this.listenTo( selection, 'change:range', ( evt, data ) => {
if ( data.directChange || selection.isCollapsed ) {
this.hide();
}

// Fire internal `_selectionChangeDebounced` event to use it for showing
// the toolbar after the selection stops changing.
this._fireSelectionChangeDebounced();
} );

// Show the toolbar when the selection stops changing.
this.listenTo( this, '_selectionChangeDebounced', () => {
if ( this.editor.editing.view.document.isFocused ) {
this.show();
}
} );
}

/**
* Creates toolbar components based on given configuration.
* This needs to be done when all plugins are ready.
Expand All @@ -102,52 +126,23 @@ export default class BalloonToolbar extends Plugin {
}

/**
* Handles the editor focus change and hides the toolbar if it's needed.
* Creates the toolbar view instance.
*
* @private
* @returns {module:ui/toolbar/toolbarview~ToolbarView}
*/
_handleFocusChange() {
const editor = this.editor;
_createToolbarView() {
const toolbarView = new ToolbarView( this.editor.locale );

// 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.hide();
toolbarView.extendTemplate( {
attributes: {
class: [ 'ck-toolbar_floating' ]
}
} );
}

/**
* 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
*/
_handleSelectionChange() {
const selection = this.editor.model.document.selection;
const viewDocument = this.editor.editing.view.document;

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 ) {
// Hide the toolbar when the selection starts changing.
this.hide();
}

// Fire internal `_selectionChangeDebounced` when the selection stops changing.
this._fireSelectionChangeDebounced();
} );
toolbarView.render();

// Hide the toolbar when the selection stops changing.
this.listenTo( this, '_selectionChangeDebounced', () => {
// This implementation assumes that only non–collapsed selections gets the contextual toolbar.
if ( viewDocument.isFocused && !viewDocument.selection.isCollapsed ) {
this.show();
}
} );
return toolbarView;
}

/**
Expand All @@ -156,11 +151,18 @@ export default class BalloonToolbar extends Plugin {
* Fires {@link #event:show} event which can be stopped to prevent the toolbar from showing up.
*/
show() {
const editor = this.editor;

// Do not add the toolbar to the balloon stack twice.
if ( this._balloon.hasView( this.toolbarView ) ) {
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
// see https://github.com/ckeditor/ckeditor5-ui/issues/269.
if ( Array.from( this.toolbarView.items ).every( item => item.isEnabled !== undefined && !item.isEnabled ) ) {
Expand Down
31 changes: 31 additions & 0 deletions tests/manual/tickets/418/1.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<div class="wrapper">
<div id="editor">
<h2>The three greatest things you learn from traveling</h2>
<p>
Like all the great things on earth traveling teaches us by example. Here are some of the most precious lessons
I’ve learned over the years of traveling.
</p>

<h3>Appreciation of diversity</h3>
<p>
Getting used to an entirely different culture can be challenging. While it’s also nice to learn about
cultures online or from books, nothing comes close to experiencing cultural diversity in person.
You learn to appreciate each and every single one of the differences while you become more culturally fluid.
</p>
</div>
</div>

<style>
#editor {
margin: 0 auto;
max-width: 800px;
}

.wrapper {
padding: 50px 20px;
}

.ck-block-toolbar-button {
transform: translateX( -10px );
}
</style>
45 changes: 45 additions & 0 deletions tests/manual/tickets/418/1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.md.
*/

/* globals window, document, console:false */

import BalloonEditor from '@ckeditor/ckeditor5-editor-balloon/src/ballooneditor';
import Essentials from '@ckeditor/ckeditor5-essentials/src/essentials';
import List from '@ckeditor/ckeditor5-list/src/list';
import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
import Heading from '@ckeditor/ckeditor5-heading/src/heading';
import HeadingButtonsUI from '@ckeditor/ckeditor5-heading/src/headingbuttonsui';
import ParagraphButtonUI from '@ckeditor/ckeditor5-paragraph/src/paragraphbuttonui';
import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold';
import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic';
import Link from '@ckeditor/ckeditor5-link/src/link';

import BlockToolbar from '../../../../src/toolbar/block/blocktoolbar';
import BalloonToolbar from '../../../../src/toolbar/balloon/balloontoolbar';

BalloonEditor
.create( document.querySelector( '#editor' ), {
plugins: [
Essentials,
List,
Paragraph,
Heading,
HeadingButtonsUI,
ParagraphButtonUI,
Bold,
Italic,
Link,
BlockToolbar,
BalloonToolbar
],
blockToolbar: [ 'paragraph', 'heading1', 'heading2', 'heading3', 'bulletedList', 'numberedList' ],
balloonToolbar: [ 'bold', 'italic', 'link' ]
} )
.then( editor => {
window.editor = editor;
} )
.catch( err => {
console.error( err.stack );
} );
5 changes: 5 additions & 0 deletions tests/manual/tickets/418/1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## BlockToolbar and BalloonToolbar collision [#418](https://github.com/ckeditor/ckeditor5-ui/issues/418)

- select some text, balloon toolbar should show up
- click block toolbar button, balloon toolbar should hide
- pres `Esc` to move focus back to editable, balloon toolbar should show up

0 comments on commit c010c95

Please sign in to comment.