From 99588c6a5e93d414f79be698591a11381462ba8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Wr=C3=B3bel?= Date: Fri, 19 Jul 2019 14:16:41 +0200 Subject: [PATCH 1/3] Refresh toolbar position when toolbar view is switched to visible in rotator. --- src/widgettoolbarrepository.js | 13 +++++++++ tests/widgettoolbarrepository.js | 49 +++++++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/src/widgettoolbarrepository.js b/src/widgettoolbarrepository.js index 703a64f0..dea4ead2 100644 --- a/src/widgettoolbarrepository.js +++ b/src/widgettoolbarrepository.js @@ -187,6 +187,7 @@ export default class WidgetToolbarRepository extends Plugin { */ _hideToolbar( toolbarDefinition ) { this._balloon.remove( toolbarDefinition.view ); + this.stopListening( this._balloon, 'change:visibleView' ); } /** @@ -209,6 +210,18 @@ export default class WidgetToolbarRepository extends Plugin { position: getBalloonPositionData( this.editor, relatedElement ), balloonClassName: toolbarDefinition.balloonClassName, } ); + + // Update toolbar position each time stack with toolbar view is switched to visible. + // This is in a case target element has changed when toolbar was in invisible stack + // e.g. target image was wrapper by a block quote. + // See https://github.com/ckeditor/ckeditor5-widget/issues/92. + this.listenTo( this._balloon, 'change:visibleView', () => { + for ( const definition of this._toolbarDefinitions.values() ) { + if ( this._isToolbarVisible( definition ) ) { + this._updateToolbarsVisibility( definition ); + } + } + } ); } } diff --git a/tests/widgettoolbarrepository.js b/tests/widgettoolbarrepository.js index 5d60e7bc..1dce9411 100644 --- a/tests/widgettoolbarrepository.js +++ b/tests/widgettoolbarrepository.js @@ -10,6 +10,7 @@ import BalloonEditor from '@ckeditor/ckeditor5-editor-balloon/src/ballooneditor' import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph'; import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold'; +import BlockQuote from '@ckeditor/ckeditor5-block-quote/src/blockquote'; import Widget from '../src/widget'; import WidgetToolbarRepository from '../src/widgettoolbarrepository'; import { isWidget, toWidget } from '../src/utils'; @@ -31,7 +32,7 @@ describe( 'WidgetToolbarRepository', () => { return ClassicTestEditor .create( editorElement, { - plugins: [ Paragraph, FakeButton, WidgetToolbarRepository, FakeWidget, FakeChildWidget ], + plugins: [ Paragraph, FakeButton, WidgetToolbarRepository, FakeWidget, FakeChildWidget, BlockQuote ], fake: { toolbar: [ 'fake_button' ] } @@ -331,6 +332,52 @@ describe( 'WidgetToolbarRepository', () => { expect( updatePositionSpy.firstCall.args[ 0 ].position.target ).to.equal( view.domConverter.viewToDom( fakeChildViewElement ) ); } ); + + it( 'should update position when is switched in rotator to a visible panel', () => { + const view = editor.editing.view; + const customView = new View(); + + sinon.spy( balloon.view, 'pin' ); + + widgetToolbarRepository.register( 'fake', { + items: editor.config.get( 'fake.toolbar' ), + getRelatedElement: getSelectedFakeWidget + } ); + + setData( model, + 'foo' + + '[]' + ); + + const fakeViewElement = view.document.getRoot().getChild( 1 ); + const fakeDomElement = editor.editing.view.domConverter.mapViewToDom( fakeViewElement ); + const fakeWidgetToolbarView = widgetToolbarRepository._toolbarDefinitions.get( 'fake' ).view; + + expect( balloon.view.pin.lastCall.args[ 0 ].target ).to.equal( fakeDomElement ); + + balloon.add( { + stackId: 'custom', + view: customView, + position: { target: {} } + } ); + + balloon.showStack( 'custom' ); + + expect( balloon.visibleView ).to.equal( customView ); + expect( balloon.hasView( fakeWidgetToolbarView ) ).to.equal( true ); + + editor.execute( 'blockQuote' ); + balloon.showStack( 'main' ); + + expect( balloon.visibleView ).to.equal( fakeWidgetToolbarView ); + expect( balloon.hasView( customView ) ).to.equal( true ); + expect( balloon.view.pin.lastCall.args[ 0 ].target ).to.not.equal( fakeDomElement ); + + const newFakeViewElement = view.document.getRoot().getChild( 1 ).getChild( 0 ); + const newFakeDomElement = editor.editing.view.domConverter.mapViewToDom( newFakeViewElement ); + + expect( balloon.view.pin.lastCall.args[ 0 ].target ).to.equal( newFakeDomElement ); + } ); } ); } ); From c39a6158fda93123b95c08887dc3ed432050a890 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Wr=C3=B3bel?= Date: Fri, 19 Jul 2019 17:28:43 +0200 Subject: [PATCH 2/3] Added missing block-quote dev dependency. --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index a7de573a..ece4f579 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ }, "devDependencies": { "@ckeditor/ckeditor5-basic-styles": "^11.1.3", + "@ckeditor/ckeditor5-block-quote": "^11.1.2", "@ckeditor/ckeditor5-clipboard": "^12.0.1", "@ckeditor/ckeditor5-editor-balloon": "^12.2.1", "@ckeditor/ckeditor5-editor-classic": "^12.1.3", From cec3fc7e961efc8201572945e44a89795f4272e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Wr=C3=B3bel?= Date: Mon, 22 Jul 2019 10:44:32 +0200 Subject: [PATCH 3/3] Added test checking balloon positioning with multiple stacks in rotator. --- src/widgettoolbarrepository.js | 2 +- tests/widgettoolbarrepository.js | 37 +++++++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/widgettoolbarrepository.js b/src/widgettoolbarrepository.js index dea4ead2..1c7559dc 100644 --- a/src/widgettoolbarrepository.js +++ b/src/widgettoolbarrepository.js @@ -213,7 +213,7 @@ export default class WidgetToolbarRepository extends Plugin { // Update toolbar position each time stack with toolbar view is switched to visible. // This is in a case target element has changed when toolbar was in invisible stack - // e.g. target image was wrapper by a block quote. + // e.g. target image was wrapped by a block quote. // See https://github.com/ckeditor/ckeditor5-widget/issues/92. this.listenTo( this._balloon, 'change:visibleView', () => { for ( const definition of this._toolbarDefinitions.values() ) { diff --git a/tests/widgettoolbarrepository.js b/tests/widgettoolbarrepository.js index 1dce9411..98c333c6 100644 --- a/tests/widgettoolbarrepository.js +++ b/tests/widgettoolbarrepository.js @@ -333,7 +333,42 @@ describe( 'WidgetToolbarRepository', () => { view.domConverter.viewToDom( fakeChildViewElement ) ); } ); - it( 'should update position when is switched in rotator to a visible panel', () => { + it( 'should not update balloon position when toolbar is in not visible stack', () => { + const customView = new View(); + + sinon.spy( balloon.view, 'pin' ); + + widgetToolbarRepository.register( 'fake', { + items: editor.config.get( 'fake.toolbar' ), + getRelatedElement: getSelectedFakeWidget + } ); + + setData( model, + 'foo' + + '[]' + ); + + balloon.add( { + stackId: 'custom', + view: customView, + position: { target: {} } + } ); + + balloon.showStack( 'custom' ); + + const fakeWidgetToolbarView = widgetToolbarRepository._toolbarDefinitions.get( 'fake' ).view; + + expect( balloon.visibleView ).to.equal( customView ); + expect( balloon.hasView( fakeWidgetToolbarView ) ).to.equal( true ); + + const spy = testUtils.sinon.spy( balloon, 'updatePosition' ); + + editor.ui.fire( 'update' ); + + sinon.assert.notCalled( spy ); + } ); + + it( 'should update balloon position when stack with toolbar is switched in rotator to visible', () => { const view = editor.editing.view; const customView = new View();