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

Align image toolbar to the new widget toolbar factory #233

Merged
merged 3 commits into from
Sep 20, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 7 additions & 116 deletions src/imagetoolbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,15 @@
*/

import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
import ToolbarView from '@ckeditor/ckeditor5-ui/src/toolbar/toolbarview';
import ContextualBalloon from '@ckeditor/ckeditor5-ui/src/panel/balloon/contextualballoon';
import { isImageWidgetSelected } from './image/utils';
import { repositionContextualBalloon, getBalloonPositionData } from './image/ui/utils';

const balloonClassName = 'ck-toolbar-container';
import WidgetToolbarRepository from '@ckeditor/ckeditor5-widget/src/widgettoolbarrepository';

/**
* The image toolbar plugin. It creates and manages the image toolbar (the toolbar displayed when an image is selected).
*
* For a detailed overview, check the {@glink features/image#image-contextual-toolbar image contextual toolbar} documentation.
*
* Instanecs of toolbar components (e.g. buttons) are created using the editor's
* Instances of toolbar components (e.g. buttons) are created using the editor's
* {@link module:ui/componentfactory~ComponentFactory component factory}
* based on the {@link module:image/image~ImageConfig#toolbar `image.toolbar` configuration option}.
*
Expand All @@ -33,7 +29,7 @@ export default class ImageToolbar extends Plugin {
* @inheritDoc
*/
static get requires() {
return [ ContextualBalloon ];
return [ WidgetToolbarRepository ];
}

/**
Expand All @@ -43,122 +39,17 @@ export default class ImageToolbar extends Plugin {
return 'ImageToolbar';
}

/**
* @inheritDoc
*/
init() {
const editor = this.editor;
const balloonToolbar = editor.plugins.get( 'BalloonToolbar' );

// If the `BalloonToolbar` plugin is loaded, it should be disabled for images
// which have their own toolbar to avoid duplication.
// https://github.com/ckeditor/ckeditor5-image/issues/110
if ( balloonToolbar ) {
this.listenTo( balloonToolbar, 'show', evt => {
if ( isImageWidgetSelected( editor.editing.view.document.selection ) ) {
evt.stop();
}
}, { priority: 'high' } );
}
}

/**
* @inheritDoc
*/
afterInit() {
const editor = this.editor;
const toolbarConfig = editor.config.get( 'image.toolbar' );

// Don't add the toolbar if there is no configuration.
if ( !toolbarConfig || !toolbarConfig.length ) {
return;
}
const widgetToolbarRepository = editor.plugins.get( WidgetToolbarRepository );

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

/**
* A `ToolbarView` instance used to display the buttons specific for image editing.
*
* @protected
* @type {module:ui/toolbar/toolbarview~ToolbarView}
*/
this._toolbar = new ToolbarView();

// Add buttons to the toolbar.
this._toolbar.fillFromConfig( toolbarConfig, editor.ui.componentFactory );

// Show balloon panel each time image widget is selected.
this.listenTo( editor.ui, 'update', () => {
this._checkIsVisible();
widgetToolbarRepository.register( 'image', {
toolbarItems: editor.config.get( 'image.toolbar' ) || [],
visibleWhen: isImageWidgetSelected,
} );

// UI#update is not fired after focus is back in editor, we need to check if balloon panel should be visible.
this.listenTo( editor.ui.focusTracker, 'change:isFocused', () => {
this._checkIsVisible();
}, { priority: 'low' } );
}

/**
* Checks whether the toolbar should show up or hide depending on the current selection.
*
* @private
*/
_checkIsVisible() {
const editor = this.editor;

if ( !editor.ui.focusTracker.isFocused || !isImageWidgetSelected( editor.editing.view.document.selection ) ) {
this._hideToolbar();
} else {
this._showToolbar();
}
}

/**
* Shows the {@link #_toolbar} in the {@link #_balloon}.
*
* @private
*/
_showToolbar() {
const editor = this.editor;

if ( this._isVisible ) {
repositionContextualBalloon( editor );
} else if ( !this._balloon.hasView( this._toolbar ) ) {
this._balloon.add( {
view: this._toolbar,
position: getBalloonPositionData( editor ),
balloonClassName
} );
}
}

/**
* Removes the {@link #_toolbar} from the {@link #_balloon}.
*
* @private
*/
_hideToolbar() {
if ( !this._isVisible ) {
return;
}

this._balloon.remove( this._toolbar );
}

/**
* Returns `true` when the {@link #_toolbar} is the visible view in the {@link #_balloon}.
*
* @private
* @type {Boolean}
*/
get _isVisible() {
return this._balloon.visibleView == this._toolbar;
}
}

Expand Down
6 changes: 3 additions & 3 deletions tests/imagetoolbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import env from '@ckeditor/ckeditor5-utils/src/env';
import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils';

describe( 'ImageToolbar', () => {
let editor, model, doc, plugin, toolbar, balloon, editorElement;
let editor, model, doc, toolbar, balloon, widgetToolbarRepository, editorElement;

testUtils.createSinonSandbox();

Expand All @@ -41,8 +41,8 @@ describe( 'ImageToolbar', () => {
editor = newEditor;
model = newEditor.model;
doc = model.document;
plugin = editor.plugins.get( ImageToolbar );
toolbar = plugin._toolbar;
widgetToolbarRepository = editor.plugins.get( 'WidgetToolbarRepository' );
toolbar = widgetToolbarRepository._toolbars.get( 'image' ).view;
balloon = editor.plugins.get( 'ContextualBalloon' );
} );
} );
Expand Down