8
0
Просмотр исходного кода

Merge branch 'master' into t/ckeditor5-image/241

Aleksander Nowodzinski 6 лет назад
Родитель
Сommit
aaf13a2013

+ 12 - 0
packages/ckeditor5-widget/CHANGELOG.md

@@ -1,6 +1,18 @@
 Changelog
 =========
 
+## [11.0.4](https://github.com/ckeditor/ckeditor5-widget/compare/v11.0.3...v11.0.4) (2019-07-10)
+
+Internal changes only (updated dependencies, documentation, etc.).
+
+
+## [11.0.3](https://github.com/ckeditor/ckeditor5-widget/compare/v11.0.2...v11.0.3) (2019-07-04)
+
+### Bug fixes
+
+* A proper `DomConverter` method should be used to map a view to DOM when getting balloon position data. Closes [#87](https://github.com/ckeditor/ckeditor5-widget/issues/87). ([160333a](https://github.com/ckeditor/ckeditor5-widget/commit/160333a))
+
+
 ## [11.0.2](https://github.com/ckeditor/ckeditor5-widget/compare/v11.0.1...v11.0.2) (2019-06-05)
 
 Internal changes only (updated dependencies, documentation, etc.).

+ 18 - 17
packages/ckeditor5-widget/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@ckeditor/ckeditor5-widget",
-  "version": "11.0.2",
+  "version": "11.0.4",
   "description": "Widget API for CKEditor 5.",
   "keywords": [
     "ckeditor",
@@ -9,25 +9,26 @@
     "ckeditor5-lib"
   ],
   "dependencies": {
-    "@ckeditor/ckeditor5-core": "^12.1.1",
-    "@ckeditor/ckeditor5-engine": "^13.1.1",
-    "@ckeditor/ckeditor5-ui": "^13.0.0",
-    "@ckeditor/ckeditor5-utils": "^12.1.1"
+    "@ckeditor/ckeditor5-core": "^12.2.1",
+    "@ckeditor/ckeditor5-engine": "^13.2.1",
+    "@ckeditor/ckeditor5-ui": "^13.0.2",
+    "@ckeditor/ckeditor5-utils": "^13.0.1"
   },
   "devDependencies": {
-    "@ckeditor/ckeditor5-basic-styles": "^11.1.1",
-    "@ckeditor/ckeditor5-clipboard": "^11.0.2",
-    "@ckeditor/ckeditor5-editor-balloon": "^12.1.1",
-    "@ckeditor/ckeditor5-editor-classic": "^12.1.1",
-    "@ckeditor/ckeditor5-enter": "^11.0.2",
-    "@ckeditor/ckeditor5-essentials": "^11.0.2",
-    "@ckeditor/ckeditor5-heading": "^11.0.2",
-    "@ckeditor/ckeditor5-paragraph": "^11.0.2",
-    "@ckeditor/ckeditor5-table": "^13.0.0",
-    "@ckeditor/ckeditor5-typing": "^12.0.2",
-    "@ckeditor/ckeditor5-undo": "^11.0.2",
+    "@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",
+    "@ckeditor/ckeditor5-enter": "^11.0.4",
+    "@ckeditor/ckeditor5-essentials": "^11.0.4",
+    "@ckeditor/ckeditor5-heading": "^11.0.4",
+    "@ckeditor/ckeditor5-paragraph": "^11.0.4",
+    "@ckeditor/ckeditor5-table": "^13.0.2",
+    "@ckeditor/ckeditor5-typing": "^12.1.1",
+    "@ckeditor/ckeditor5-undo": "^11.0.4",
     "eslint": "^5.5.0",
-    "eslint-config-ckeditor5": "^1.0.11",
+    "eslint-config-ckeditor5": "^2.0.0",
     "husky": "^1.3.1",
     "lint-staged": "^7.0.0"
   },

+ 15 - 2
packages/ckeditor5-widget/src/widgettoolbarrepository.js

@@ -126,7 +126,7 @@ export default class WidgetToolbarRepository extends Plugin {
 			 * @error widget-toolbar-duplicated
 			 * @param toolbarId Toolbar id.
 			 */
-			throw new CKEditorError( 'widget-toolbar-duplicated: Toolbar with the given id was already added.', { toolbarId } );
+			throw new CKEditorError( 'widget-toolbar-duplicated: Toolbar with the given id was already added.', this, { toolbarId } );
 		}
 
 		toolbarView.fillFromConfig( items, editor.ui.componentFactory );
@@ -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 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() ) {
+					if ( this._isToolbarVisible( definition ) ) {
+						this._updateToolbarsVisibility( definition );
+					}
+				}
+			} );
 		}
 	}
 
@@ -243,7 +256,7 @@ function getBalloonPositionData( editor, relatedElement ) {
 	const defaultPositions = BalloonPanelView.defaultPositions;
 
 	return {
-		target: editingView.domConverter.viewToDom( relatedElement ),
+		target: editingView.domConverter.mapViewToDom( relatedElement ),
 		positions: [
 			defaultPositions.northArrowSouth,
 			defaultPositions.northArrowSouthWest,

+ 86 - 4
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';
@@ -18,7 +19,7 @@ import View from '@ckeditor/ckeditor5-ui/src/view';
 
 import { setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
 import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils';
-import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
+import { expectToThrowCKEditorError } from '@ckeditor/ckeditor5-utils/tests/_utils/utils';
 
 describe( 'WidgetToolbarRepository', () => {
 	let editor, model, balloon, widgetToolbarRepository, editorElement;
@@ -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' ]
 				}
@@ -82,12 +83,12 @@ describe( 'WidgetToolbarRepository', () => {
 				getRelatedElement: () => null
 			} );
 
-			expect( () => {
+			expectToThrowCKEditorError( () => {
 				widgetToolbarRepository.register( 'fake', {
 					items: editor.config.get( 'fake.toolbar' ),
 					getRelatedElement: () => null
 				} );
-			} ).to.throw( CKEditorError, /^widget-toolbar-duplicated/ );
+			}, /^widget-toolbar-duplicated/, editor );
 		} );
 	} );
 
@@ -331,6 +332,87 @@ describe( 'WidgetToolbarRepository', () => {
 			expect( updatePositionSpy.firstCall.args[ 0 ].position.target ).to.equal(
 				view.domConverter.viewToDom( fakeChildViewElement ) );
 		} );
+
+		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,
+				'<paragraph>foo</paragraph>' +
+				'[<fake-widget></fake-widget>]'
+			);
+
+			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();
+
+			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 );
+		} );
 	} );
 } );