Browse Source

Merge branch t/engine/1186

Internal: Update API usage after merge t/1186 on engine.
Piotr Jasiun 8 years ago
parent
commit
d996bca481

+ 1 - 1
packages/ckeditor5-image/src/image/converters.js

@@ -55,7 +55,7 @@ export function viewFigureToModel() {
 		data.context.pop();
 
 		// Add converted children to model image.
-		conversionApi.batch.insert( modelChildren, modelImage );
+		conversionApi.writer.insert( modelChildren, modelImage );
 
 		// Set model image as conversion result.
 		data.output = modelImage;

+ 1 - 2
packages/ckeditor5-image/src/image/imageengine.js

@@ -35,8 +35,7 @@ export default class ImageEngine extends Plugin {
 	 */
 	init() {
 		const editor = this.editor;
-		const doc = editor.document;
-		const schema = doc.schema;
+		const schema = editor.model.schema;
 		const data = editor.data;
 		const editing = editor.editing;
 		const t = editor.t;

+ 39 - 35
packages/ckeditor5-image/src/imagecaption/imagecaptionengine.js

@@ -35,9 +35,9 @@ export default class ImageCaptionEngine extends Plugin {
 	 */
 	init() {
 		const editor = this.editor;
-		const document = editor.document;
+		const document = editor.model.document;
 		const viewDocument = editor.editing.view;
-		const schema = document.schema;
+		const schema = editor.model.schema;
 		const data = editor.data;
 		const editing = editor.editing;
 		const t = editor.t;
@@ -65,7 +65,7 @@ export default class ImageCaptionEngine extends Plugin {
 		schema.limits.add( 'caption' );
 
 		// Add caption element to each image inserted without it.
-		document.on( 'change', insertMissingModelCaptionElement );
+		document.on( 'change', ( evt, type, data, batch ) => this._insertMissingModelCaptionElement( type, data, batch ) );
 
 		// View to model converter for the data pipeline.
 		buildViewConverter()
@@ -105,7 +105,7 @@ export default class ImageCaptionEngine extends Plugin {
 		}
 
 		// If whole image is selected.
-		const modelSelection = this.editor.document.selection;
+		const modelSelection = this.editor.model.document.selection;
 		const selectedElement = modelSelection.getSelectedElement();
 
 		if ( selectedElement && selectedElement.is( 'image' ) ) {
@@ -150,33 +150,38 @@ export default class ImageCaptionEngine extends Plugin {
 			}
 		}
 	}
-}
-
-// Checks whether data inserted to the model document have image element that has no caption element inside it.
-// If there is none - adds it to the image element.
-//
-// @private
-function insertMissingModelCaptionElement( evt, changeType, data, batch ) {
-	if ( changeType !== 'insert' ) {
-		return;
-	}
 
-	const walker = new ModelTreeWalker( {
-		boundaries: data.range,
-		ignoreElementEnd: true
-	} );
-
-	for ( const value of walker ) {
-		const item = value.item;
+	/**
+	 * Checks whether data inserted to the model document have image element that has no caption element inside it.
+	 * If there is none - adds it to the image element.
+	 *
+	 * @private
+	 * @param {String} changeType Type of change.
+	 * @param {Object} data Change data.
+	 * @param {module:engine/model/batch} batch Bath to with changed will be added.
+	 */
+	_insertMissingModelCaptionElement( changeType, data, batch ) {
+		if ( changeType !== 'insert' ) {
+			return;
+		}
 
-		if ( value.type == 'elementStart' && isImage( item ) && !getCaptionFromImage( item ) ) {
-			batch.document.enqueueChanges( () => {
-				// Make sure that the image does not have caption already.
-				// https://github.com/ckeditor/ckeditor5-image/issues/78
-				if ( !getCaptionFromImage( item ) ) {
-					batch.appendElement( 'caption', item );
-				}
-			} );
+		const walker = new ModelTreeWalker( {
+			boundaries: data.range,
+			ignoreElementEnd: true
+		} );
+
+		for ( const value of walker ) {
+			const item = value.item;
+
+			if ( value.type == 'elementStart' && isImage( item ) && !getCaptionFromImage( item ) ) {
+				this.editor.model.enqueueChange( batch, writer => {
+					// Make sure that the image does not have caption already.
+					// https://github.com/ckeditor/ckeditor5-image/issues/78
+					if ( !getCaptionFromImage( item ) ) {
+						writer.appendElement( 'caption', item );
+					}
+				} );
+			}
 		}
 	}
 }
@@ -230,12 +235,11 @@ function insertViewCaptionAndBind( viewCaption, modelCaption, viewImage, mapper
 	mapper.bindElements( modelCaption, viewCaption );
 }
 
-/**
- * Checks if the provided node or one of its ancestors is a caption element, and returns it.
- *
- * @param {module:engine/model/node~Node} node
- * @returns {module:engine/model/element~Element|null}
- */
+// Checks if the provided node or one of its ancestors is a caption element, and returns it.
+//
+// @private
+// @param {module:engine/model/node~Node} node
+// @returns {module:engine/model/element~Element|null}
 function getParentCaption( node ) {
 	const ancestors = node.getAncestors( { includeSelf: true } );
 	const caption = ancestors.find( ancestor => ancestor.name == 'caption' );

+ 7 - 12
packages/ckeditor5-image/src/imagestyle/imagestylecommand.js

@@ -47,7 +47,7 @@ export default class ImageStyleCommand extends Command {
 	 * @inheritDoc
 	 */
 	refresh() {
-		const element = this.editor.document.selection.getSelectedElement();
+		const element = this.editor.model.document.selection.getSelectedElement();
 
 		this.isEnabled = isImage( element );
 
@@ -64,27 +64,22 @@ export default class ImageStyleCommand extends Command {
 	 * Executes the command.
 	 *
 	 * @fires execute
-	 * @param {Object} options
-	 * @param {module:engine/model/batch~Batch} [options.batch] A batch to collect all the change steps. A new batch will be
-	 * created if this option is not set.
 	 */
-	execute( options = {} ) {
+	execute() {
 		if ( this.value ) {
 			return;
 		}
 
-		const doc = this.editor.document;
-		const imageElement = doc.selection.getSelectedElement();
-
-		doc.enqueueChanges( () => {
-			const batch = options.batch || doc.batch();
+		const model = this.editor.model;
+		const imageElement = model.document.selection.getSelectedElement();
 
+		model.change( writer => {
 			// Default style means that there is no `imageStyle` attribute in the model.
 			// https://github.com/ckeditor/ckeditor5-image/issues/147
 			if ( this.style.isDefault ) {
-				batch.removeAttribute( 'imageStyle', imageElement );
+				writer.removeAttribute( 'imageStyle', imageElement );
 			} else {
-				batch.setAttribute( 'imageStyle', this.style.name, imageElement );
+				writer.setAttribute( 'imageStyle', this.style.name, imageElement );
 			}
 		} );
 	}

+ 1 - 2
packages/ckeditor5-image/src/imagestyle/imagestyleengine.js

@@ -44,8 +44,7 @@ export default class ImageStyleEngine extends Plugin {
 	 */
 	init() {
 		const editor = this.editor;
-		const doc = editor.document;
-		const schema = doc.schema;
+		const schema = editor.model.schema;
 		const data = editor.data;
 		const editing = editor.editing;
 

+ 5 - 9
packages/ckeditor5-image/src/imagetextalternative/imagetextalternativecommand.js

@@ -28,7 +28,7 @@ export default class ImageTextAlternativeCommand extends Command {
 	 * @inheritDoc
 	 */
 	refresh() {
-		const element = this.editor.document.selection.getSelectedElement();
+		const element = this.editor.model.document.selection.getSelectedElement();
 
 		this.isEnabled = isImage( element );
 
@@ -45,17 +45,13 @@ export default class ImageTextAlternativeCommand extends Command {
 	 * @fires execute
 	 * @param {Object} options
 	 * @param {String} options.newValue The new value of the `alt` attribute to set.
-	 * @param {module:engine/model/batch~Batch} [options.batch] A batch to collect all the change steps. A new batch will be
-	 * created if this option is not set.
 	 */
 	execute( options ) {
-		const doc = this.editor.document;
-		const imageElement = doc.selection.getSelectedElement();
+		const model = this.editor.model;
+		const imageElement = model.document.selection.getSelectedElement();
 
-		doc.enqueueChanges( () => {
-			const batch = options.batch || doc.batch();
-
-			batch.setAttribute( 'alt', options.newValue, imageElement );
+		model.change( writer => {
+			writer.setAttribute( 'alt', options.newValue, imageElement );
 		} );
 	}
 }

+ 7 - 6
packages/ckeditor5-image/tests/image.js

@@ -14,7 +14,7 @@ import ModelRange from '@ckeditor/ckeditor5-engine/src/model/range';
 import global from '@ckeditor/ckeditor5-utils/src/dom/global';
 
 describe( 'Image', () => {
-	let editorElement, editor, document, viewDocument;
+	let editorElement, model, editor, document, viewDocument;
 
 	beforeEach( () => {
 		editorElement = global.document.createElement( 'div' );
@@ -26,7 +26,8 @@ describe( 'Image', () => {
 			} )
 			.then( newEditor => {
 				editor = newEditor;
-				document = editor.document;
+				model = editor.model;
+				document = model.document;
 				viewDocument = editor.editing.view;
 			} );
 	} );
@@ -55,7 +56,7 @@ describe( 'Image', () => {
 
 	describe( 'selection', () => {
 		it( 'should create fake selection', () => {
-			setModelData( document, '[<image alt="alt text" src="foo.png"></image>]' );
+			setModelData( model, '[<image alt="alt text" src="foo.png"></image>]' );
 
 			expect( getViewData( viewDocument ) ).to.equal(
 				'[<figure class="ck-widget ck-widget_selected image" contenteditable="false">' +
@@ -68,7 +69,7 @@ describe( 'Image', () => {
 		} );
 
 		it( 'should create proper fake selection label when alt attribute is empty', () => {
-			setModelData( document, '[<image src="foo.png" alt=""></image>]' );
+			setModelData( model, '[<image src="foo.png" alt=""></image>]' );
 
 			expect( getViewData( viewDocument ) ).to.equal(
 				'[<figure class="ck-widget ck-widget_selected image" contenteditable="false">' +
@@ -81,7 +82,7 @@ describe( 'Image', () => {
 		} );
 
 		it( 'should remove selected class from previously selected element', () => {
-			setModelData( document,
+			setModelData( model,
 				'[<image src="foo.png" alt="alt text"></image>]' +
 				'<image src="foo.png" alt="alt text"></image>'
 			);
@@ -95,7 +96,7 @@ describe( 'Image', () => {
 				'</figure>'
 			);
 
-			document.enqueueChanges( () => {
+			model.change( () => {
 				const secondImage = document.getRoot().getChild( 1 );
 				document.selection.setRanges( [ ModelRange.createOn( secondImage ) ] );
 			} );

+ 29 - 36
packages/ckeditor5-image/tests/image/converters.js

@@ -22,16 +22,17 @@ import { getData as getViewData } from '@ckeditor/ckeditor5-engine/src/dev-utils
 import { setData as setModelData, getData as getModelData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
 
 describe( 'Image converters', () => {
-	let editor, document, viewDocument, batch;
+	let editor, model, document, viewDocument;
 
 	beforeEach( () => {
 		return VirtualTestEditor.create()
 			.then( newEditor => {
 				editor = newEditor;
-				document = editor.document;
-				batch = document.batch();
+				model = editor.model;
+				document = model.document;
 				viewDocument = editor.editing.view;
-				const schema = document.schema;
+
+				const schema = model.schema;
 
 				schema.registerItem( 'image' );
 				schema.requireAttributes( 'image', [ 'src' ] );
@@ -48,8 +49,8 @@ describe( 'Image converters', () => {
 	} );
 
 	describe( 'viewFigureToModel', () => {
-		function expectModel( model ) {
-			expect( getModelData( document, { withoutSelection: true } ) ).to.equal( model );
+		function expectModel( data ) {
+			expect( getModelData( model, { withoutSelection: true } ) ).to.equal( data );
 		}
 
 		let dispatcher, schema, imgConverterCalled;
@@ -57,7 +58,7 @@ describe( 'Image converters', () => {
 		beforeEach( () => {
 			imgConverterCalled = false;
 
-			schema = document.schema;
+			schema = model.schema;
 			schema.allow( { name: '$text', inside: 'image' } );
 
 			dispatcher = editor.data.viewToModel;
@@ -133,13 +134,11 @@ describe( 'Image converters', () => {
 
 	describe( 'modelToViewAttributeConverter', () => {
 		it( 'should convert adding attribute to image', () => {
-			setModelData( document, '<image src=""></image>' );
+			setModelData( model, '<image src=""></image>' );
 			const image = document.getRoot().getChild( 0 );
 
-			document.enqueueChanges( () => {
-				const batch = document.batch();
-
-				batch.setAttribute( 'alt', 'foo bar', image );
+			model.change( writer => {
+				writer.setAttribute( 'alt', 'foo bar', image );
 			} );
 
 			expect( getViewData( viewDocument, { withoutSelection: true } ) ).to.equal(
@@ -148,13 +147,11 @@ describe( 'Image converters', () => {
 		} );
 
 		it( 'should convert removing attribute from image', () => {
-			setModelData( document, '<image src="" alt="foo bar"></image>' );
+			setModelData( model, '<image src="" alt="foo bar"></image>' );
 			const image = document.getRoot().getChild( 0 );
 
-			document.enqueueChanges( () => {
-				const batch = document.batch();
-
-				batch.removeAttribute( 'alt', image );
+			model.change( writer => {
+				writer.removeAttribute( 'alt', image );
 			} );
 
 			expect( getViewData( viewDocument, { withoutSelection: true } ) ).to.equal(
@@ -163,13 +160,11 @@ describe( 'Image converters', () => {
 		} );
 
 		it( 'should convert change of attribute image', () => {
-			setModelData( document, '<image src="" alt="foo bar"></image>' );
+			setModelData( model, '<image src="" alt="foo bar"></image>' );
 			const image = document.getRoot().getChild( 0 );
 
-			document.enqueueChanges( () => {
-				const batch = document.batch();
-
-				batch.setAttribute( 'alt', 'baz quix', image );
+			model.change( writer => {
+				writer.setAttribute( 'alt', 'baz quix', image );
 			} );
 
 			expect( getViewData( viewDocument, { withoutSelection: true } ) ).to.equal(
@@ -182,13 +177,11 @@ describe( 'Image converters', () => {
 				consumable.consume( data.item, 'changeAttribute:alt' );
 			}, { priority: 'high' } );
 
-			setModelData( document, '<image src="" alt="foo bar"></image>' );
+			setModelData( model, '<image src="" alt="foo bar"></image>' );
 			const image = document.getRoot().getChild( 0 );
 
-			document.enqueueChanges( () => {
-				const batch = document.batch();
-
-				batch.setAttribute( 'alt', 'baz quix', image );
+			model.change( writer => {
+				writer.setAttribute( 'alt', 'baz quix', image );
 			} );
 
 			expect( getViewData( viewDocument, { withoutSelection: true } ) ).to.equal(
@@ -204,7 +197,7 @@ describe( 'Image converters', () => {
 		beforeEach( () => {
 			imgConverterCalled = false;
 
-			schema = document.schema;
+			schema = model.schema;
 
 			dispatcher = editor.data.viewToModel;
 			dispatcher.on( 'element:img', ( evt, data, consumable ) => {
@@ -231,7 +224,7 @@ describe( 'Image converters', () => {
 
 		describe( 'convertHoistableImage', () => {
 			it( 'should convert img element using already added converters if it is allowed in any point of given context #1', () => {
-				const result = dispatcher.convert( viewImg, batch, { context: [ '$root', 'div', 'paragraph' ] } );
+				const result = dispatcher.convert( viewImg, { context: [ '$root', 'div', 'paragraph' ] } );
 
 				// `result` is a model document fragment.
 				expect( result.childCount ).to.equal( 1 );
@@ -241,7 +234,7 @@ describe( 'Image converters', () => {
 			} );
 
 			it( 'should convert img element using already added converters if it is allowed in any point of given context #2', () => {
-				const result = dispatcher.convert( viewImg, batch, { context: [ '$root', modelDiv, modelParagraph ] } );
+				const result = dispatcher.convert( viewImg, { context: [ '$root', modelDiv, modelParagraph ] } );
 
 				// `result` is a model document fragment.
 				expect( result.childCount ).to.equal( 1 );
@@ -251,7 +244,7 @@ describe( 'Image converters', () => {
 			} );
 
 			it( 'should not convert img element if there is no allowed context #1', () => {
-				const result = dispatcher.convert( viewImg, batch, { context: [ 'div', 'paragraph' ] } );
+				const result = dispatcher.convert( viewImg, { context: [ 'div', 'paragraph' ] } );
 
 				// `result` is an empty model document fragment.
 				expect( result.childCount ).to.equal( 0 );
@@ -259,7 +252,7 @@ describe( 'Image converters', () => {
 			} );
 
 			it( 'should not convert img element if there is no allowed context #2', () => {
-				const result = dispatcher.convert( viewImg, batch, { context: [ modelDiv, modelParagraph ] } );
+				const result = dispatcher.convert( viewImg, { context: [ modelDiv, modelParagraph ] } );
 
 				// `result` is an empty model document fragment.
 				expect( result.childCount ).to.equal( 0 );
@@ -269,7 +262,7 @@ describe( 'Image converters', () => {
 			it( 'should not convert img element if allowed context is "above" limiting element #1', () => {
 				schema.limits.add( 'limit' );
 
-				const result = dispatcher.convert( viewImg, batch, { context: [ '$root', 'limit', 'div', 'paragraph' ] } );
+				const result = dispatcher.convert( viewImg, { context: [ '$root', 'limit', 'div', 'paragraph' ] } );
 
 				// `result` is an empty model document fragment.
 				expect( result.childCount ).to.equal( 0 );
@@ -279,7 +272,7 @@ describe( 'Image converters', () => {
 			it( 'should not convert img element if allowed context is "above" limiting element #2', () => {
 				schema.limits.add( 'limit' );
 
-				const result = dispatcher.convert( viewImg, batch, { context: [ '$root', modelLimit, modelDiv, modelParagraph ] } );
+				const result = dispatcher.convert( viewImg, { context: [ '$root', modelLimit, modelDiv, modelParagraph ] } );
 
 				// `result` is an empty model document fragment.
 				expect( result.childCount ).to.equal( 0 );
@@ -301,7 +294,7 @@ describe( 'Image converters', () => {
 				// because image is not allowed in div.
 				const viewDiv = new ViewContainerElement( 'div', null, [ 'foo', viewImg, 'bar' ] );
 
-				const result = dispatcher.convert( viewDiv, batch, { context: [ '$root' ] } );
+				const result = dispatcher.convert( viewDiv, { context: [ '$root' ] } );
 
 				// `result` is a model document fragment.
 				expect( result.childCount ).to.equal( 3 );
@@ -320,7 +313,7 @@ describe( 'Image converters', () => {
 
 				const viewDiv = new ViewContainerElement( 'p', null, [ 'foo', viewImg, 'bar' ] );
 
-				const result = dispatcher.convert( viewDiv, batch, { context: [ '$root', 'div' ] } );
+				const result = dispatcher.convert( viewDiv, { context: [ '$root', 'div' ] } );
 
 				// `result` is a model document fragment.
 				expect( result.childCount ).to.equal( 3 );

+ 70 - 83
packages/ckeditor5-image/tests/image/imageengine.js

@@ -13,7 +13,7 @@ import { isImageWidget } from '../../src/image/utils';
 import normalizeHtml from '@ckeditor/ckeditor5-utils/tests/_utils/normalizehtml';
 
 describe( 'ImageEngine', () => {
-	let editor, document, viewDocument;
+	let editor, model, document, viewDocument;
 
 	beforeEach( () => {
 		return VirtualTestEditor
@@ -22,7 +22,8 @@ describe( 'ImageEngine', () => {
 			} )
 			.then( newEditor => {
 				editor = newEditor;
-				document = editor.document;
+				model = editor.model;
+				document = model.document;
 				viewDocument = editor.editing.view;
 			} );
 	} );
@@ -32,26 +33,26 @@ describe( 'ImageEngine', () => {
 	} );
 
 	it( 'should set proper schema rules', () => {
-		expect( document.schema.check( { name: 'image', attributes: [ 'src', 'alt' ], inside: '$root' } ) ).to.be.true;
-		expect( document.schema.objects.has( 'image' ) ).to.be.true;
+		expect( model.schema.check( { name: 'image', attributes: [ 'src', 'alt' ], inside: '$root' } ) ).to.be.true;
+		expect( model.schema.objects.has( 'image' ) ).to.be.true;
 	} );
 
 	describe( 'conversion in data pipeline', () => {
 		describe( 'model to view', () => {
 			it( 'should convert', () => {
-				setModelData( document, '<image src="foo.png" alt="alt text"></image>' );
+				setModelData( model, '<image src="foo.png" alt="alt text"></image>' );
 
 				expect( editor.getData() ).to.equal( '<figure class="image"><img alt="alt text" src="foo.png"></figure>' );
 			} );
 
 			it( 'should convert without alt attribute', () => {
-				setModelData( document, '<image src="foo.png"></image>' );
+				setModelData( model, '<image src="foo.png"></image>' );
 
 				expect( editor.getData() ).to.equal( '<figure class="image"><img src="foo.png"></figure>' );
 			} );
 
 			it( 'should convert srcset attribute to srcset and sizes attribute', () => {
-				setModelData( document,
+				setModelData( model,
 					'<image src="foo.png" alt="alt text" srcset=\'{ "data": "small.png 148w, big.png 1024w" }\'></image>'
 				);
 
@@ -63,7 +64,7 @@ describe( 'ImageEngine', () => {
 			} );
 
 			it( 'should convert srcset attribute to width, srcset and add sizes attribute', () => {
-				setModelData( document,
+				setModelData( model,
 					'<image ' +
 						'src="foo.png" ' +
 						'alt="alt text" ' +
@@ -87,7 +88,7 @@ describe( 'ImageEngine', () => {
 					consumable.consume( modelImage, consumableType );
 				}, { priority: 'high' } );
 
-				setModelData( document,
+				setModelData( model,
 					'<image ' +
 						'src="foo.png" ' +
 						'alt="alt text" ' +
@@ -103,7 +104,7 @@ describe( 'ImageEngine', () => {
 			} );
 
 			it( 'should not convert srcset attribute if has wrong data', () => {
-				setModelData( document,
+				setModelData( model,
 					'<image ' +
 						'src="foo.png" ' +
 						'alt="alt text" ' +
@@ -111,10 +112,8 @@ describe( 'ImageEngine', () => {
 					'</image>' );
 
 				const image = document.getRoot().getChild( 0 );
-				document.enqueueChanges( () => {
-					const batch = document.batch();
-
-					batch.removeAttribute( 'srcset', image );
+				model.change( writer => {
+					writer.removeAttribute( 'srcset', image );
 				} );
 
 				expect( editor.getData() ).to.equal(
@@ -129,42 +128,42 @@ describe( 'ImageEngine', () => {
 			it( 'should convert image figure', () => {
 				editor.setData( '<figure class="image"><img src="foo.png" alt="alt text" /></figure>' );
 
-				expect( getModelData( document, { withoutSelection: true } ) )
+				expect( getModelData( model, { withoutSelection: true } ) )
 					.to.equal( '<image alt="alt text" src="foo.png"></image>' );
 			} );
 
 			it( 'should not convert if there is no image class', () => {
 				editor.setData( '<figure class="quote">My quote</figure>' );
 
-				expect( getModelData( document, { withoutSelection: true } ) )
+				expect( getModelData( model, { withoutSelection: true } ) )
 					.to.equal( '' );
 			} );
 
 			it( 'should not convert if there is no img inside #1', () => {
 				editor.setData( '<figure class="image"></figure>' );
 
-				expect( getModelData( document, { withoutSelection: true } ) )
+				expect( getModelData( model, { withoutSelection: true } ) )
 					.to.equal( '' );
 			} );
 
 			it( 'should not convert if there is no img inside #2', () => {
 				editor.setData( '<figure class="image">test</figure>' );
 
-				expect( getModelData( document, { withoutSelection: true } ) )
+				expect( getModelData( model, { withoutSelection: true } ) )
 					.to.equal( '' );
 			} );
 
 			it( 'should convert without alt attribute', () => {
 				editor.setData( '<figure class="image"><img src="foo.png" /></figure>' );
 
-				expect( getModelData( document, { withoutSelection: true } ) )
+				expect( getModelData( model, { withoutSelection: true } ) )
 					.to.equal( '<image src="foo.png"></image>' );
 			} );
 
 			it( 'should not convert without src attribute', () => {
 				editor.setData( '<figure class="image"><img alt="alt text" /></figure>' );
 
-				expect( getModelData( document, { withoutSelection: true } ) )
+				expect( getModelData( model, { withoutSelection: true } ) )
 					.to.equal( '' );
 			} );
 
@@ -172,15 +171,15 @@ describe( 'ImageEngine', () => {
 				const data = editor.data;
 				const editing = editor.editing;
 
-				document.schema.registerItem( 'div', '$block' );
-				document.schema.disallow( { name: 'image', inside: '$root', attributes: 'src' } );
+				model.schema.registerItem( 'div', '$block' );
+				model.schema.disallow( { name: 'image', inside: '$root', attributes: 'src' } );
 
 				buildModelConverter().for( data.modelToView, editing.modelToView ).fromElement( 'div' ).toElement( 'div' );
 				buildViewConverter().for( data.viewToModel ).fromElement( 'div' ).toElement( 'div' );
 
 				editor.setData( '<div><figure class="image"><img src="foo.png" alt="alt text" /></figure></div>' );
 
-				expect( getModelData( document, { withoutSelection: true } ) )
+				expect( getModelData( model, { withoutSelection: true } ) )
 					.to.equal( '<div></div>' );
 			} );
 
@@ -192,7 +191,7 @@ describe( 'ImageEngine', () => {
 
 				editor.setData( '<figure class="image"><img src="foo.png" alt="alt text" /></figure>' );
 
-				expect( getModelData( document, { withoutSelection: true } ) )
+				expect( getModelData( model, { withoutSelection: true } ) )
 					.to.equal( '' );
 			} );
 
@@ -204,7 +203,7 @@ describe( 'ImageEngine', () => {
 
 				editor.setData( '<figure class="image"><img src="foo.png" alt="alt text" /></figure>' );
 
-				expect( getModelData( document, { withoutSelection: true } ) )
+				expect( getModelData( model, { withoutSelection: true } ) )
 					.to.equal( '' );
 			} );
 
@@ -220,7 +219,7 @@ describe( 'ImageEngine', () => {
 			it( 'should convert bare img element', () => {
 				editor.setData( '<img src="foo.png" alt="alt text" />' );
 
-				expect( getModelData( document, { withoutSelection: true } ) )
+				expect( getModelData( model, { withoutSelection: true } ) )
 					.to.equal( '<image alt="alt text" src="foo.png"></image>' );
 			} );
 
@@ -228,25 +227,25 @@ describe( 'ImageEngine', () => {
 				const data = editor.data;
 				const editing = editor.editing;
 
-				document.schema.registerItem( 'div', '$block' );
-				document.schema.allow( { name: 'div', attributes: 'alt', inside: '$root' } );
+				model.schema.registerItem( 'div', '$block' );
+				model.schema.allow( { name: 'div', attributes: 'alt', inside: '$root' } );
 
 				buildModelConverter().for( data.modelToView, editing.modelToView ).fromElement( 'div' ).toElement( 'div' );
 				buildViewConverter().for( data.viewToModel ).fromElement( 'div' ).toElement( 'div' );
 
 				editor.setData( '<div alt="foo"></div>' );
 
-				expect( getModelData( document, { withoutSelection: true } ) ).to.equal( '<div></div>' );
+				expect( getModelData( model, { withoutSelection: true } ) ).to.equal( '<div></div>' );
 			} );
 
 			it( 'should handle figure with two images', () => {
-				document.schema.allow( { name: '$text', inside: 'image' } );
+				model.schema.allow( { name: '$text', inside: 'image' } );
 
 				editor.setData( '<figure class="image"><img src="foo.jpg" /><img src="bar.jpg" />abc</figure>' );
 
 				// The foo.jpg image is properly converted using figure converter. The other image was tried to
 				// be added as a child of foo.jpg and then was autohoisted.
-				expect( getModelData( document, { withoutSelection: true } ) )
+				expect( getModelData( model, { withoutSelection: true } ) )
 					.to.equal( '<image src="bar.jpg"></image><image src="foo.jpg">abc</image>' );
 			} );
 
@@ -257,7 +256,7 @@ describe( 'ImageEngine', () => {
 					'</figure>'
 				);
 
-				expect( getModelData( document, { withoutSelection: true } ) )
+				expect( getModelData( model, { withoutSelection: true } ) )
 					.to.equal( '<image alt="alt text" src="foo.png" srcset="{"data":"small.png 148w, big.png 1024w"}"></image>' );
 			} );
 
@@ -268,7 +267,7 @@ describe( 'ImageEngine', () => {
 					'</figure>'
 				);
 
-				expect( getModelData( document, { withoutSelection: true } ) ).to.equal(
+				expect( getModelData( model, { withoutSelection: true } ) ).to.equal(
 					'<image alt="alt text" src="foo.png" srcset="{"data":"small.png 148w, big.png 1024w","width":"1024"}"></image>' );
 			} );
 
@@ -279,13 +278,13 @@ describe( 'ImageEngine', () => {
 					'</figure>'
 				);
 
-				expect( getModelData( document, { withoutSelection: true } ) )
+				expect( getModelData( model, { withoutSelection: true } ) )
 					.to.equal( '<image alt="alt text" src="foo.png" srcset="{"data":"small.png 148w, big.png 1024w"}"></image>' );
 			} );
 
 			describe( 'should autohoist images', () => {
 				beforeEach( () => {
-					document.schema.registerItem( 'div', '$block' );
+					model.schema.registerItem( 'div', '$block' );
 
 					buildModelConverter()
 						.for( editor.data.modelToView, editor.editing.modelToView )
@@ -301,7 +300,7 @@ describe( 'ImageEngine', () => {
 				it( 'image between non-hoisted elements', () => {
 					editor.setData( '<div>foo<img src="foo.jpg" alt="foo" />bar</div>' );
 
-					expect( getModelData( document, { withoutSelection: true } ) ).to.equal(
+					expect( getModelData( model, { withoutSelection: true } ) ).to.equal(
 						'<div>foo</div>' +
 						'<image alt="foo" src="foo.jpg"></image>' +
 						'<div>bar</div>'
@@ -311,7 +310,7 @@ describe( 'ImageEngine', () => {
 				it( 'multiple images', () => {
 					editor.setData( '<div>foo<img src="foo.jpg" alt="foo" />ba<img src="foo.jpg" alt="foo" />r</div>' );
 
-					expect( getModelData( document, { withoutSelection: true } ) ).to.equal(
+					expect( getModelData( model, { withoutSelection: true } ) ).to.equal(
 						'<div>foo</div>' +
 						'<image alt="foo" src="foo.jpg"></image>' +
 						'<div>ba</div>' +
@@ -323,7 +322,7 @@ describe( 'ImageEngine', () => {
 				it( 'images on borders of parent', () => {
 					editor.setData( '<div><img src="foo.jpg" alt="foo" />foobar<img src="foo.jpg" alt="foo" /></div>' );
 
-					expect( getModelData( document, { withoutSelection: true } ) ).to.equal(
+					expect( getModelData( model, { withoutSelection: true } ) ).to.equal(
 						'<image alt="foo" src="foo.jpg"></image>' +
 						'<div>foobar</div>' +
 						'<image alt="foo" src="foo.jpg"></image>'
@@ -333,18 +332,18 @@ describe( 'ImageEngine', () => {
 				it( 'images are only content of parent', () => {
 					editor.setData( '<div><img src="foo.jpg" alt="foo" /><img src="foo.jpg" alt="foo" /></div>' );
 
-					expect( getModelData( document, { withoutSelection: true } ) ).to.equal(
+					expect( getModelData( model, { withoutSelection: true } ) ).to.equal(
 						'<image alt="foo" src="foo.jpg"></image>' +
 						'<image alt="foo" src="foo.jpg"></image>'
 					);
 				} );
 
 				it( 'deep autohoisting #1', () => {
-					document.schema.allow( { name: 'div', inside: 'div' } );
+					model.schema.allow( { name: 'div', inside: 'div' } );
 
 					editor.setData( '<div>foo<div>xx<img src="foo.jpg" alt="foo" /></div>bar</div>' );
 
-					expect( getModelData( document, { withoutSelection: true } ) ).to.equal(
+					expect( getModelData( model, { withoutSelection: true } ) ).to.equal(
 						'<div>' +
 							'foo' +
 							'<div>' +
@@ -357,7 +356,7 @@ describe( 'ImageEngine', () => {
 				} );
 
 				it( 'deep autohoisting #2', () => {
-					document.schema.allow( { name: 'div', inside: 'div' } );
+					model.schema.allow( { name: 'div', inside: 'div' } );
 
 					editor.setData(
 						'<div>x</div>' +
@@ -365,15 +364,15 @@ describe( 'ImageEngine', () => {
 						'<div>y</div>'
 					);
 
-					expect( getModelData( document, { withoutSelection: true } ) ).to.equal(
+					expect( getModelData( model, { withoutSelection: true } ) ).to.equal(
 						'<div>x</div><image alt="foo" src="foo.jpg"></image><div>y</div>'
 					);
 				} );
 
 				it( 'should not break a limiting element', () => {
-					document.schema.registerItem( 'limit', '$block' );
-					document.schema.allow( { name: 'div', inside: 'limit' } );
-					document.schema.limits.add( 'limit' );
+					model.schema.registerItem( 'limit', '$block' );
+					model.schema.allow( { name: 'div', inside: 'limit' } );
+					model.schema.limits.add( 'limit' );
 
 					buildModelConverter()
 						.for( editor.data.modelToView, editor.editing.modelToView ).fromElement( 'limit' ).toElement( 'limit' );
@@ -383,13 +382,13 @@ describe( 'ImageEngine', () => {
 					editor.setData( '<limit><div>foo<img src="foo.jpg" alt="foo" />bar</div></limit>' );
 
 					// <limit> element does not have converters so it is not converted.
-					expect( getModelData( document, { withoutSelection: true } ) ).to.equal( '<limit><div>foobar</div></limit>' );
+					expect( getModelData( model, { withoutSelection: true } ) ).to.equal( '<limit><div>foobar</div></limit>' );
 				} );
 
 				it( 'should not convert and autohoist image element without src attribute (which is not allowed by schema)', () => {
 					editor.setData( '<div>foo<img alt="foo" />bar</div>' );
 
-					expect( getModelData( document, { withoutSelection: true } ) ).to.equal( '<div>foobar</div>' );
+					expect( getModelData( model, { withoutSelection: true } ) ).to.equal( '<div>foobar</div>' );
 				} );
 			} );
 		} );
@@ -398,7 +397,7 @@ describe( 'ImageEngine', () => {
 	describe( 'conversion in editing pipeline', () => {
 		describe( 'model to view', () => {
 			it( 'should convert', () => {
-				setModelData( document, '<image src="foo.png" alt="alt text"></image>' );
+				setModelData( model, '<image src="foo.png" alt="alt text"></image>' );
 
 				expect( getViewData( viewDocument, { withoutSelection: true } ) ).to.equal(
 					'<figure class="ck-widget image" contenteditable="false"><img alt="alt text" src="foo.png"></img></figure>'
@@ -406,7 +405,7 @@ describe( 'ImageEngine', () => {
 			} );
 
 			it( 'converted element should be widgetized', () => {
-				setModelData( document, '<image src="foo.png" alt="alt text"></image>' );
+				setModelData( model, '<image src="foo.png" alt="alt text"></image>' );
 				const figure = viewDocument.getRoot().getChild( 0 );
 
 				expect( figure.name ).to.equal( 'figure' );
@@ -414,13 +413,11 @@ describe( 'ImageEngine', () => {
 			} );
 
 			it( 'should convert attribute change', () => {
-				setModelData( document, '<image src="foo.png" alt="alt text"></image>' );
+				setModelData( model, '<image src="foo.png" alt="alt text"></image>' );
 				const image = document.getRoot().getChild( 0 );
 
-				document.enqueueChanges( () => {
-					const batch = document.batch();
-
-					batch.setAttribute( 'alt', 'new text', image );
+				model.change( writer => {
+					writer.setAttribute( 'alt', 'new text', image );
 				} );
 
 				expect( getViewData( viewDocument, { withoutSelection: true } ) ).to.equal(
@@ -429,13 +426,11 @@ describe( 'ImageEngine', () => {
 			} );
 
 			it( 'should convert attribute removal', () => {
-				setModelData( document, '<image src="foo.png" alt="alt text"></image>' );
+				setModelData( model, '<image src="foo.png" alt="alt text"></image>' );
 				const image = document.getRoot().getChild( 0 );
 
-				document.enqueueChanges( () => {
-					const batch = document.batch();
-
-					batch.removeAttribute( 'alt', image );
+				model.change( writer => {
+					writer.removeAttribute( 'alt', image );
 				} );
 
 				expect( getViewData( viewDocument, { withoutSelection: true } ) )
@@ -443,17 +438,15 @@ describe( 'ImageEngine', () => {
 			} );
 
 			it( 'should not convert change if is already consumed', () => {
-				setModelData( document, '<image src="foo.png" alt="alt text"></image>' );
+				setModelData( model, '<image src="foo.png" alt="alt text"></image>' );
 				const image = document.getRoot().getChild( 0 );
 
 				editor.editing.modelToView.on( 'removeAttribute:alt:image', ( evt, data, consumable ) => {
 					consumable.consume( data.item, 'removeAttribute:alt' );
 				}, { priority: 'high' } );
 
-				document.enqueueChanges( () => {
-					const batch = document.batch();
-
-					batch.removeAttribute( 'alt', image );
+				model.change( writer => {
+					writer.removeAttribute( 'alt', image );
 				} );
 
 				expect( getViewData( viewDocument, { withoutSelection: true } ) ).to.equal(
@@ -462,7 +455,7 @@ describe( 'ImageEngine', () => {
 			} );
 
 			it( 'should convert srcset attribute to srcset and sizes', () => {
-				setModelData( document,
+				setModelData( model,
 					'<image ' +
 						'src="foo.png" ' +
 						'alt="alt text" ' +
@@ -477,7 +470,7 @@ describe( 'ImageEngine', () => {
 			} );
 
 			it( 'should not convert srcset attribute if has wrong data', () => {
-				setModelData( document,
+				setModelData( model,
 					'<image ' +
 						'src="foo.png" ' +
 						'alt="alt text" ' +
@@ -485,10 +478,8 @@ describe( 'ImageEngine', () => {
 					'</image>' );
 
 				const image = document.getRoot().getChild( 0 );
-				document.enqueueChanges( () => {
-					const batch = document.batch();
-
-					batch.removeAttribute( 'srcset', image );
+				model.change( writer => {
+					writer.removeAttribute( 'srcset', image );
 				} );
 
 				expect( getViewData( viewDocument, { withoutSelection: true } ) ).to.equal(
@@ -499,7 +490,7 @@ describe( 'ImageEngine', () => {
 			} );
 
 			it( 'should convert srcset attribute to srcset, width and sizes', () => {
-				setModelData( document,
+				setModelData( model,
 					'<image ' +
 						'src="foo.png" ' +
 						'alt="alt text" ' +
@@ -514,13 +505,11 @@ describe( 'ImageEngine', () => {
 			} );
 
 			it( 'should remove sizes and srcsset attribute when srcset attribute is removed from model', () => {
-				setModelData( document, '<image src="foo.png" srcset=\'{ "data": "small.png 148w, big.png 1024w" }\'></image>' );
+				setModelData( model, '<image src="foo.png" srcset=\'{ "data": "small.png 148w, big.png 1024w" }\'></image>' );
 				const image = document.getRoot().getChild( 0 );
 
-				document.enqueueChanges( () => {
-					const batch = document.batch();
-
-					batch.removeAttribute( 'srcset', image );
+				model.change( writer => {
+					writer.removeAttribute( 'srcset', image );
 				} );
 
 				expect( getViewData( viewDocument, { withoutSelection: true } ) ).to.equal(
@@ -531,7 +520,7 @@ describe( 'ImageEngine', () => {
 			} );
 
 			it( 'should remove width, sizes and srcsset attribute when srcset attribute is removed from model', () => {
-				setModelData( document,
+				setModelData( model,
 					'<image ' +
 						'src="foo.png" ' +
 						'srcset=\'{ "data": "small.png 148w, big.png 1024w", "width": "1024" }\'>' +
@@ -539,10 +528,8 @@ describe( 'ImageEngine', () => {
 				);
 				const image = document.getRoot().getChild( 0 );
 
-				document.enqueueChanges( () => {
-					const batch = document.batch();
-
-					batch.removeAttribute( 'srcset', image );
+				model.change( writer => {
+					writer.removeAttribute( 'srcset', image );
 				} );
 
 				expect( getViewData( viewDocument, { withoutSelection: true } ) ).to.equal(
@@ -561,7 +548,7 @@ describe( 'ImageEngine', () => {
 					consumable.consume( modelImage, consumableType );
 				}, { priority: 'high' } );
 
-				setModelData( document,
+				setModelData( model,
 					'<image ' +
 						'src="foo.png" ' +
 						'alt="alt text" ' +

+ 4 - 5
packages/ckeditor5-image/tests/image/ui/utils.js

@@ -14,7 +14,7 @@ import { setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
 import { repositionContextualBalloon, getBalloonPositionData } from '../../../src/image/ui/utils';
 
 describe( 'Utils', () => {
-	let editor, doc, editingView, balloon, editorElement;
+	let editor, editingView, balloon, editorElement;
 
 	beforeEach( () => {
 		editorElement = global.document.createElement( 'div' );
@@ -26,7 +26,6 @@ describe( 'Utils', () => {
 			} )
 			.then( newEditor => {
 				editor = newEditor;
-				doc = editor.document;
 				editingView = editor.editing.view;
 				balloon = editor.plugins.get( 'ContextualBalloon' );
 			} );
@@ -53,7 +52,7 @@ describe( 'Utils', () => {
 				}
 			} );
 
-			setData( doc, '[<image src=""></image>]' );
+			setData( editor.model, '[<image src=""></image>]' );
 			repositionContextualBalloon( editor );
 
 			sinon.assert.calledWithExactly( spy, {
@@ -68,7 +67,7 @@ describe( 'Utils', () => {
 		it( 'should not engage with no image is selected', () => {
 			const spy = sinon.spy( balloon, 'updatePosition' );
 
-			setData( doc, '<paragraph>foo</paragraph>' );
+			setData( editor.model, '<paragraph>foo</paragraph>' );
 
 			repositionContextualBalloon( editor );
 			sinon.assert.notCalled( spy );
@@ -79,7 +78,7 @@ describe( 'Utils', () => {
 		it( 'returns the position data', () => {
 			const defaultPositions = BalloonPanelView.defaultPositions;
 
-			setData( doc, '[<image src=""></image>]' );
+			setData( editor.model, '[<image src=""></image>]' );
 			const data = getBalloonPositionData( editor );
 
 			expect( data ).to.deep.equal( {

+ 66 - 77
packages/ckeditor5-image/tests/imagecaption/imagecaptionengine.js

@@ -23,7 +23,7 @@ import buildViewConverter from '@ckeditor/ckeditor5-engine/src/conversion/buildv
 import buildModelConverter from '@ckeditor/ckeditor5-engine/src/conversion/buildmodelconverter';
 
 describe( 'ImageCaptionEngine', () => {
-	let editor, doc, viewDocument;
+	let editor, model, doc, viewDocument;
 
 	beforeEach( () => {
 		return VirtualTestEditor
@@ -32,12 +32,13 @@ describe( 'ImageCaptionEngine', () => {
 			} )
 			.then( newEditor => {
 				editor = newEditor;
-				doc = editor.document;
+				model = editor.model;
+				doc = model.document;
 				viewDocument = editor.editing.view;
-				doc.schema.registerItem( 'widget' );
-				doc.schema.allow( { name: 'widget', inside: '$root' } );
-				doc.schema.allow( { name: 'caption', inside: 'widget' } );
-				doc.schema.allow( { name: '$inline', inside: 'widget' } );
+				model.schema.registerItem( 'widget' );
+				model.schema.allow( { name: 'widget', inside: '$root' } );
+				model.schema.allow( { name: 'caption', inside: 'widget' } );
+				model.schema.allow( { name: '$inline', inside: 'widget' } );
 
 				buildViewConverter()
 					.for( editor.data.viewToModel )
@@ -56,10 +57,10 @@ describe( 'ImageCaptionEngine', () => {
 	} );
 
 	it( 'should set proper schema rules', () => {
-		expect( doc.schema.check( { name: 'caption', iniside: 'image' } ) ).to.be.true;
-		expect( doc.schema.check( { name: '$inline', inside: 'caption' } ) ).to.be.true;
-		expect( doc.schema.itemExtends( 'caption', '$block' ) ).to.be.true;
-		expect( doc.schema.limits.has( 'caption' ) );
+		expect( model.schema.check( { name: 'caption', iniside: 'image' } ) ).to.be.true;
+		expect( model.schema.check( { name: '$inline', inside: 'caption' } ) ).to.be.true;
+		expect( model.schema.itemExtends( 'caption', '$block' ) ).to.be.true;
+		expect( model.schema.limits.has( 'caption' ) );
 	} );
 
 	describe( 'data pipeline', () => {
@@ -67,28 +68,28 @@ describe( 'ImageCaptionEngine', () => {
 			it( 'should convert figcaption inside image figure', () => {
 				editor.setData( '<figure class="image"><img src="foo.png"/><figcaption>foo bar</figcaption></figure>' );
 
-				expect( getModelData( doc, { withoutSelection: true } ) )
+				expect( getModelData( model, { withoutSelection: true } ) )
 					.to.equal( '<image src="foo.png"><caption>foo bar</caption></image>' );
 			} );
 
 			it( 'should add empty caption if there is no figcaption', () => {
 				editor.setData( '<figure class="image"><img src="foo.png"/></figure>' );
 
-				expect( getModelData( doc, { withoutSelection: true } ) )
+				expect( getModelData( model, { withoutSelection: true } ) )
 					.to.equal( '<image src="foo.png"><caption></caption></image>' );
 			} );
 
 			it( 'should not convert figcaption inside other elements than image', () => {
 				editor.setData( '<widget><figcaption>foobar</figcaption></widget>' );
 
-				expect( getModelData( doc, { withoutSelection: true } ) )
+				expect( getModelData( model, { withoutSelection: true } ) )
 					.to.equal( '<widget>foobar</widget>' );
 			} );
 		} );
 
 		describe( 'model to view', () => {
 			it( 'should convert caption element to figcaption', () => {
-				setModelData( doc, '<image src="img.png"><caption>Foo bar baz.</caption></image>' );
+				setModelData( model, '<image src="img.png"><caption>Foo bar baz.</caption></image>' );
 
 				expect( editor.getData() ).to.equal(
 					'<figure class="image"><img src="img.png"><figcaption>Foo bar baz.</figcaption></figure>'
@@ -96,13 +97,13 @@ describe( 'ImageCaptionEngine', () => {
 			} );
 
 			it( 'should not convert caption to figcaption if it\'s empty', () => {
-				setModelData( doc, '<image src="img.png"><caption></caption></image>' );
+				setModelData( model, '<image src="img.png"><caption></caption></image>' );
 
 				expect( editor.getData() ).to.equal( '<figure class="image"><img src="img.png"></figure>' );
 			} );
 
 			it( 'should not convert caption from other elements', () => {
-				setModelData( doc, '<widget>foo bar<caption></caption></widget>' );
+				setModelData( model, '<widget>foo bar<caption></caption></widget>' );
 
 				expect( editor.getData() ).to.equal( '<widget>foo bar</widget>' );
 			} );
@@ -112,7 +113,7 @@ describe( 'ImageCaptionEngine', () => {
 	describe( 'editing pipeline', () => {
 		describe( 'model to view', () => {
 			it( 'should convert caption element to figcaption contenteditable', () => {
-				setModelData( doc, '<image src="img.png"><caption>Foo bar baz.</caption></image>' );
+				setModelData( model, '<image src="img.png"><caption>Foo bar baz.</caption></image>' );
 
 				expect( getViewData( viewDocument, { withoutSelection: true } ) ).to.equal(
 					'<figure class="ck-widget image" contenteditable="false">' +
@@ -125,7 +126,7 @@ describe( 'ImageCaptionEngine', () => {
 			} );
 
 			it( 'should convert caption to element with proper CSS class if it\'s empty', () => {
-				setModelData( doc, '<paragraph>foo</paragraph><image src="img.png"><caption></caption></image>' );
+				setModelData( model, '<paragraph>foo</paragraph><image src="img.png"><caption></caption></image>' );
 
 				expect( getViewData( viewDocument, { withoutSelection: true } ) ).to.equal(
 					'<p>foo</p>' +
@@ -139,7 +140,7 @@ describe( 'ImageCaptionEngine', () => {
 			} );
 
 			it( 'should not convert caption from other elements', () => {
-				setModelData( doc, '<widget>foo bar<caption></caption></widget>' );
+				setModelData( model, '<widget>foo bar<caption></caption></widget>' );
 				expect( getViewData( viewDocument, { withoutSelection: true } ) ).to.equal( '<widget>foo bar</widget>' );
 			} );
 
@@ -159,7 +160,7 @@ describe( 'ImageCaptionEngine', () => {
 					{ priority: 'high' }
 				);
 
-				setModelData( doc, '<image src="img.png"><caption>Foo bar baz.</caption></image>' );
+				setModelData( model, '<image src="img.png"><caption>Foo bar baz.</caption></image>' );
 
 				expect( getViewData( viewDocument, { withoutSelection: true } ) ).to.equal(
 					'<figure class="ck-widget image" contenteditable="false"><img src="img.png"></img><span></span>Foo bar baz.</figure>'
@@ -167,14 +168,13 @@ describe( 'ImageCaptionEngine', () => {
 			} );
 
 			it( 'should show caption when something is inserted inside', () => {
-				setModelData( doc, '<paragraph>foo</paragraph><image src="img.png"><caption></caption></image>' );
+				setModelData( model, '<paragraph>foo</paragraph><image src="img.png"><caption></caption></image>' );
 
 				const image = doc.getRoot().getChild( 1 );
 				const caption = image.getChild( 0 );
 
-				doc.enqueueChanges( () => {
-					const batch = doc.batch();
-					batch.insertText( 'foo bar', caption );
+				model.change( writer => {
+					writer.insertText( 'foo bar', caption );
 				} );
 
 				expect( getViewData( viewDocument ) ).to.equal(
@@ -189,14 +189,13 @@ describe( 'ImageCaptionEngine', () => {
 			} );
 
 			it( 'should hide when everything is removed from caption', () => {
-				setModelData( doc, '<paragraph>foo</paragraph><image src="img.png"><caption>foo bar baz</caption></image>' );
+				setModelData( model, '<paragraph>foo</paragraph><image src="img.png"><caption>foo bar baz</caption></image>' );
 
 				const image = doc.getRoot().getChild( 1 );
 				const caption = image.getChild( 0 );
 
-				doc.enqueueChanges( () => {
-					const batch = doc.batch();
-					batch.remove( ModelRange.createIn( caption ) );
+				model.change( writer => {
+					writer.remove( ModelRange.createIn( caption ) );
 				} );
 
 				expect( getViewData( viewDocument ) ).to.equal(
@@ -211,14 +210,13 @@ describe( 'ImageCaptionEngine', () => {
 			} );
 
 			it( 'should show when not everything is removed from caption', () => {
-				setModelData( doc, '<paragraph>foo</paragraph><image src="img.png"><caption>foo bar baz</caption></image>' );
+				setModelData( model, '<paragraph>foo</paragraph><image src="img.png"><caption>foo bar baz</caption></image>' );
 
 				const image = doc.getRoot().getChild( 1 );
 				const caption = image.getChild( 0 );
 
-				doc.enqueueChanges( () => {
-					const batch = doc.batch();
-					batch.remove( ModelRange.createFromParentsAndOffsets( caption, 0, caption, 8 ) );
+				model.change( writer => {
+					writer.remove( ModelRange.createFromParentsAndOffsets( caption, 0, caption, 8 ) );
 				} );
 
 				expect( getViewData( viewDocument ) ).to.equal(
@@ -234,13 +232,11 @@ describe( 'ImageCaptionEngine', () => {
 
 	describe( 'inserting image to the document', () => {
 		it( 'should add caption element if image does not have it', () => {
-			const batch = doc.batch();
-
-			doc.enqueueChanges( () => {
-				batch.insertElement( 'image', { src: '', alt: '' }, doc.getRoot() );
+			model.change( writer => {
+				writer.insertElement( 'image', { src: '', alt: '' }, doc.getRoot() );
 			} );
 
-			expect( getModelData( doc ) ).to.equal(
+			expect( getModelData( model ) ).to.equal(
 				'[<image alt="" src=""><caption></caption></image>]<paragraph></paragraph>'
 			);
 
@@ -258,13 +254,12 @@ describe( 'ImageCaptionEngine', () => {
 		it( 'should not add caption element if image already have it', () => {
 			const caption = new ModelElement( 'caption', null, 'foo bar' );
 			const image = new ModelElement( 'image', { src: '', alt: '' }, caption );
-			const batch = doc.batch();
 
-			doc.enqueueChanges( () => {
-				batch.insert( image, doc.getRoot() );
+			model.change( writer => {
+				writer.insert( image, doc.getRoot() );
 			} );
 
-			expect( getModelData( doc ) ).to.equal(
+			expect( getModelData( model ) ).to.equal(
 				'[<image alt="" src=""><caption>foo bar</caption></image>]<paragraph></paragraph>'
 			);
 
@@ -282,18 +277,17 @@ describe( 'ImageCaptionEngine', () => {
 		it( 'should not add caption element twice', () => {
 			const image = new ModelElement( 'image', { src: '', alt: '' } );
 			const caption = new ModelElement( 'caption' );
-			const batch = doc.batch();
 
-			doc.enqueueChanges( () => {
+			model.change( writer => {
 				// Since we are adding an empty image, this should trigger caption fixer.
-				batch.insert( image, doc.getRoot() );
+				writer.insert( image, doc.getRoot() );
 
-				// Add caption just after the image is inserted, in same batch and enqueue changes block.
-				batch.insert( caption, image );
+				// Add caption just after the image is inserted, in same batch.
+				writer.insert( caption, image );
 			} );
 
 			// Check whether caption fixer added redundant caption.
-			expect( getModelData( doc ) ).to.equal(
+			expect( getModelData( model ) ).to.equal(
 				'[<image alt="" src=""><caption></caption></image>]<paragraph></paragraph>'
 			);
 
@@ -308,16 +302,15 @@ describe( 'ImageCaptionEngine', () => {
 		} );
 
 		it( 'should do nothing for other changes than insert', () => {
-			setModelData( doc, '<image src=""><caption>foo bar</caption></image>' );
+			setModelData( model, '<image src=""><caption>foo bar</caption></image>' );
 
 			const image = doc.getRoot().getChild( 0 );
-			const batch = doc.batch();
 
-			doc.enqueueChanges( () => {
-				batch.setAttribute( 'alt', 'alt text', image );
+			model.change( writer => {
+				writer.setAttribute( 'alt', 'alt text', image );
 			} );
 
-			expect( getModelData( doc, { withoutSelection: true } ) ).to.equal(
+			expect( getModelData( model, { withoutSelection: true } ) ).to.equal(
 				'<image alt="alt text" src=""><caption>foo bar</caption></image>'
 			);
 		} );
@@ -325,7 +318,7 @@ describe( 'ImageCaptionEngine', () => {
 
 	describe( 'editing view', () => {
 		it( 'image should have empty figcaption element when is selected', () => {
-			setModelData( doc, '<paragraph>foo</paragraph>[<image src=""><caption></caption></image>]' );
+			setModelData( model, '<paragraph>foo</paragraph>[<image src=""><caption></caption></image>]' );
 
 			expect( getViewData( viewDocument ) ).to.equal(
 				'<p>foo</p>' +
@@ -338,7 +331,7 @@ describe( 'ImageCaptionEngine', () => {
 		} );
 
 		it( 'image should have empty figcaption element with hidden class when not selected', () => {
-			setModelData( doc, '<paragraph>[]foo</paragraph><image src=""><caption></caption></image>' );
+			setModelData( model, '<paragraph>[]foo</paragraph><image src=""><caption></caption></image>' );
 
 			expect( getViewData( viewDocument ) ).to.equal(
 				'<p>{}foo</p>' +
@@ -352,7 +345,7 @@ describe( 'ImageCaptionEngine', () => {
 		} );
 
 		it( 'should not add additional figcaption if one is already present', () => {
-			setModelData( doc, '<paragraph>foo</paragraph>[<image src=""><caption>foo bar</caption></image>]' );
+			setModelData( model, '<paragraph>foo</paragraph>[<image src=""><caption>foo bar</caption></image>]' );
 
 			expect( getViewData( viewDocument ) ).to.equal(
 				'<p>foo</p>' +
@@ -364,9 +357,9 @@ describe( 'ImageCaptionEngine', () => {
 		} );
 
 		it( 'should add hidden class to figcaption when caption is empty and image is no longer selected', () => {
-			setModelData( doc, '<paragraph>foo</paragraph>[<image src=""><caption></caption></image>]' );
+			setModelData( model, '<paragraph>foo</paragraph>[<image src=""><caption></caption></image>]' );
 
-			doc.enqueueChanges( () => {
+			model.change( () => {
 				doc.selection.removeAllRanges();
 			} );
 
@@ -382,10 +375,10 @@ describe( 'ImageCaptionEngine', () => {
 		} );
 
 		it( 'should not remove figcaption when selection is inside it even when it is empty', () => {
-			setModelData( doc, '<image src=""><caption>[foo bar]</caption></image>' );
+			setModelData( model, '<image src=""><caption>[foo bar]</caption></image>' );
 
-			doc.enqueueChanges( () => {
-				doc.batch().remove( doc.selection.getFirstRange() );
+			model.change( writer => {
+				writer.remove( doc.selection.getFirstRange() );
 			} );
 
 			expect( getViewData( viewDocument ) ).to.equal(
@@ -399,11 +392,11 @@ describe( 'ImageCaptionEngine', () => {
 		} );
 
 		it( 'should not remove figcaption when selection is moved from it to its image', () => {
-			setModelData( doc, '<image src=""><caption>[foo bar]</caption></image>' );
+			setModelData( model, '<image src=""><caption>[foo bar]</caption></image>' );
 			const image = doc.getRoot().getChild( 0 );
 
-			doc.enqueueChanges( () => {
-				doc.batch().remove( doc.selection.getFirstRange() );
+			model.change( writer => {
+				writer.remove( doc.selection.getFirstRange() );
 				doc.selection.setRanges( [ ModelRange.createOn( image ) ] );
 			} );
 
@@ -417,10 +410,10 @@ describe( 'ImageCaptionEngine', () => {
 		} );
 
 		it( 'should not remove figcaption when selection is moved from it to other image', () => {
-			setModelData( doc, '<image src=""><caption>[foo bar]</caption></image><image src=""><caption></caption></image>' );
+			setModelData( model, '<image src=""><caption>[foo bar]</caption></image><image src=""><caption></caption></image>' );
 			const image = doc.getRoot().getChild( 1 );
 
-			doc.enqueueChanges( () => {
+			model.change( () => {
 				doc.selection.setRanges( [ ModelRange.createOn( image ) ] );
 			} );
 
@@ -439,17 +432,15 @@ describe( 'ImageCaptionEngine', () => {
 
 		describe( 'undo/redo integration', () => {
 			it( 'should create view element after redo', () => {
-				setModelData( doc, '<paragraph>foo</paragraph><image src=""><caption>[foo bar baz]</caption></image>' );
+				setModelData( model, '<paragraph>foo</paragraph><image src=""><caption>[foo bar baz]</caption></image>' );
 
 				const modelRoot = doc.getRoot();
 				const modelImage = modelRoot.getChild( 1 );
 				const modelCaption = modelImage.getChild( 0 );
 
 				// Remove text and selection from caption.
-				doc.enqueueChanges( () => {
-					const batch = doc.batch();
-
-					batch.remove( ModelRange.createIn( modelCaption ) );
+				model.change( writer => {
+					writer.remove( ModelRange.createIn( modelCaption ) );
 					doc.selection.removeAllRanges();
 				} );
 
@@ -482,19 +473,17 @@ describe( 'ImageCaptionEngine', () => {
 				const image = new ModelElement( 'image' );
 				image.setAttribute( 'src', '/foo.png' );
 
-				setModelData( doc, '<paragraph>foo[]</paragraph>' );
-
-				doc.enqueueChanges( () => {
-					const batch = doc.batch();
+				setModelData( model, '<paragraph>foo[]</paragraph>' );
 
-					batch.insert( image, doc.getRoot() );
+				model.change( writer => {
+					writer.insert( image, doc.getRoot() );
 				} );
 
-				expect( getModelData( doc ) ).to.equal( '<image src="/foo.png"><caption></caption></image><paragraph>foo[]</paragraph>' );
+				expect( getModelData( model ) ).to.equal( '<image src="/foo.png"><caption></caption></image><paragraph>foo[]</paragraph>' );
 
 				editor.execute( 'undo' );
 
-				expect( getModelData( doc ) ).to.equal( '<paragraph>foo[]</paragraph>' );
+				expect( getModelData( model ) ).to.equal( '<paragraph>foo[]</paragraph>' );
 			} );
 		} );
 	} );

+ 28 - 28
packages/ckeditor5-image/tests/imagestyle/imagestylecommand.js

@@ -11,114 +11,114 @@ describe( 'ImageStyleCommand', () => {
 	const defaultStyle = { name: 'defaultStyle', title: 'foo bar', icon: 'icon-1', isDefault: true };
 	const otherStyle = { name: 'otherStyle', title: 'baz', icon: 'icon-2', className: 'other-class-name' };
 
-	let document, defaultStyleCommand, otherStyleCommand;
+	let model, defaultStyleCommand, otherStyleCommand;
 
 	beforeEach( () => {
 		return ModelTestEditor.create()
 			.then( newEditor => {
-				document = newEditor.document;
+				model = newEditor.model;
 				defaultStyleCommand = new ImageStyleCommand( newEditor, defaultStyle );
 				otherStyleCommand = new ImageStyleCommand( newEditor, otherStyle );
 
-				document.schema.registerItem( 'p', '$block' );
+				model.schema.registerItem( 'p', '$block' );
 
-				document.schema.registerItem( 'image' );
-				document.schema.objects.add( 'image' );
-				document.schema.allow( { name: 'image', inside: '$root' } );
-				document.schema.allow( { name: 'image', inside: '$root', attributes: [ 'imageStyle' ] } );
+				model.schema.registerItem( 'image' );
+				model.schema.objects.add( 'image' );
+				model.schema.allow( { name: 'image', inside: '$root' } );
+				model.schema.allow( { name: 'image', inside: '$root', attributes: [ 'imageStyle' ] } );
 			} );
 	} );
 
 	it( 'command value should be false if no image is selected', () => {
-		setData( document, '[]<image></image>' );
+		setData( model, '[]<image></image>' );
 
 		expect( defaultStyleCommand.value ).to.be.false;
 		expect( otherStyleCommand.value ).to.be.false;
 	} );
 
 	it( 'should match default style if no imageStyle attribute is present', () => {
-		setData( document, '[<image></image>]' );
+		setData( model, '[<image></image>]' );
 
 		expect( defaultStyleCommand.value ).to.be.true;
 		expect( otherStyleCommand.value ).to.be.false;
 	} );
 
 	it( 'proper command should have true value when imageStyle attribute is present', () => {
-		setData( document, '[<image imageStyle="otherStyle"></image>]' );
+		setData( model, '[<image imageStyle="otherStyle"></image>]' );
 
 		expect( defaultStyleCommand.value ).to.be.false;
 		expect( otherStyleCommand.value ).to.be.true;
 	} );
 
 	it( 'should have false value if style does not match', () => {
-		setData( document, '[<image imageStyle="foo"></image>]' );
+		setData( model, '[<image imageStyle="foo"></image>]' );
 
 		expect( defaultStyleCommand.value ).to.be.false;
 		expect( otherStyleCommand.value ).to.be.false;
 	} );
 
 	it( 'should set proper value when executed', () => {
-		setData( document, '[<image></image>]' );
+		setData( model, '[<image></image>]' );
 
 		otherStyleCommand.execute();
 
-		expect( getData( document ) ).to.equal( '[<image imageStyle="otherStyle"></image>]' );
+		expect( getData( model ) ).to.equal( '[<image imageStyle="otherStyle"></image>]' );
 	} );
 
 	it( 'should do nothing when attribute already present', () => {
-		setData( document, '[<image imageStyle="otherStyle"></image>]' );
+		setData( model, '[<image imageStyle="otherStyle"></image>]' );
 
 		otherStyleCommand.execute();
 
-		expect( getData( document ) ).to.equal( '[<image imageStyle="otherStyle"></image>]' );
+		expect( getData( model ) ).to.equal( '[<image imageStyle="otherStyle"></image>]' );
 	} );
 
-	it( 'should allow to provide batch instance', () => {
-		const batch = document.batch();
-		const spy = sinon.spy( batch, 'setAttribute' );
+	it( 'should use parent batch', () => {
+		setData( model, '[<image></image>]' );
 
-		setData( document, '[<image></image>]' );
+		model.change( writer => {
+			expect( writer.batch.deltas ).to.length( 0 );
 
-		otherStyleCommand.execute( { batch } );
+			otherStyleCommand.execute();
 
-		expect( getData( document ) ).to.equal( '[<image imageStyle="otherStyle"></image>]' );
-		sinon.assert.calledOnce( spy );
+			expect( writer.batch.deltas ).to.length.above( 0 );
+		} );
 	} );
 
 	it( 'should be enabled on image element', () => {
-		setData( document, '[<image></image>]' );
+		setData( model, '[<image></image>]' );
 
 		expect( defaultStyleCommand.isEnabled ).to.be.true;
 		expect( otherStyleCommand.isEnabled ).to.be.true;
 	} );
 
 	it( 'should be disabled when not placed on image', () => {
-		setData( document, '[<p></p>]' );
+		setData( model, '[<p></p>]' );
 
 		expect( defaultStyleCommand.isEnabled ).to.be.false;
 		expect( otherStyleCommand.isEnabled ).to.be.false;
 	} );
 
 	it( 'should be disabled when not placed directly on image', () => {
-		setData( document, '[<p></p><image></image>]' );
+		setData( model, '[<p></p><image></image>]' );
 
 		expect( defaultStyleCommand.isEnabled ).to.be.false;
 		expect( otherStyleCommand.isEnabled ).to.be.false;
 	} );
 
 	it( 'default style should be active after executing it after another style', () => {
-		setData( document, '[<image></image>]' );
+		setData( model, '[<image></image>]' );
 
 		expect( defaultStyleCommand.value ).to.be.true;
 		expect( otherStyleCommand.value ).to.be.false;
 
 		otherStyleCommand.execute();
 
-		expect( getData( document ) ).to.equal( '[<image imageStyle="otherStyle"></image>]' );
+		expect( getData( model ) ).to.equal( '[<image imageStyle="otherStyle"></image>]' );
 
 		defaultStyleCommand.execute();
 
-		expect( getData( document ) ).to.equal( '[<image></image>]' );
+		expect( getData( model ) ).to.equal( '[<image></image>]' );
 		expect( defaultStyleCommand.value ).to.be.true;
 		expect( otherStyleCommand.value ).to.be.false;
 	} );

+ 38 - 46
packages/ckeditor5-image/tests/imagestyle/imagestyleengine.js

@@ -22,7 +22,7 @@ import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils';
 testUtils.createSinonSandbox();
 
 describe( 'ImageStyleEngine', () => {
-	let editor, plugin, document, viewDocument;
+	let editor, plugin, model, document, viewDocument;
 
 	afterEach( () => {
 		editor.destroy();
@@ -63,7 +63,8 @@ describe( 'ImageStyleEngine', () => {
 				} )
 				.then( newEditor => {
 					editor = newEditor;
-					document = editor.document;
+					model = editor.model;
+					document = model.document;
 					viewDocument = editor.editing.view;
 				} );
 		} );
@@ -81,7 +82,7 @@ describe( 'ImageStyleEngine', () => {
 		} );
 
 		it( 'should set schema rules for image style', () => {
-			const schema = document.schema;
+			const schema = model.schema;
 
 			expect( schema.check( { name: 'image', attributes: [ 'imageStyle', 'src' ], inside: '$root' } ) ).to.be.true;
 		} );
@@ -95,7 +96,7 @@ describe( 'ImageStyleEngine', () => {
 		it( 'should convert from view to model', () => {
 			editor.setData( '<figure class="image side-class"><img src="foo.png" /></figure>' );
 
-			expect( getModelData( document, { withoutSelection: true } ) )
+			expect( getModelData( model, { withoutSelection: true } ) )
 				.to.equal( '<image imageStyle="sideStyle" src="foo.png"></image>' );
 			expect( getViewData( viewDocument, { withoutSelection: true } ) ).to.equal(
 				'<figure class="ck-widget image side-class" contenteditable="false">' +
@@ -106,7 +107,7 @@ describe( 'ImageStyleEngine', () => {
 		it( 'should not convert from view to model if class is not defined', () => {
 			editor.setData( '<figure class="image foo-bar"><img src="foo.png" /></figure>' );
 
-			expect( getModelData( document, { withoutSelection: true } ) ).to.equal( '<image src="foo.png"></image>' );
+			expect( getModelData( model, { withoutSelection: true } ) ).to.equal( '<image src="foo.png"></image>' );
 			expect( getViewData( viewDocument, { withoutSelection: true } ) ).to.equal(
 				'<figure class="ck-widget image" contenteditable="false"><img src="foo.png"></img></figure>'
 			);
@@ -115,27 +116,26 @@ describe( 'ImageStyleEngine', () => {
 		it( 'should not convert from view to model when not in image figure', () => {
 			editor.setData( '<figure class="side-class"></figure>' );
 
-			expect( getModelData( document, { withoutSelection: true } ) ).to.equal( '' );
+			expect( getModelData( model, { withoutSelection: true } ) ).to.equal( '' );
 			expect( getViewData( viewDocument, { withoutSelection: true } ) ).to.equal( '' );
 		} );
 
 		it( 'should not convert from view to model if schema prevents it', () => {
-			document.schema.disallow( { name: 'image', attributes: 'imageStyle' } );
+			model.schema.disallow( { name: 'image', attributes: 'imageStyle' } );
 			editor.setData( '<figure class="image side-class"><img src="foo.png" /></figure>' );
 
-			expect( getModelData( document, { withoutSelection: true } ) ).to.equal( '<image src="foo.png"></image>' );
+			expect( getModelData( model, { withoutSelection: true } ) ).to.equal( '<image src="foo.png"></image>' );
 			expect( getViewData( viewDocument, { withoutSelection: true } ) ).to.equal(
 				'<figure class="ck-widget image" contenteditable="false"><img src="foo.png"></img></figure>'
 			);
 		} );
 
 		it( 'should convert model to view: adding attribute', () => {
-			setModelData( document, '<image src="foo.png"></image>' );
+			setModelData( model, '<image src="foo.png"></image>' );
 			const image = document.getRoot().getChild( 0 );
-			const batch = document.batch();
 
-			document.enqueueChanges( () => {
-				batch.setAttribute( 'imageStyle', 'sideStyle', image );
+			model.change( writer => {
+				writer.setAttribute( 'imageStyle', 'sideStyle', image );
 			} );
 
 			expect( editor.getData() ).to.equal( '<figure class="image side-class"><img src="foo.png"></figure>' );
@@ -145,12 +145,11 @@ describe( 'ImageStyleEngine', () => {
 		} );
 
 		it( 'should convert model to view: removing attribute', () => {
-			setModelData( document, '<image src="foo.png" imageStyle="sideStyle"></image>' );
+			setModelData( model, '<image src="foo.png" imageStyle="sideStyle"></image>' );
 			const image = document.getRoot().getChild( 0 );
-			const batch = document.batch();
 
-			document.enqueueChanges( () => {
-				batch.setAttribute( 'imageStyle', null, image );
+			model.change( writer => {
+				writer.setAttribute( 'imageStyle', null, image );
 			} );
 
 			expect( editor.getData() ).to.equal( '<figure class="image"><img src="foo.png"></figure>' );
@@ -160,12 +159,11 @@ describe( 'ImageStyleEngine', () => {
 		} );
 
 		it( 'should convert model to view: change attribute', () => {
-			setModelData( document, '<image src="foo.png" imageStyle="dummy"></image>' );
+			setModelData( model, '<image src="foo.png" imageStyle="dummy"></image>' );
 			const image = document.getRoot().getChild( 0 );
-			const batch = document.batch();
 
-			document.enqueueChanges( () => {
-				batch.setAttribute( 'imageStyle', 'sideStyle', image );
+			model.change( writer => {
+				writer.setAttribute( 'imageStyle', 'sideStyle', image );
 			} );
 
 			expect( editor.getData() ).to.equal( '<figure class="image side-class"><img src="foo.png"></figure>' );
@@ -175,8 +173,8 @@ describe( 'ImageStyleEngine', () => {
 				'<figure class="ck-widget image side-class" contenteditable="false"><img src="foo.png"></img></figure>'
 			);
 
-			document.enqueueChanges( () => {
-				batch.setAttribute( 'imageStyle', 'dummyStyle', image );
+			model.change( writer => {
+				writer.setAttribute( 'imageStyle', 'dummyStyle', image );
 			} );
 
 			expect( editor.getData() ).to.equal( '<figure class="image dummy-class"><img src="foo.png"></figure>' );
@@ -192,12 +190,11 @@ describe( 'ImageStyleEngine', () => {
 				consumable.consume( data.item, 'addAttribute:imageStyle' );
 			}, { priority: 'high' } );
 
-			setModelData( document, '<image src="foo.png"></image>' );
+			setModelData( model, '<image src="foo.png"></image>' );
 			const image = document.getRoot().getChild( 0 );
-			const batch = document.batch();
 
-			document.enqueueChanges( () => {
-				batch.setAttribute( 'imageStyle', 'sideStyle', image );
+			model.change( writer => {
+				writer.setAttribute( 'imageStyle', 'sideStyle', image );
 			} );
 
 			expect( getViewData( viewDocument, { withoutSelection: true } ) ).to.equal(
@@ -210,12 +207,11 @@ describe( 'ImageStyleEngine', () => {
 				consumable.consume( data.item, 'removeAttribute:imageStyle' );
 			}, { priority: 'high' } );
 
-			setModelData( document, '<image src="foo.png" imageStyle="sideStyle"></image>' );
+			setModelData( model, '<image src="foo.png" imageStyle="sideStyle"></image>' );
 			const image = document.getRoot().getChild( 0 );
-			const batch = document.batch();
 
-			document.enqueueChanges( () => {
-				batch.setAttribute( 'imageStyle', null, image );
+			model.change( writer => {
+				writer.removeAttribute( 'imageStyle', image );
 			} );
 
 			expect( getViewData( viewDocument, { withoutSelection: true } ) ).to.equal(
@@ -228,12 +224,11 @@ describe( 'ImageStyleEngine', () => {
 				consumable.consume( data.item, 'changeAttribute:imageStyle' );
 			}, { priority: 'high' } );
 
-			setModelData( document, '<image src="foo.png" imageStyle="dummyStyle"></image>' );
+			setModelData( model, '<image src="foo.png" imageStyle="dummyStyle"></image>' );
 			const image = document.getRoot().getChild( 0 );
-			const batch = document.batch();
 
-			document.enqueueChanges( () => {
-				batch.setAttribute( 'imageStyle', 'sideStyle', image );
+			model.change( writer => {
+				writer.setAttribute( 'imageStyle', 'sideStyle', image );
 			} );
 
 			expect( getViewData( viewDocument, { withoutSelection: true } ) ).to.equal(
@@ -242,12 +237,11 @@ describe( 'ImageStyleEngine', () => {
 		} );
 
 		it( 'should not convert from model to view if style is not present: adding attribute', () => {
-			setModelData( document, '<image src="foo.png"></image>' );
+			setModelData( model, '<image src="foo.png"></image>' );
 			const image = document.getRoot().getChild( 0 );
-			const batch = document.batch();
 
-			document.enqueueChanges( () => {
-				batch.setAttribute( 'imageStyle', 'foo', image );
+			model.change( writer => {
+				writer.setAttribute( 'imageStyle', 'foo', image );
 			} );
 
 			expect( editor.getData() ).to.equal( '<figure class="image"><img src="foo.png"></figure>' );
@@ -257,12 +251,11 @@ describe( 'ImageStyleEngine', () => {
 		} );
 
 		it( 'should not convert from model to view if style is not present: change attribute', () => {
-			setModelData( document, '<image src="foo.png" imageStyle="dummy"></image>' );
+			setModelData( model, '<image src="foo.png" imageStyle="dummy"></image>' );
 			const image = document.getRoot().getChild( 0 );
-			const batch = document.batch();
 
-			document.enqueueChanges( () => {
-				batch.setAttribute( 'imageStyle', 'foo', image );
+			model.change( writer => {
+				writer.setAttribute( 'imageStyle', 'foo', image );
 			} );
 
 			expect( editor.getData() ).to.equal( '<figure class="image"><img src="foo.png"></figure>' );
@@ -272,12 +265,11 @@ describe( 'ImageStyleEngine', () => {
 		} );
 
 		it( 'should not convert from model to view if style is not present: remove attribute', () => {
-			setModelData( document, '<image src="foo.png" imageStyle="foo"></image>' );
+			setModelData( model, '<image src="foo.png" imageStyle="foo"></image>' );
 			const image = document.getRoot().getChild( 0 );
-			const batch = document.batch();
 
-			document.enqueueChanges( () => {
-				batch.setAttribute( 'imageStyle', null, image );
+			model.change( writer => {
+				writer.setAttribute( 'imageStyle', null, image );
 			} );
 
 			expect( editor.getData() ).to.equal( '<figure class="image"><img src="foo.png"></figure>' );

+ 17 - 16
packages/ckeditor5-image/tests/imagetextalternative.js

@@ -16,7 +16,7 @@ import { setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
 import { keyCodes } from '@ckeditor/ckeditor5-utils/src/keyboard';
 
 describe( 'ImageTextAlternative', () => {
-	let editor, editingView, doc, plugin, command, form, balloon, editorElement, button;
+	let editor, editingView, model, doc, plugin, command, form, balloon, editorElement, button;
 
 	beforeEach( () => {
 		editorElement = global.document.createElement( 'div' );
@@ -28,8 +28,9 @@ describe( 'ImageTextAlternative', () => {
 			} )
 			.then( newEditor => {
 				editor = newEditor;
+				model = editor.model;
 				editingView = editor.editing.view;
-				doc = editor.document;
+				doc = model.document;
 				newEditor.editing.view.attachDomRoot( editorElement );
 				plugin = editor.plugins.get( ImageTextAlternative );
 				command = editor.commands.get( 'imageTextAlternative' );
@@ -69,7 +70,7 @@ describe( 'ImageTextAlternative', () => {
 		it( 'should show balloon panel on execute', () => {
 			expect( balloon.visibleView ).to.be.null;
 
-			setData( doc, '[<image src="" alt="foo bar"></image>]' );
+			setData( model, '[<image src="" alt="foo bar"></image>]' );
 
 			button.fire( 'execute' );
 			expect( balloon.visibleView ).to.equal( form );
@@ -83,7 +84,7 @@ describe( 'ImageTextAlternative', () => {
 		it( 'should set alt attribute value to textarea and select it', () => {
 			const spy = sinon.spy( form.labeledInput, 'select' );
 
-			setData( doc, '[<image src="" alt="foo bar"></image>]' );
+			setData( model, '[<image src="" alt="foo bar"></image>]' );
 
 			button.fire( 'execute' );
 			sinon.assert.calledOnce( spy );
@@ -93,7 +94,7 @@ describe( 'ImageTextAlternative', () => {
 		it( 'should set empty text to textarea and select it when there is no alt attribute', () => {
 			const spy = sinon.spy( form.labeledInput, 'select' );
 
-			setData( doc, '[<image src=""></image>]' );
+			setData( model, '[<image src=""></image>]' );
 
 			button.fire( 'execute' );
 			sinon.assert.calledOnce( spy );
@@ -114,7 +115,7 @@ describe( 'ImageTextAlternative', () => {
 			form.labeledInput.inputView.element.value = 'This value was canceled.';
 
 			// Mock the user editing the same image once again.
-			setData( doc, '[<image src="" alt="foo"></image>]' );
+			setData( model, '[<image src="" alt="foo"></image>]' );
 
 			button.fire( 'execute' );
 			expect( form.labeledInput.inputView.element.value ).to.equal( 'foo' );
@@ -133,7 +134,7 @@ describe( 'ImageTextAlternative', () => {
 		it( 'should hide the panel on cancel and focus the editing view', () => {
 			const spy = sinon.spy( editor.editing.view, 'focus' );
 
-			setData( doc, '[<image src="" alt="foo bar"></image>]' );
+			setData( model, '[<image src="" alt="foo bar"></image>]' );
 
 			editor.ui.componentFactory.create( 'imageTextAlternative' ).fire( 'execute' );
 			expect( balloon.visibleView ).to.equal( form );
@@ -144,7 +145,7 @@ describe( 'ImageTextAlternative', () => {
 		} );
 
 		it( 'should not engage when the form is in the balloon yet invisible', () => {
-			setData( doc, '[<image src=""></image>]' );
+			setData( model, '[<image src=""></image>]' );
 			button.fire( 'execute' );
 			expect( balloon.visibleView ).to.equal( form );
 
@@ -160,7 +161,7 @@ describe( 'ImageTextAlternative', () => {
 
 		describe( 'integration with the editor selection (#render event)', () => {
 			it( 'should re-position the form', () => {
-				setData( doc, '[<image src=""></image>]' );
+				setData( model, '[<image src=""></image>]' );
 				button.fire( 'execute' );
 
 				const spy = sinon.spy( balloon, 'updatePosition' );
@@ -170,15 +171,15 @@ describe( 'ImageTextAlternative', () => {
 			} );
 
 			it( 'should hide the form and focus editable when image widget has been removed by external change', () => {
-				setData( doc, '[<image src=""></image>]' );
+				setData( model, '[<image src=""></image>]' );
 				button.fire( 'execute' );
 
 				const remveSpy = sinon.spy( balloon, 'remove' );
 				const focusSpy = sinon.spy( editor.editing.view, 'focus' );
 
-				// EnqueueChanges automatically fires #render event.
-				doc.enqueueChanges( () => {
-					doc.batch( 'transparent' ).remove( doc.selection.getFirstRange() );
+				// EnqueueChange automatically fires #render event.
+				model.enqueueChange( 'transparent', writer => {
+					writer.remove( doc.selection.getFirstRange() );
 				} );
 
 				sinon.assert.calledWithExactly( remveSpy, form );
@@ -192,7 +193,7 @@ describe( 'ImageTextAlternative', () => {
 					const hideSpy = sinon.spy( plugin, '_hideForm' );
 					const focusSpy = sinon.spy( editor.editing.view, 'focus' );
 
-					setData( doc, '[<image src=""></image>]' );
+					setData( model, '[<image src=""></image>]' );
 					button.fire( 'execute' );
 
 					const keyEvtData = {
@@ -213,7 +214,7 @@ describe( 'ImageTextAlternative', () => {
 					const hideSpy = sinon.spy( plugin, '_hideForm' );
 					const focusSpy = sinon.spy( editor.editing.view, 'focus' );
 
-					setData( doc, '[<image src=""></image>]' );
+					setData( model, '[<image src=""></image>]' );
 					button.fire( 'execute' );
 
 					global.document.body.dispatchEvent( new Event( 'mousedown', { bubbles: true } ) );
@@ -224,7 +225,7 @@ describe( 'ImageTextAlternative', () => {
 				it( 'should not close on click inside the panel', () => {
 					const spy = sinon.spy( plugin, '_hideForm' );
 
-					setData( doc, '[<image src=""></image>]' );
+					setData( model, '[<image src=""></image>]' );
 					button.fire( 'execute' );
 
 					form.element.dispatchEvent( new Event( 'mousedown', { bubbles: true } ) );

+ 23 - 23
packages/ckeditor5-image/tests/imagetextalternative/imagetextalternativecommand.js

@@ -8,78 +8,78 @@ import ImageTextAlternativeCommand from '../../src/imagetextalternative/imagetex
 import { setData, getData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
 
 describe( 'ImageTextAlternativeCommand', () => {
-	let document, command;
+	let model, command;
 
 	beforeEach( () => {
 		return ModelTestEditor.create()
 			.then( newEditor => {
-				document = newEditor.document;
+				model = newEditor.model;
 				command = new ImageTextAlternativeCommand( newEditor );
 
-				document.schema.registerItem( 'p', '$block' );
+				model.schema.registerItem( 'p', '$block' );
 
-				document.schema.registerItem( 'image' );
-				document.schema.requireAttributes( 'image', [ 'src' ] );
-				document.schema.allow( { name: 'image', attributes: [ 'alt', 'src' ], inside: '$root' } );
-				document.schema.objects.add( 'image' );
+				model.schema.registerItem( 'image' );
+				model.schema.requireAttributes( 'image', [ 'src' ] );
+				model.schema.allow( { name: 'image', attributes: [ 'alt', 'src' ], inside: '$root' } );
+				model.schema.objects.add( 'image' );
 			} );
 	} );
 
 	it( 'should have false value if no image is selected', () => {
-		setData( document, '[]<p></p>' );
+		setData( model, '[]<p></p>' );
 
 		expect( command.value ).to.be.false;
 	} );
 
 	it( 'should have false value if image without alt is selected', () => {
-		setData( document, '[<image src="image.png"></image>]' );
+		setData( model, '[<image src="image.png"></image>]' );
 
 		expect( command.value ).to.be.false;
 	} );
 
 	it( 'should be disabled if not on image element', () => {
-		setData( document, '[]<p></p>' );
+		setData( model, '[]<p></p>' );
 
 		expect( command.isEnabled ).to.be.false;
 	} );
 
 	it( 'should be enabled on image element without alt attribute', () => {
-		setData( document, '[<image src="image.png"></image>]' );
+		setData( model, '[<image src="image.png"></image>]' );
 
 		expect( command.isEnabled ).to.be.true;
 	} );
 
 	it( 'should have proper value if on image element with alt attribute', () => {
-		setData( document, '[<image src="image.png" alt="foo bar baz"></image>]' );
+		setData( model, '[<image src="image.png" alt="foo bar baz"></image>]' );
 
 		expect( command.value ).to.equal( 'foo bar baz' );
 	} );
 
 	it( 'should set proper alt if executed on image without alt attribute', () => {
-		setData( document, '[<image src="image.png"></image>]' );
+		setData( model, '[<image src="image.png"></image>]' );
 
 		command.execute( { newValue: 'fiz buz' } );
 
-		expect( getData( document ) ).to.equal( '[<image alt="fiz buz" src="image.png"></image>]' );
+		expect( getData( model ) ).to.equal( '[<image alt="fiz buz" src="image.png"></image>]' );
 	} );
 
 	it( 'should change alt if executed on image with alt attribute', () => {
-		setData( document, '[<image alt="foo bar" src="image.png"></image>]' );
+		setData( model, '[<image alt="foo bar" src="image.png"></image>]' );
 
 		command.execute( { newValue: 'fiz buz' } );
 
-		expect( getData( document ) ).to.equal( '[<image alt="fiz buz" src="image.png"></image>]' );
+		expect( getData( model ) ).to.equal( '[<image alt="fiz buz" src="image.png"></image>]' );
 	} );
 
-	it( 'should allow to provide batch instance', () => {
-		const batch = document.batch();
-		const spy = sinon.spy( batch, 'setAttribute' );
+	it( 'should use parent batch', () => {
+		setData( model, '[<image src="image.png"></image>]' );
 
-		setData( document, '[<image src="image.png"></image>]' );
+		model.change( writer => {
+			expect( writer.batch.deltas ).to.length( 0 );
 
-		command.execute( { newValue: 'foo bar', batch } );
+			command.execute( { newValue: 'foo bar' } );
 
-		expect( getData( document ) ).to.equal( '[<image alt="foo bar" src="image.png"></image>]' );
-		sinon.assert.calledOnce( spy );
+			expect( writer.batch.deltas ).to.length.above( 0 );
+		} );
 	} );
 } );

+ 12 - 11
packages/ckeditor5-image/tests/imagetoolbar.js

@@ -17,7 +17,7 @@ import View from '@ckeditor/ckeditor5-ui/src/view';
 import { setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
 
 describe( 'ImageToolbar', () => {
-	let editor, doc, editingView, plugin, toolbar, balloon, editorElement;
+	let editor, model, doc, editingView, plugin, toolbar, balloon, editorElement;
 
 	beforeEach( () => {
 		editorElement = global.document.createElement( 'div' );
@@ -32,7 +32,8 @@ describe( 'ImageToolbar', () => {
 			} )
 			.then( newEditor => {
 				editor = newEditor;
-				doc = editor.document;
+				model = newEditor.model;
+				doc = model.document;
 				plugin = editor.plugins.get( ImageToolbar );
 				toolbar = plugin._toolbar;
 				editingView = editor.editing.view;
@@ -61,7 +62,7 @@ describe( 'ImageToolbar', () => {
 				expect( editor.plugins.get( ImageToolbar )._toolbar ).to.be.undefined;
 
 				editorElement.remove();
-				editor.destroy();
+				return editor.destroy();
 			} );
 	} );
 
@@ -76,7 +77,7 @@ describe( 'ImageToolbar', () => {
 
 			editor.ui.focusTracker.isFocused = true;
 
-			setData( doc, '[<image src=""></image>]' );
+			setData( model, '[<image src=""></image>]' );
 
 			expect( toolbar.element.classList.contains( 'ck-editor-toolbar' ) ).to.be.true;
 
@@ -91,7 +92,7 @@ describe( 'ImageToolbar', () => {
 		it( 'should show the toolbar when the editor gains focus and the image is selected', () => {
 			editor.ui.focusTracker.isFocused = true;
 
-			setData( doc, '[<image src=""></image>]' );
+			setData( model, '[<image src=""></image>]' );
 
 			editor.ui.focusTracker.isFocused = false;
 			expect( balloon.visibleView ).to.be.null;
@@ -103,7 +104,7 @@ describe( 'ImageToolbar', () => {
 		it( 'should hide the toolbar when the editor loses focus and the image is selected', () => {
 			editor.ui.focusTracker.isFocused = false;
 
-			setData( doc, '[<image src=""></image>]' );
+			setData( model, '[<image src=""></image>]' );
 
 			editor.ui.focusTracker.isFocused = true;
 			expect( balloon.visibleView ).to.equal( toolbar );
@@ -119,14 +120,14 @@ describe( 'ImageToolbar', () => {
 		} );
 
 		it( 'should show the toolbar on render when the image is selected', () => {
-			setData( doc, '<paragraph>[foo]</paragraph><image src=""></image>' );
+			setData( model, '<paragraph>[foo]</paragraph><image src=""></image>' );
 
 			expect( balloon.visibleView ).to.be.null;
 
 			editingView.fire( 'render' );
 			expect( balloon.visibleView ).to.be.null;
 
-			doc.enqueueChanges( () => {
+			model.change( () => {
 				// Select the [<image></image>]
 				doc.selection.setRanges( [
 					Range.createOn( doc.getRoot().getChild( 1 ) )
@@ -142,7 +143,7 @@ describe( 'ImageToolbar', () => {
 		} );
 
 		it( 'should not engage when the toolbar is in the balloon yet invisible', () => {
-			setData( doc, '[<image src=""></image>]' );
+			setData( model, '[<image src=""></image>]' );
 			expect( balloon.visibleView ).to.equal( toolbar );
 
 			const lastView = new View();
@@ -156,11 +157,11 @@ describe( 'ImageToolbar', () => {
 		} );
 
 		it( 'should hide the toolbar on render if the image is de–selected', () => {
-			setData( doc, '<paragraph>foo</paragraph>[<image src=""></image>]' );
+			setData( model, '<paragraph>foo</paragraph>[<image src=""></image>]' );
 
 			expect( balloon.visibleView ).to.equal( toolbar );
 
-			doc.enqueueChanges( () => {
+			model.change( () => {
 				// Select the <paragraph>[...]</paragraph>
 				doc.selection.setRanges( [
 					Range.createIn( doc.getRoot().getChild( 0 ) )

+ 3 - 3
packages/ckeditor5-image/tests/integration.js

@@ -47,7 +47,7 @@ describe( 'Image integration', () => {
 
 		it( 'should prevent the ContextualToolbar from being displayed when an image is selected', () => {
 			// When image is selected along with text.
-			setModelData( newEditor.document, '<paragraph>fo[o</paragraph><image alt="alt text" src="foo.png"></image>]' );
+			setModelData( newEditor.model, '<paragraph>fo[o</paragraph><image alt="alt text" src="foo.png"></image>]' );
 
 			contextualToolbar.show();
 
@@ -55,7 +55,7 @@ describe( 'Image integration', () => {
 			expect( balloon.visibleView ).to.equal( contextualToolbar.toolbarView );
 
 			// When only image is selected.
-			setModelData( newEditor.document, '<paragraph>foo</paragraph>[<image alt="alt text" src="foo.png"></image>]' );
+			setModelData( newEditor.model, '<paragraph>foo</paragraph>[<image alt="alt text" src="foo.png"></image>]' );
 
 			contextualToolbar.show();
 
@@ -69,7 +69,7 @@ describe( 'Image integration', () => {
 			const normalPrioritySpy = sinon.spy();
 
 			// Select an image
-			setModelData( newEditor.document, '<paragraph>foo</paragraph>[<image alt="alt text" src="foo.png"></image>]' );
+			setModelData( newEditor.model, '<paragraph>foo</paragraph>[<image alt="alt text" src="foo.png"></image>]' );
 
 			newEditor.listenTo( contextualToolbar, 'show', highestPrioritySpy, { priority: 'highest' } );
 			newEditor.listenTo( contextualToolbar, 'show', highPrioritySpy, { priority: 'high' } );

+ 9 - 13
packages/ckeditor5-image/tests/manual/tickets/106/1.js

@@ -8,8 +8,6 @@
 import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor';
 import ArticlePluginSet from '@ckeditor/ckeditor5-core/tests/_utils/articlepluginset';
 
-import Element from '@ckeditor/ckeditor5-engine/src/model/element';
-import Text from '@ckeditor/ckeditor5-engine/src/model/text';
 import Position from '@ckeditor/ckeditor5-engine/src/model/position';
 import Range from '@ckeditor/ckeditor5-engine/src/model/range';
 
@@ -52,18 +50,17 @@ function wait( delay ) {
 }
 
 function startExternalInsert( editor ) {
-	const document = editor.document;
-	const bath = document.batch( 'transparent' );
+	const model = editor.model;
 
 	function type( path, text ) {
 		return new Promise( resolve => {
-			let position = new Position( document.getRoot(), path );
+			let position = new Position( model.document.getRoot(), path );
 			let index = 0;
 
 			function typing() {
 				wait( 40 ).then( () => {
-					document.enqueueChanges( () => {
-						bath.insert( position, new Text( text[ index ] ) );
+					model.enqueueChange( 'transparent', writer => {
+						writer.insertText( text[ index ], position );
 						position = position.getShiftedBy( 1 );
 
 						const nextLetter = text[ ++index ];
@@ -84,8 +81,8 @@ function startExternalInsert( editor ) {
 
 	function insertNewLine( path ) {
 		return wait( 200 ).then( () => {
-			document.enqueueChanges( () => {
-				bath.insert( new Position( document.getRoot(), path ), new Element( 'paragraph' ) );
+			model.enqueueChange( 'transparent', writer => {
+				writer.insertElement( 'paragraph', new Position( model.document.getRoot(), path ) );
 			} );
 
 			return Promise.resolve();
@@ -105,12 +102,11 @@ function startExternalInsert( editor ) {
 }
 
 function startExternalDelete( editor ) {
-	const document = editor.document;
-	const bath = document.batch( 'transparent' );
+	const model = editor.model;
 
 	function removeSecondBlock() {
-		document.enqueueChanges( () => {
-			bath.remove( Range.createFromPositionAndShift( new Position( document.getRoot(), [ 1 ] ), 1 ) );
+		model.enqueueChange( 'transparent', writer => {
+			writer.remove( Range.createFromPositionAndShift( new Position( model.document.getRoot(), [ 1 ] ), 1 ) );
 		} );
 	}