diff --git a/src/image.js b/src/image.js index 777af10a..a5d15035 100644 --- a/src/image.js +++ b/src/image.js @@ -11,6 +11,7 @@ import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; import ImageEngine from './image/imageengine'; import Widget from '@ckeditor/ckeditor5-widget/src/widget'; import ImageTextAlternative from './imagetextalternative'; +import { isImageWidget } from './image/utils'; import '../theme/theme.scss'; @@ -35,4 +36,25 @@ export default class Image extends Plugin { static get pluginName() { return 'image/image'; } + + /** + * @inheritDoc + */ + init() { + const editor = this.editor; + const contextualToolbar = editor.plugins.get( 'ui/contextualtoolbar' ); + + // If `ContextualToolbar` 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 ( contextualToolbar ) { + this.listenTo( contextualToolbar, 'beforeShow', ( evt, stop ) => { + const selectedElement = editor.editing.view.selection.getSelectedElement(); + + if ( selectedElement && isImageWidget( selectedElement ) ) { + stop(); + } + } ); + } + } } diff --git a/src/imagetextalternative.js b/src/imagetextalternative.js index 0773e259..2605efd4 100644 --- a/src/imagetextalternative.js +++ b/src/imagetextalternative.js @@ -49,7 +49,7 @@ export default class ImageTextAlternative extends Plugin { /** * Balloon panel containing text alternative change form. * - * @member {module:image/ui/imageballoonpanel~ImageBalloonPanelView} #baloonPanel + * @member {module:image/image/ui/imageballoonpanel~ImageBalloonPanelView} #baloonPanel */ this.balloonPanel = panel; diff --git a/src/imagetextalternative/ui/textalternativeformview.js b/src/imagetextalternative/ui/textalternativeformview.js index 7def38bc..7e965430 100644 --- a/src/imagetextalternative/ui/textalternativeformview.js +++ b/src/imagetextalternative/ui/textalternativeformview.js @@ -4,7 +4,7 @@ */ /** - * @module image/imagetextalternative/ui/imagetextalternativeformview + * @module image/imagetextalternative/ui/textalternativeformview */ import View from '@ckeditor/ckeditor5-ui/src/view'; diff --git a/tests/image.js b/tests/image.js index ff5f01e5..52eb6ec2 100644 --- a/tests/image.js +++ b/tests/image.js @@ -13,12 +13,14 @@ import ImageTextAlternative from '../src/imagetextalternative'; import { setData as setModelData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model'; import { getData as getViewData } from '@ckeditor/ckeditor5-engine/src/dev-utils/view'; import ModelRange from '@ckeditor/ckeditor5-engine/src/model/range'; +import ContextualToolbar from '@ckeditor/ckeditor5-ui/src/toolbar/contextual/contextualtoolbar'; +import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph'; describe( 'Image', () => { - let editor, document, viewDocument; + let editorElement, editor, document, viewDocument; beforeEach( () => { - const editorElement = window.document.createElement( 'div' ); + editorElement = window.document.createElement( 'div' ); window.document.body.appendChild( editorElement ); return ClassicTestEditor.create( editorElement, { @@ -31,6 +33,12 @@ describe( 'Image', () => { } ); } ); + afterEach( () => { + editorElement.remove(); + + return editor.destroy(); + } ); + it( 'should be loaded', () => { expect( editor.plugins.get( Image ) ).to.instanceOf( Image ); } ); @@ -47,6 +55,41 @@ describe( 'Image', () => { expect( editor.plugins.get( ImageTextAlternative ) ).to.instanceOf( ImageTextAlternative ); } ); + it( 'should prevent the ContextualToolbar from being displayed when an image is selected', () => { + return ClassicTestEditor.create( editorElement, { + plugins: [ Image, ContextualToolbar, Paragraph ] + } ) + .then( newEditor => { + const balloon = newEditor.plugins.get( 'ui/contextualballoon' ); + const contextualToolbar = newEditor.plugins.get( 'ui/contextualtoolbar' ); + + newEditor.editing.view.isFocused = true; + + // When image is selected along with text. + setModelData( newEditor.document, 'fo[oalt text]' ); + + return contextualToolbar._showPanel() + .then( () => { + // ContextualToolbar should be visible. + expect( balloon.visibleView ).to.equal( contextualToolbar.toolbarView ); + + // When only image is selected. + setModelData( newEditor.document, 'foo[alt text]' ); + + return contextualToolbar._showPanel() + .then( () => { + // ContextualToolbar should not be visible. + expect( balloon.visibleView ).to.be.null; + + // Cleaning up. + editorElement.remove(); + + return newEditor.destroy(); + } ); + } ); + } ); + } ); + describe( 'selection', () => { it( 'should create fake selection', () => { setModelData( document, '[alt text]' ); diff --git a/tests/manual/tickets/110/1.html b/tests/manual/tickets/110/1.html new file mode 100644 index 00000000..eedc75a9 --- /dev/null +++ b/tests/manual/tickets/110/1.html @@ -0,0 +1,8 @@ +
+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla finibus consequat placerat. Vestibulum id tellus et mauris sagittis tincidunt quis id mauris. Curabitur consectetur lectus sit amet tellus mattis, non lobortis leo interdum.

+
+ CKEditor logo +
+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla finibus consequat placerat. Vestibulum id tellus et mauris sagittis tincidunt quis id mauris. Curabitur consectetur lectus sit amet tellus mattis, non lobortis leo interdum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla finibus consequat placerat. Vestibulum id tellus et mauris sagittis tincidunt quis id mauris. Curabitur consectetur lectus sit amet tellus mattis, non lobortis leo interdum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla finibus consequat placerat. Vestibulum id tellus et mauris sagittis tincidunt quis id mauris. Curabitur consectetur lectus sit amet tellus mattis, non lobortis leo interdum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla finibus consequat placerat. Vestibulum id tellus et mauris sagittis tincidunt quis id mauris. Curabitur consectetur lectus sit amet tellus mattis, non lobortis leo interdum.

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla finibus consequat placerat. Vestibulum id tellus et mauris sagittis tincidunt quis id mauris. Curabitur consectetur lectus sit amet tellus mattis, non lobortis leo interdum.

+
diff --git a/tests/manual/tickets/110/1.js b/tests/manual/tickets/110/1.js new file mode 100644 index 00000000..ee957d15 --- /dev/null +++ b/tests/manual/tickets/110/1.js @@ -0,0 +1,30 @@ +/** + * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md. + */ + +/* global document, console, window */ + +import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classic'; +import EnterPlugin from '@ckeditor/ckeditor5-enter/src/enter'; +import TypingPlugin from '@ckeditor/ckeditor5-typing/src/typing'; +import ParagraphPlugin from '@ckeditor/ckeditor5-paragraph/src/paragraph'; +import HeadingPlugin from '@ckeditor/ckeditor5-heading/src/heading'; +import ImagePlugin from '../../../../src/image'; +import UndoPlugin from '@ckeditor/ckeditor5-undo/src/undo'; +import ContextualToolbar from '@ckeditor/ckeditor5-ui/src/toolbar/contextual/contextualtoolbar'; +import ImageToolbar from '../../../../src/imagetoolbar'; + +ClassicEditor.create( document.querySelector( '#editor' ), { + plugins: [ EnterPlugin, TypingPlugin, ParagraphPlugin, HeadingPlugin, ImagePlugin, UndoPlugin, ImageToolbar, ContextualToolbar ], + contextualToolbar: [ 'headings', 'undo', 'redo' ], + image: { + toolbar: [ 'imageTextAlternative' ] + } +} ) +.then( editor => { + window.editor = editor; +} ) +.catch( err => { + console.error( err.stack ); +} ); diff --git a/tests/manual/tickets/110/1.md b/tests/manual/tickets/110/1.md new file mode 100644 index 00000000..b5ea72ff --- /dev/null +++ b/tests/manual/tickets/110/1.md @@ -0,0 +1,6 @@ +### Double image toolbar when ContextualToolbar plugin is loaded [#110](https://github.com/ckeditor/ckeditor5-image/issues/110) + +1. When selecting a text, the `ContextualToolbar` should appear. +2. Click on image: + 1. The image toolbar in a balloon should show up, + 2. The ContextualToolbar should not be visible.