Bläddra i källkod

Added more tests.

Maciej Bukowski 7 år sedan
förälder
incheckning
766bf9d1d4

+ 23 - 5
packages/ckeditor5-widget/src/widgettoolbar.js

@@ -110,9 +110,9 @@ export default class WidgetToolbar extends Plugin {
 			/**
 			 * Toolbar with the given id was already added.
 			 *
-			 * @error duplicated-widget-toolbar
+			 * @error widget-toolbar-duplicated
 			 */
-			throw new Error( 'duplicated-widget-toolbar: Toolbar with the given id was already added.', { toolbarId } )
+			throw new Error( 'widget-toolbar-duplicated: Toolbar with the given id was already added.', { toolbarId } )
 		}
 
 		this._toolbars.set( toolbarId, {
@@ -130,10 +130,28 @@ export default class WidgetToolbar extends Plugin {
 	remove( toolbarId ) {
 		const toolbar = this._toolbars.get( toolbarId );
 
+		if ( !toolbar ) {
+			/**
+			 * Toolbar with the given id was already added.
+			 *
+			 * @error widget-toolbar-does-not-exist
+			 */
+			throw new Error( 'widget-toolbar-does-not-exist' );
+		}
+
 		this._hideToolbar( toolbar );
 		this._toolbars.delete( toolbarId );
 	}
 
+	/**
+	 * Returns `true` when a toolbar with the given id is present in the toolbar collection.
+	 *
+	 * @param {String} toolbarId Toolbar identificator.
+	 */
+	has( toolbarId ) {
+		return this._toolbars.has( toolbarId );
+	}
+
 	/**
 	 * Iterates over stored toolbars and makes them visible or hidden.
 	 *
@@ -156,7 +174,7 @@ export default class WidgetToolbar extends Plugin {
 	 * @param {Object} toolbar
 	 */
 	_hideToolbar( toolbar ) {
-		if ( !this._isVisible( toolbar ) ) {
+		if ( !this._isToolbarVisible( toolbar ) ) {
 			return;
 		}
 
@@ -170,7 +188,7 @@ export default class WidgetToolbar extends Plugin {
 	 * @param {Object} toolbar
 	 */
 	_showToolbar( toolbar ) {
-		if ( this._isVisible( toolbar ) ) {
+		if ( this._isToolbarVisible( toolbar ) ) {
 			repositionContextualBalloon( this.editor );
 		} else if ( !this._balloon.hasView( toolbar.view ) ) {
 			this._balloon.add( {
@@ -185,7 +203,7 @@ export default class WidgetToolbar extends Plugin {
 	 * @private
 	 * @param {Object} toolbar
 	 */
-	_isVisible( toolbar ) {
+	_isToolbarVisible( toolbar ) {
 		return this._balloon.visibleView == toolbar.view;
 	}
 }

+ 99 - 13
packages/ckeditor5-widget/tests/widgettoolbar.js

@@ -78,7 +78,57 @@ describe( 'WidgetToolbar', () => {
 					toolbarItems: editor.config.get( 'fake.toolbar' ),
 					isVisible: () => false
 				} );
-			} ).to.throw( /duplicated-widget-toolbar/ );
+			} ).to.throw( /widget-toolbar-duplicated/ );
+		} );
+	} );
+
+	describe( 'remove', () => {
+		it( 'should remove given widget toolbar', () => {
+			widgetToolbar.add( 'fake', {
+				toolbarItems: editor.config.get( 'fake.toolbar' ),
+				isVisible: () => false
+			} );
+
+			widgetToolbar.remove( 'fake' );
+
+			expect( widgetToolbar._toolbars.size ).to.equal( 0 );
+		} );
+
+		it( 'should throw an error if a toolbar does not exist', () => {
+			widgetToolbar.add( 'foo', {
+				toolbarItems: editor.config.get( 'fake.toolbar' ),
+				isVisible: () => false
+			} );
+
+			expect( () => {
+				widgetToolbar.remove( 'bar' );
+			} ).to.throw( /widget-toolbar-does-not-exist/ );
+		} );
+	} );
+
+	describe( 'has', () => {
+		it( 'should return `true` when a toolbar with given id was added', () => {
+			widgetToolbar.add( 'foo', {
+				toolbarItems: editor.config.get( 'fake.toolbar' ),
+				isVisible: () => false
+			} );
+
+			expect( widgetToolbar.has( 'foo' ) ).to.be.true;
+		} );
+
+		it( 'should return `false` when a toolbar with given id was not added', () => {
+			widgetToolbar.add( 'foo', {
+				toolbarItems: editor.config.get( 'fake.toolbar' ),
+				isVisible: () => false
+			} );
+
+			expect( widgetToolbar.has( 'bar' ) ).to.be.false;
+		} );
+	} );
+
+	describe( 'integration tests', () => {
+		beforeEach( () => {
+			editor.ui.focusTracker.isFocused = true;
 		} );
 
 		it( 'should show widget toolbar when the `isVisible` callback returns true', () => {
@@ -91,8 +141,6 @@ describe( 'WidgetToolbar', () => {
 				}
 			} );
 
-			editor.ui.focusTracker.isFocused = true;
-
 			setData( model, '<paragraph>foo</paragraph>[<fake-widget></fake-widget>]' );
 
 			const fakeWidgetToolbarView = widgetToolbar._toolbars.get( 'fake' ).view;
@@ -110,8 +158,6 @@ describe( 'WidgetToolbar', () => {
 				}
 			} );
 
-			editor.ui.focusTracker.isFocused = true;
-
 			setData( model, '[<paragraph>foo</paragraph>]<fake-widget></fake-widget>' );
 
 			expect( balloon.visibleView ).to.equal( null );
@@ -127,24 +173,62 @@ describe( 'WidgetToolbar', () => {
 				}
 			} );
 
-			editor.ui.focusTracker.isFocused = true;
+			setData( model, '<paragraph>foo</paragraph>[<fake-widget></fake-widget>]' );
 
-			setData( model, '[<paragraph>foo</paragraph>]<fake-widget></fake-widget>' );
+			model.change( writer => {
+				// Select the paragraph content.
+				writer.setSelection( model.document.getRoot().getChild( 0 ), 'in' );
+			} );
 
 			expect( balloon.visibleView ).to.equal( null );
 		} );
-	} );
 
-	describe( 'remove', () => {
-		it( 'should remove given widget toolbar', () => {
+		it( 'should update toolbar position when other widget is being selected', () => {
 			widgetToolbar.add( 'fake', {
 				toolbarItems: editor.config.get( 'fake.toolbar' ),
-				isVisible: () => false
+				isVisible: selection => {
+					const el = selection.getSelectedElement();
+
+					return el && isWidget( el );
+				}
 			} );
 
-			widgetToolbar.remove( 'fake' );
+			setData( model, '[<fake-widget></fake-widget>]<fake-widget></fake-widget>' );
 
-			expect( widgetToolbar._toolbars.size ).to.equal( 0 );
+			model.change( writer => {
+				// Select the second widget.
+				writer.setSelection( model.document.getRoot().getChild( 1 ), 'on' );
+			} );
+
+			const fakeWidgetToolbarView = widgetToolbar._toolbars.get( 'fake' ).view;
+
+			expect( balloon.visibleView ).to.equal( fakeWidgetToolbarView );
+		} );
+
+		it( 'should be able to show toolbar for elements inside the widget', () => {
+			widgetToolbar.add( 'fake', {
+				toolbarItems: editor.config.get( 'fake.toolbar' ),
+				isVisible: selection => {
+					const pos = selection.getFirstPosition();
+					let node = pos.parent;
+
+					while( node ) {
+						if ( node.is( 'element' ) && isWidget( node ) ) {
+							return true;
+						}
+
+						node = node.parent;
+					}
+
+					return false;
+				}
+			} );
+
+			setData( model, '<fake-widget>[foo]</fake-widget>' );
+
+			const fakeWidgetToolbarView = widgetToolbar._toolbars.get( 'fake' ).view;
+
+			expect( balloon.visibleView ).to.equal( fakeWidgetToolbarView );
 		} );
 	} );
 
@@ -179,6 +263,8 @@ describe( 'WidgetToolbar', () => {
 				allowWhere: '$block',
 			} );
 
+			schema.extend( '$text', { allowIn: 'fake-widget' } );
+
 			const conversion = editor.conversion;
 
 			conversion.for( 'dataDowncast' ).add( downcastElementToElement( {