瀏覽代碼

Refresh toolbar position when toolbar view is switched to visible in rotator.

Oskar Wróbel 6 年之前
父節點
當前提交
49887adefc

+ 13 - 0
packages/ckeditor5-widget/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 );
+					}
+				}
+			} );
 		}
 	}
 

+ 48 - 1
packages/ckeditor5-widget/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,
+				'<paragraph>foo</paragraph>' +
+				'[<fake-widget></fake-widget>]'
+			);
+
+			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 );
+		} );
 	} );
 } );