Przeglądaj źródła

Merge branch 'master' into t/260

Aleksander Nowodzinski 8 lat temu
rodzic
commit
50f90d158c
23 zmienionych plików z 279 dodań i 212 usunięć
  1. 1 1
      packages/ckeditor5-ui/package.json
  2. 9 0
      packages/ckeditor5-ui/src/componentfactory.js
  3. 4 0
      packages/ckeditor5-ui/src/dropdown/dropdownmodel.jsdoc
  4. 4 0
      packages/ckeditor5-ui/src/dropdown/list/listdropdownmodel.jsdoc
  5. 4 0
      packages/ckeditor5-ui/src/dropdown/list/listdropdownview.jsdoc
  6. 19 0
      packages/ckeditor5-ui/src/toolbar/contextual/contextualtoolbar.js
  7. 2 2
      packages/ckeditor5-ui/src/toolbar/normalizetoolbarconfig.js
  8. 1 1
      packages/ckeditor5-ui/src/toolbar/toolbarview.js
  9. 2 2
      packages/ckeditor5-ui/tests/_utils/utils.js
  10. 17 2
      packages/ckeditor5-ui/tests/componentfactory.js
  11. 12 11
      packages/ckeditor5-ui/tests/manual/contextualballoon/contextualballoon.js
  12. 21 19
      packages/ckeditor5-ui/tests/manual/contextualballoon/externalchanges.js
  13. 20 19
      packages/ckeditor5-ui/tests/manual/contextualtoolbar/contextualtoolbar.js
  14. 13 12
      packages/ckeditor5-ui/tests/manual/imagetoolbar/imagetoolbar.js
  15. 46 44
      packages/ckeditor5-ui/tests/manual/tickets/170/1.js
  16. 30 28
      packages/ckeditor5-ui/tests/manual/tickets/198/1.js
  17. 6 5
      packages/ckeditor5-ui/tests/manual/tickets/228/1.js
  18. 11 10
      packages/ckeditor5-ui/tests/manual/tickets/76/1.js
  19. 8 7
      packages/ckeditor5-ui/tests/notification/notification.js
  20. 1 1
      packages/ckeditor5-ui/tests/panel/balloon/balloonpanelview.js
  21. 23 22
      packages/ckeditor5-ui/tests/panel/balloon/contextualballoon.js
  22. 24 25
      packages/ckeditor5-ui/tests/toolbar/contextual/contextualtoolbar.js
  23. 1 1
      packages/ckeditor5-ui/tests/toolbar/sticky/stickytoolbarview.js

+ 1 - 1
packages/ckeditor5-ui/package.json

@@ -23,7 +23,7 @@
     "@ckeditor/ckeditor5-typing": "^0.9.1",
     "@ckeditor/ckeditor5-undo": "^0.8.1",
     "del": "^2.2.0",
-    "eslint-config-ckeditor5": "^1.0.0",
+    "eslint-config-ckeditor5": "^1.0.5",
     "gulp": "^3.9.1",
     "guppy-pre-commit": "^0.4.0",
     "lodash-cli": "^4"

+ 9 - 0
packages/ckeditor5-ui/src/componentfactory.js

@@ -42,6 +42,15 @@ export default class ComponentFactory {
 		this._components = new Map();
 	}
 
+	/**
+	 * Returns iterator of component names.
+	 *
+	 * @returns {Iterator.<String>}
+	 */
+	* names() {
+		yield* this._components.keys();
+	}
+
 	/**
 	 * Registers a component factory.
 	 *

+ 4 - 0
packages/ckeditor5-ui/src/dropdown/dropdownmodel.jsdoc

@@ -3,6 +3,10 @@
  * For licensing, see LICENSE.md.
  */
 
+/**
+ * @module ui/dropdown/dropdownmodel
+ */
+
 /**
  * The basic dropdown model interface.
  *

+ 4 - 0
packages/ckeditor5-ui/src/dropdown/list/listdropdownmodel.jsdoc

@@ -3,6 +3,10 @@
  * For licensing, see LICENSE.md.
  */
 
+/**
+ * @module ui/dropdown/list/listdropdownmodel
+ */
+
 /**
  * The list dropdown model interface.
  *

+ 4 - 0
packages/ckeditor5-ui/src/dropdown/list/listdropdownview.jsdoc

@@ -3,6 +3,10 @@
  * For licensing, see LICENSE.md.
  */
 
+/**
+ * @module ui/dropdown/list/createlistdropdown
+ */
+
 /**
  * The list dropdown view.
  *

+ 19 - 0
packages/ckeditor5-ui/src/toolbar/contextual/contextualtoolbar.js

@@ -269,3 +269,22 @@ function getBalloonPositions( isBackward ) {
 		defaultPositions.northEastArrowSouthWest
 	];
 }
+
+/**
+ * Contextual toolbar configuration. Used by the {@link module:ui/toolbar/contextual/contextualtoolbar~ContextualToolbar}
+ * feature.
+ *
+ *		const config = {
+ *			contextualToolbar: [ 'bold', 'italic', 'undo', 'redo' ]
+ *		};
+ *
+ * You can also use `'|'` to create a separator between groups of items:
+ *
+ *		const config = {
+ *			contextualToolbar: [ 'bold', 'italic', | 'undo', 'redo' ]
+ *		};
+ *
+ * Read also about configuring the main editor toolbar in {@link module:core/editor/editorconfig~EditorConfig#toolbar}.
+ *
+ * @member {Array.<String>} module:core/editor/editorconfig~EditorConfig#contextualToolbar
+ */

+ 2 - 2
packages/ckeditor5-ui/src/toolbar/normalizetoolbarconfig.js

@@ -8,11 +8,11 @@
  */
 
 /**
- * Normalizes the toolbar configuration (`config.toolbar`), which may be defined as an `Array`
+ * Normalizes the toolbar configuration (`config.toolbar`), which may be defined as an `Array`:
  *
  * 		toolbar: [ 'headings', 'bold', 'italic', 'link', 'unlink', ... ]
  *
- * or an `Object`
+ * or an `Object`:
  *
  *		toolbar: {
  *			items: [ 'headings', 'bold', 'italic', 'link', 'unlink', ... ],

+ 1 - 1
packages/ckeditor5-ui/src/toolbar/toolbarview.js

@@ -117,7 +117,7 @@ export default class ToolbarView extends View {
 	 * A utility which expands a plain toolbar configuration into
 	 * {@link module:ui/toolbar/toolbarview~ToolbarView#items} using a given component factory.
 	 *
-	 * @param {Array} config The toolbar config.
+	 * @param {Array.<String>} config The toolbar items config.
 	 * @param {module:ui/componentfactory~ComponentFactory} factory A factory producing toolbar items.
 	 */
 	fillFromConfig( config, factory ) {

+ 2 - 2
packages/ckeditor5-ui/tests/_utils/utils.js

@@ -41,8 +41,8 @@ const utils = {
 
 					regionCollection.setParent(
 						typeof callbackOrSelector == 'string' ?
-								document.querySelector( callbackOrSelector )							:
-								callbackOrSelector( this.element )
+							document.querySelector( callbackOrSelector ) :
+							callbackOrSelector( this.element )
 					);
 				}
 			}

+ 17 - 2
packages/ckeditor5-ui/tests/componentfactory.js

@@ -21,7 +21,22 @@ describe( 'ComponentFactory', () => {
 		} );
 	} );
 
-	describe( 'add', () => {
+	describe( 'names()', () => {
+		it( 'returns iterator', () => {
+			const names = factory.names();
+
+			expect( names.next ).to.be.a( 'function' );
+		} );
+
+		it( 'returns iterator of command names', () => {
+			factory.add( 'foo', () => {} );
+			factory.add( 'bar', () => {} );
+
+			expect( Array.from( factory.names() ) ).to.have.members( [ 'foo', 'bar' ] );
+		} );
+	} );
+
+	describe( 'add()', () => {
 		it( 'throws when trying to override already registered component', () => {
 			factory.add( 'foo', () => {} );
 
@@ -31,7 +46,7 @@ describe( 'ComponentFactory', () => {
 		} );
 	} );
 
-	describe( 'create', () => {
+	describe( 'create()', () => {
 		it( 'throws when trying to create a component which has not been registered', () => {
 			expect( () => {
 				factory.create( 'foo' );

+ 12 - 11
packages/ckeditor5-ui/tests/manual/contextualballoon/contextualballoon.js

@@ -10,14 +10,15 @@ import ArticlePresets from '@ckeditor/ckeditor5-presets/src/article';
 import ContextualToolbar from '@ckeditor/ckeditor5-ui/src/toolbar/contextual/contextualtoolbar';
 
 // Finally the editor.
-ClassicEditor.create( document.querySelector( '#editor' ), {
-	plugins: [ ArticlePresets, ContextualToolbar ],
-	toolbar: [ 'bold', 'link' ],
-	contextualToolbar: [ 'bold', 'link' ]
-} )
-.then( editor => {
-	window.editor = editor;
-} )
-.catch( err => {
-	console.error( err.stack );
-} );
+ClassicEditor
+	.create( document.querySelector( '#editor' ), {
+		plugins: [ ArticlePresets, ContextualToolbar ],
+		toolbar: [ 'bold', 'link' ],
+		contextualToolbar: [ 'bold', 'link' ]
+	} )
+	.then( editor => {
+		window.editor = editor;
+	} )
+	.catch( err => {
+		console.error( err.stack );
+	} );

+ 21 - 19
packages/ckeditor5-ui/tests/manual/contextualballoon/externalchanges.js

@@ -15,27 +15,29 @@ import Position from '@ckeditor/ckeditor5-engine/src/model/position';
 import Range from '@ckeditor/ckeditor5-engine/src/model/range';
 
 // Editor for the external insert.
-ClassicEditor.create( document.querySelector( '#editor-insert' ), {
-	plugins: [ ArticlePresets, ContextualToolbar ],
-	toolbar: [ 'bold', 'link' ],
-	contextualToolbar: [ 'bold', 'link' ]
-} )
-.then( editor => {
-	const element = document.querySelector( '#button-insert' );
-
-	element.addEventListener( 'click', () => {
-		element.disabled = true;
-		startExternalInsert( editor );
-	} );
-} )
-.catch( err => console.error( err.stack ) );
+ClassicEditor
+	.create( document.querySelector( '#editor-insert' ), {
+		plugins: [ ArticlePresets, ContextualToolbar ],
+		toolbar: [ 'bold', 'link' ],
+		contextualToolbar: [ 'bold', 'link' ]
+	} )
+	.then( editor => {
+		const element = document.querySelector( '#button-insert' );
+
+		element.addEventListener( 'click', () => {
+			element.disabled = true;
+			startExternalInsert( editor );
+		} );
+	} )
+	.catch( err => console.error( err.stack ) );
 
 // Editor for the external delete.
-ClassicEditor.create( document.querySelector( '#editor-delete' ), {
-	plugins: [ ArticlePresets, ContextualToolbar ],
-	toolbar: [ 'bold', 'link' ],
-	contextualToolbar: [ 'bold', 'link' ]
-} )
+ClassicEditor
+	.create( document.querySelector( '#editor-delete' ), {
+		plugins: [ ArticlePresets, ContextualToolbar ],
+		toolbar: [ 'bold', 'link' ],
+		contextualToolbar: [ 'bold', 'link' ]
+	} )
 	.then( editor => {
 		const element = document.querySelector( '#button-delete' );
 

+ 20 - 19
packages/ckeditor5-ui/tests/manual/contextualtoolbar/contextualtoolbar.js

@@ -10,25 +10,26 @@ import ArticlePresets from '@ckeditor/ckeditor5-presets/src/article';
 import ContextualToolbar from '../../../src/toolbar/contextual/contextualtoolbar';
 import Range from '@ckeditor/ckeditor5-engine/src/model/range';
 
-ClassicEditor.create( document.querySelector( '#editor' ), {
-	plugins: [ ArticlePresets, ContextualToolbar ],
-	toolbar: [ 'bold', 'italic', 'link', 'undo', 'redo' ],
-	contextualToolbar: [ 'bold', 'italic', 'link' ]
-} )
-.then( editor => {
-	window.editor = editor;
+ClassicEditor
+	.create( document.querySelector( '#editor' ), {
+		plugins: [ ArticlePresets, ContextualToolbar ],
+		toolbar: [ 'bold', 'italic', 'link', 'undo', 'redo' ],
+		contextualToolbar: [ 'bold', 'italic', 'link' ]
+	} )
+	.then( editor => {
+		window.editor = editor;
 
-	const contextualToolbar = editor.plugins.get( 'ContextualToolbar' );
+		const contextualToolbar = editor.plugins.get( 'ContextualToolbar' );
 
-	contextualToolbar.on( 'show', evt => {
-		const selectionRange = editor.document.selection.getFirstRange();
-		const blockRange = Range.createOn( editor.document.getRoot().getChild( 0 ) );
+		contextualToolbar.on( 'show', evt => {
+			const selectionRange = editor.document.selection.getFirstRange();
+			const blockRange = Range.createOn( editor.document.getRoot().getChild( 0 ) );
 
-		if ( selectionRange.containsRange( blockRange ) || selectionRange.isIntersecting( blockRange ) ) {
-			evt.stop();
-		}
-	}, { priority: 'high' } );
-} )
-.catch( err => {
-	console.error( err.stack );
-} );
+			if ( selectionRange.containsRange( blockRange ) || selectionRange.isIntersecting( blockRange ) ) {
+				evt.stop();
+			}
+		}, { priority: 'high' } );
+	} )
+	.catch( err => {
+		console.error( err.stack );
+	} );

+ 13 - 12
packages/ckeditor5-ui/tests/manual/imagetoolbar/imagetoolbar.js

@@ -19,18 +19,19 @@ import Template from '../../../src/template';
 import ToolbarView from '../../../src/toolbar/toolbarview';
 import BalloonPanelView from '../../../src/panel/balloon/balloonpanelview';
 
-ClassicEditor.create( document.querySelector( '#editor' ), {
-	plugins: [ Enter, Typing, Paragraph, Undo, Bold, Italic, Image ],
-	toolbar: [ 'bold', 'italic', 'undo', 'redo' ]
-} )
-.then( editor => {
-	createImageToolbar( editor );
-
-	window.editor = editor;
-} )
-.catch( err => {
-	console.error( err.stack );
-} );
+ClassicEditor
+	.create( document.querySelector( '#editor' ), {
+		plugins: [ Enter, Typing, Paragraph, Undo, Bold, Italic, Image ],
+		toolbar: [ 'bold', 'italic', 'undo', 'redo' ]
+	} )
+	.then( editor => {
+		createImageToolbar( editor );
+
+		window.editor = editor;
+	} )
+	.catch( err => {
+		console.error( err.stack );
+	} );
 
 function createImageToolbar( editor ) {
 	// Create a plain toolbar instance.

+ 46 - 44
packages/ckeditor5-ui/tests/manual/tickets/170/1.js

@@ -13,51 +13,53 @@ import BalloonPanelView from '../../../../src/panel/balloon/balloonpanelview';
 document.querySelector( '.container-outer' ).scrollTop = 450;
 
 // Init editor with balloon attached to the target element.
-ClassicEditor.create( document.querySelector( '#editor-attach' ), {
-	plugins: [ ArticlePresets ],
-	toolbar: [ 'bold', 'italic', 'undo', 'redo' ]
-} )
-.then( editor => {
-	const panel = new BalloonPanelView();
-
-	panel.element.innerHTML = 'Balloon content.';
-	editor.ui.view.body.add( panel );
-
-	editor.ui.view.element.querySelector( '.ck-editor__editable' ).scrollTop = 360;
-
-	panel.init();
-	panel.attachTo( {
-		target: editor.ui.view.element.querySelector( '.ck-editor__editable p strong' ),
-		limiter: editor.ui.view.editableElement
-	} );
+ClassicEditor
+	.create( document.querySelector( '#editor-attach' ), {
+		plugins: [ ArticlePresets ],
+		toolbar: [ 'bold', 'italic', 'undo', 'redo' ]
+	} )
+	.then( editor => {
+		const panel = new BalloonPanelView();
 
-	window.attachEditor = editor;
-} )
-.catch( err => {
-	console.error( err.stack );
-} );
+		panel.element.innerHTML = 'Balloon content.';
+		editor.ui.view.body.add( panel );
 
-// Init editor with balloon sticked to the target element.
-ClassicEditor.create( document.querySelector( '#editor-stick' ), {
-	plugins: [ ArticlePresets ],
-	toolbar: [ 'bold', 'italic', 'undo', 'redo' ]
-} )
-.then( editor => {
-	const panel = new BalloonPanelView();
-
-	panel.element.innerHTML = 'Balloon content.';
-	editor.ui.view.body.add( panel );
-
-	editor.ui.view.element.querySelector( '.ck-editor__editable' ).scrollTop = 360;
-
-	panel.init();
-	panel.pin( {
-		target: editor.ui.view.element.querySelector( '.ck-editor__editable p strong' ),
-		limiter: editor.ui.view.editableElement
+		editor.ui.view.element.querySelector( '.ck-editor__editable' ).scrollTop = 360;
+
+		panel.init();
+		panel.attachTo( {
+			target: editor.ui.view.element.querySelector( '.ck-editor__editable p strong' ),
+			limiter: editor.ui.view.editableElement
+		} );
+
+		window.attachEditor = editor;
+	} )
+	.catch( err => {
+		console.error( err.stack );
 	} );
 
-	window.stickEditor = editor;
-} )
-.catch( err => {
-	console.error( err.stack );
-} );
+// Init editor with balloon sticked to the target element.
+ClassicEditor
+	.create( document.querySelector( '#editor-stick' ), {
+		plugins: [ ArticlePresets ],
+		toolbar: [ 'bold', 'italic', 'undo', 'redo' ]
+	} )
+	.then( editor => {
+		const panel = new BalloonPanelView();
+
+		panel.element.innerHTML = 'Balloon content.';
+		editor.ui.view.body.add( panel );
+
+		editor.ui.view.element.querySelector( '.ck-editor__editable' ).scrollTop = 360;
+
+		panel.init();
+		panel.pin( {
+			target: editor.ui.view.element.querySelector( '.ck-editor__editable p strong' ),
+			limiter: editor.ui.view.editableElement
+		} );
+
+		window.stickEditor = editor;
+	} )
+	.catch( err => {
+		console.error( err.stack );
+	} );

+ 30 - 28
packages/ckeditor5-ui/tests/manual/tickets/198/1.js

@@ -15,36 +15,38 @@ import Position from '@ckeditor/ckeditor5-engine/src/model/position';
 import Range from '@ckeditor/ckeditor5-engine/src/model/range';
 
 // Editor for the external insert.
-ClassicEditor.create( document.querySelector( '#editor-insert' ), {
-	plugins: [ ArticlePresets, ContextualToolbar ],
-	toolbar: [ 'undo', 'redo' ],
-	contextualToolbar: [ 'bold', 'italic' ]
-} )
-.then( editor => {
-	const element = document.querySelector( '#button-insert' );
-
-	element.addEventListener( 'click', () => {
-		element.disabled = true;
-		startExternalInsert( editor );
-	} );
-} )
-.catch( err => console.error( err.stack ) );
+ClassicEditor
+	.create( document.querySelector( '#editor-insert' ), {
+		plugins: [ ArticlePresets, ContextualToolbar ],
+		toolbar: [ 'undo', 'redo' ],
+		contextualToolbar: [ 'bold', 'italic' ]
+	} )
+	.then( editor => {
+		const element = document.querySelector( '#button-insert' );
+
+		element.addEventListener( 'click', () => {
+			element.disabled = true;
+			startExternalInsert( editor );
+		} );
+	} )
+	.catch( err => console.error( err.stack ) );
 
 // Editor for the external delete.
-ClassicEditor.create( document.querySelector( '#editor-delete' ), {
-	plugins: [ ArticlePresets, ContextualToolbar ],
-	toolbar: [ 'undo', 'redo' ],
-	contextualToolbar: [ 'bold', 'italic' ]
-} )
-.then( editor => {
-	const element = document.querySelector( '#button-delete' );
-
-	element.addEventListener( 'click', () => {
-		element.disabled = true;
-		startExternalDelete( editor );
-	} );
-} )
-.catch( err => console.error( err.stack ) );
+ClassicEditor
+	.create( document.querySelector( '#editor-delete' ), {
+		plugins: [ ArticlePresets, ContextualToolbar ],
+		toolbar: [ 'undo', 'redo' ],
+		contextualToolbar: [ 'bold', 'italic' ]
+	} )
+	.then( editor => {
+		const element = document.querySelector( '#button-delete' );
+
+		element.addEventListener( 'click', () => {
+			element.disabled = true;
+			startExternalDelete( editor );
+		} );
+	} )
+	.catch( err => console.error( err.stack ) );
 
 function wait( delay ) {
 	return new Promise( resolve => {

+ 6 - 5
packages/ckeditor5-ui/tests/manual/tickets/228/1.js

@@ -8,8 +8,9 @@
 import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
 import ArticlePresets from '@ckeditor/ckeditor5-presets/src/article';
 
-ClassicEditor.create( document.querySelector( '#editor' ), {
-	plugins: [ ArticlePresets ],
-	toolbar: [ 'headings' ],
-} )
-.catch( err => console.error( err.stack ) );
+ClassicEditor
+	.create( document.querySelector( '#editor' ), {
+		plugins: [ ArticlePresets ],
+		toolbar: [ 'headings' ],
+	} )
+	.catch( err => console.error( err.stack ) );

+ 11 - 10
packages/ckeditor5-ui/tests/manual/tickets/76/1.js

@@ -11,13 +11,14 @@ import Typing from '@ckeditor/ckeditor5-typing/src/typing';
 import Heading from '@ckeditor/ckeditor5-heading/src/heading';
 import Link from '@ckeditor/ckeditor5-link/src/link';
 
-ClassicEditor.create( document.querySelector( '#editor' ), {
-	plugins: [ Enter, Typing, Heading, Link ],
-	toolbar: [ 'link' ]
-} )
-.then( editor => {
-	window.editor = editor;
-} )
-.catch( err => {
-	console.error( err.stack );
-} );
+ClassicEditor
+	.create( document.querySelector( '#editor' ), {
+		plugins: [ Enter, Typing, Heading, Link ],
+		toolbar: [ 'link' ]
+	} )
+	.then( editor => {
+		window.editor = editor;
+	} )
+	.catch( err => {
+		console.error( err.stack );
+	} );

+ 8 - 7
packages/ckeditor5-ui/tests/notification/notification.js

@@ -15,13 +15,14 @@ describe( 'Notification', () => {
 	testUtils.createSinonSandbox();
 
 	beforeEach( () => {
-		return VirtualTestEditor.create( {
-			plugins: [ Notification ]
-		} )
-		.then( newEditor => {
-			editor = newEditor;
-			notification = editor.plugins.get( Notification );
-		} );
+		return VirtualTestEditor
+			.create( {
+				plugins: [ Notification ]
+			} )
+			.then( newEditor => {
+				editor = newEditor;
+				notification = editor.plugins.get( Notification );
+			} );
 	} );
 
 	describe( 'init()', () => {

+ 1 - 1
packages/ckeditor5-ui/tests/panel/balloon/balloonpanelview.js

@@ -186,7 +186,7 @@ describe( 'BalloonPanelView', () => {
 				}
 			};
 
-			testUtils.sinon.stub( global, 'window', windowStub );
+			testUtils.sinon.stub( global, 'window' ).value( windowStub );
 		} );
 
 		it( 'should use default options', () => {

+ 23 - 22
packages/ckeditor5-ui/tests/panel/balloon/contextualballoon.js

@@ -19,29 +19,30 @@ describe( 'ContextualBalloon', () => {
 		editorElement = document.createElement( 'div' );
 		document.body.appendChild( editorElement );
 
-		return ClassicTestEditor.create( editorElement, {
-			plugins: [ ContextualBalloon ]
-		} )
-		.then( newEditor => {
-			editor = newEditor;
-			balloon = editor.plugins.get( ContextualBalloon );
-
-			// We don't need to execute BalloonPanel pin and attachTo methods
-			// it's enough to check if was called with the proper data.
-			sinon.stub( balloon.view, 'attachTo', () => {} );
-			sinon.stub( balloon.view, 'pin', () => {} );
-
-			viewA = new View();
-			viewB = new View();
-
-			// Add viewA to the pane and init viewB.
-			balloon.add( {
-				view: viewA,
-				position: { target: 'fake' }
-			} );
+		return ClassicTestEditor
+			.create( editorElement, {
+				plugins: [ ContextualBalloon ]
+			} )
+			.then( newEditor => {
+				editor = newEditor;
+				balloon = editor.plugins.get( ContextualBalloon );
+
+				// We don't need to execute BalloonPanel pin and attachTo methods
+				// it's enough to check if was called with the proper data.
+				sinon.stub( balloon.view, 'attachTo' ).returns( {} );
+				sinon.stub( balloon.view, 'pin' ).returns( {} );
+
+				viewA = new View();
+				viewB = new View();
+
+				// Add viewA to the pane and init viewB.
+				balloon.add( {
+					view: viewA,
+					position: { target: 'fake' }
+				} );
 
-			viewB.init();
-		} );
+				viewB.init();
+			} );
 	} );
 
 	afterEach( () => {

+ 24 - 25
packages/ckeditor5-ui/tests/toolbar/contextual/contextualtoolbar.js

@@ -25,26 +25,27 @@ describe( 'ContextualToolbar', () => {
 		editorElement = document.createElement( 'div' );
 		document.body.appendChild( editorElement );
 
-		return ClassicTestEditor.create( editorElement, {
-			plugins: [ Paragraph, Bold, Italic, ContextualToolbar ],
-			contextualToolbar: [ 'bold', 'italic' ]
-		} )
-		.then( newEditor => {
-			newEditor.editing.view.attachDomRoot( editorElement );
-
-			editor = newEditor;
-			contextualToolbar = editor.plugins.get( ContextualToolbar );
-			balloon = editor.plugins.get( ContextualBalloon );
-
-			// There is no point to execute BalloonPanelView attachTo and pin methods so lets override it.
-			sandbox.stub( balloon.view, 'attachTo', () => {} );
-			sandbox.stub( balloon.view, 'pin', () => {} );
-
-			// Focus the engine.
-			editor.editing.view.isFocused = true;
+		return ClassicTestEditor
+			.create( editorElement, {
+				plugins: [ Paragraph, Bold, Italic, ContextualToolbar ],
+				contextualToolbar: [ 'bold', 'italic' ]
+			} )
+			.then( newEditor => {
+				newEditor.editing.view.attachDomRoot( editorElement );
+
+				editor = newEditor;
+				contextualToolbar = editor.plugins.get( ContextualToolbar );
+				balloon = editor.plugins.get( ContextualBalloon );
+
+				// There is no point to execute BalloonPanelView attachTo and pin methods so lets override it.
+				sandbox.stub( balloon.view, 'attachTo' ).returns( {} );
+				sandbox.stub( balloon.view, 'pin' ).returns( {} );
+
+				// Focus the engine.
+				editor.editing.view.isFocused = true;
 
-			contextualToolbar.toolbarView.init();
-		} );
+				contextualToolbar.toolbarView.init();
+			} );
 	} );
 
 	afterEach( () => {
@@ -276,7 +277,7 @@ describe( 'ContextualToolbar', () => {
 		let removeBalloonSpy;
 
 		beforeEach( () => {
-			removeBalloonSpy = sandbox.stub( balloon, 'remove', () => {} );
+			removeBalloonSpy = sandbox.stub( balloon, 'remove' ).returns( {} );
 			editor.editing.view.isFocused = true;
 		} );
 
@@ -397,8 +398,7 @@ describe( 'ContextualToolbar', () => {
 
 			contextualToolbar.fire( '_selectionChangeDebounced' );
 
-			// Stubbing getters doesn't wor for sandbox.
-			const stub = sinon.stub( balloon, 'visibleView', { get: () => contextualToolbar.toolbarView } );
+			const stub = sinon.stub( balloon, 'visibleView' ).get( () => contextualToolbar.toolbarView );
 
 			sinon.assert.calledOnce( showPanelSpy );
 			sinon.assert.notCalled( hidePanelSpy );
@@ -416,8 +416,7 @@ describe( 'ContextualToolbar', () => {
 
 			contextualToolbar.fire( '_selectionChangeDebounced' );
 
-			// Stubbing getters doesn't wor for sandbox.
-			const stub = sinon.stub( balloon, 'visibleView', { get: () => null } );
+			const stub = sinon.stub( balloon, 'visibleView' ).get( () => null );
 
 			sinon.assert.calledOnce( showPanelSpy );
 			sinon.assert.notCalled( hidePanelSpy );
@@ -459,7 +458,7 @@ describe( 'ContextualToolbar', () => {
 		const originalViewRangeToDom = editingView.domConverter.viewRangeToDom;
 
 		// Mock selection rect.
-		sandbox.stub( editingView.domConverter, 'viewRangeToDom', ( ...args ) => {
+		sandbox.stub( editingView.domConverter, 'viewRangeToDom' ).callsFake( ( ...args ) => {
 			const domRange = originalViewRangeToDom.apply( editingView.domConverter, args );
 
 			sandbox.stub( domRange, 'getClientRects' )

+ 1 - 1
packages/ckeditor5-ui/tests/toolbar/sticky/stickytoolbarview.js

@@ -34,7 +34,7 @@ describe( 'StickyToolbarView', () => {
 			scrollY: 0
 		} );
 
-		testUtils.sinon.stub( global, 'window', windowStub );
+		testUtils.sinon.stub( global, 'window' ).value( windowStub );
 
 		document.body.appendChild( element );
 	} );