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

Changed: Moved `consumable` parameter to `conversionApi` parameter in downcast.

Szymon Cofalik 8 лет назад
Родитель
Сommit
aee8d7f71b

+ 23 - 24
packages/ckeditor5-engine/src/conversion/downcast-converters.js

@@ -431,10 +431,9 @@ function _normalizeToAttributeConfig( view ) {
  *
  *		downcastDispatcher.on(
  *			'insert:myElem',
- *			insertElement( ( modelItem, consumable, conversionApi ) => {
- *				const writer = conversionApi.writer;
- *				const text = writer.createText( 'myText' );
- *				const myElem = writer.createElement( 'myElem', { myAttr: 'my-' + modelItem.getAttribute( 'myAttr' ) }, text );
+ *			insertElement( ( modelItem, viewWriter ) => {
+ *				const text = viewWriter.createText( 'myText' );
+ *				const myElem = viewWriter.createElement( 'myElem', { myAttr: 'my-' + modelItem.getAttribute( 'myAttr' ) }, text );
  *
  *				// Do something fancy with myElem using `modelItem` or other parameters.
  *
@@ -446,14 +445,14 @@ function _normalizeToAttributeConfig( view ) {
  * @returns {Function} Insert element event converter.
  */
 export function insertElement( elementCreator ) {
-	return ( evt, data, consumable, conversionApi ) => {
+	return ( evt, data, conversionApi ) => {
 		const viewElement = elementCreator( data.item, conversionApi.writer );
 
 		if ( !viewElement ) {
 			return;
 		}
 
-		if ( !consumable.consume( data.item, 'insert' ) ) {
+		if ( !conversionApi.consumable.consume( data.item, 'insert' ) ) {
 			return;
 		}
 
@@ -475,8 +474,8 @@ export function insertElement( elementCreator ) {
  * @returns {Function} Insert text event converter.
  */
 export function insertText() {
-	return ( evt, data, consumable, conversionApi ) => {
-		if ( !consumable.consume( data.item, 'insert' ) ) {
+	return ( evt, data, conversionApi ) => {
+		if ( !conversionApi.consumable.consume( data.item, 'insert' ) ) {
 			return;
 		}
 
@@ -530,7 +529,7 @@ export function remove() {
  * @returns {Function} Insert element event converter.
  */
 export function insertUIElement( elementCreator ) {
-	return ( evt, data, consumable, conversionApi ) => {
+	return ( evt, data, conversionApi ) => {
 		// Create two view elements. One will be inserted at the beginning of marker, one at the end.
 		// If marker is collapsed, only "opening" element will be inserted.
 		data.isOpening = true;
@@ -548,13 +547,13 @@ export function insertUIElement( elementCreator ) {
 		// Marker that is collapsed has consumable build differently that non-collapsed one.
 		// For more information see `addMarker` event description.
 		// If marker's range is collapsed - check if it can be consumed.
-		if ( markerRange.isCollapsed && !consumable.consume( markerRange, evt.name ) ) {
+		if ( markerRange.isCollapsed && !conversionApi.consumable.consume( markerRange, evt.name ) ) {
 			return;
 		}
 
 		// If marker's range is not collapsed - consume all items inside.
 		for ( const value of markerRange ) {
-			if ( !consumable.consume( value.item, evt.name ) ) {
+			if ( !conversionApi.consumable.consume( value.item, evt.name ) ) {
 				return;
 			}
 		}
@@ -646,8 +645,8 @@ export function removeUIElement( elementCreator ) {
 export function changeAttribute( attributeCreator ) {
 	attributeCreator = attributeCreator || ( ( value, data ) => ( { value, key: data.attributeKey } ) );
 
-	return ( evt, data, consumable, conversionApi ) => {
-		if ( !consumable.consume( data.item, evt.name ) ) {
+	return ( evt, data, conversionApi ) => {
+		if ( !conversionApi.consumable.consume( data.item, evt.name ) ) {
 			return;
 		}
 
@@ -676,7 +675,7 @@ export function changeAttribute( attributeCreator ) {
 		}
 
 		// Then, if conversion was successful, set the new attribute.
-		const newAttribute = attributeCreator( data.attributeNewValue, data, consumable, conversionApi );
+		const newAttribute = attributeCreator( data.attributeNewValue, data );
 
 		if ( data.attributeNewValue !== null && newAttribute ) {
 			if ( newAttribute.key == 'class' ) {
@@ -721,15 +720,15 @@ export function changeAttribute( attributeCreator ) {
  * The converter automatically consumes corresponding value from consumables list, stops the event (see
  * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher}).
  *
- *		modelDispatcher.on( 'attribute:bold', wrapItem( ( attributeValue, data, consumable, conversionApi ) => {
- *			return conversionApi.writer.createAttributeElement( 'strong' );
+ *		modelDispatcher.on( 'attribute:bold', wrapItem( ( modelAttributeValue, viewWriter ) => {
+ *			return viewWriter.createAttributeElement( 'strong' );
  *		} );
  *
  * @param {Function} elementCreator Function returning a view element, which will be used for wrapping.
  * @returns {Function} Set/change attribute converter.
  */
 export function wrap( elementCreator ) {
-	return ( evt, data, consumable, conversionApi ) => {
+	return ( evt, data, conversionApi ) => {
 		// Recreate current wrapping node. It will be used to unwrap view range if the attribute value has changed
 		// or the attribute was removed.
 		const oldViewElement = elementCreator( data.attributeOldValue, conversionApi.writer );
@@ -741,7 +740,7 @@ export function wrap( elementCreator ) {
 			return;
 		}
 
-		if ( !consumable.consume( data.item, evt.name ) ) {
+		if ( !conversionApi.consumable.consume( data.item, evt.name ) ) {
 			return;
 		}
 
@@ -783,7 +782,7 @@ export function wrap( elementCreator ) {
  * @return {Function}
  */
 export function highlightText( highlightDescriptor ) {
-	return ( evt, data, consumable, conversionApi ) => {
+	return ( evt, data, conversionApi ) => {
 		if ( data.markerRange.isCollapsed ) {
 			return;
 		}
@@ -798,7 +797,7 @@ export function highlightText( highlightDescriptor ) {
 			return;
 		}
 
-		if ( !consumable.consume( data.item, evt.name ) ) {
+		if ( !conversionApi.consumable.consume( data.item, evt.name ) ) {
 			return;
 		}
 
@@ -833,7 +832,7 @@ export function highlightText( highlightDescriptor ) {
  * @return {Function}
  */
 export function highlightElement( highlightDescriptor ) {
-	return ( evt, data, consumable, conversionApi ) => {
+	return ( evt, data, conversionApi ) => {
 		if ( data.markerRange.isCollapsed ) {
 			return;
 		}
@@ -848,7 +847,7 @@ export function highlightElement( highlightDescriptor ) {
 			return;
 		}
 
-		if ( !consumable.test( data.item, evt.name ) ) {
+		if ( !conversionApi.consumable.test( data.item, evt.name ) ) {
 			return;
 		}
 
@@ -856,11 +855,11 @@ export function highlightElement( highlightDescriptor ) {
 
 		if ( viewElement && viewElement.getCustomProperty( 'addHighlight' ) ) {
 			// Consume element itself.
-			consumable.consume( data.item, evt.name );
+			conversionApi.consumable.consume( data.item, evt.name );
 
 			// Consume all children nodes.
 			for ( const value of ModelRange.createIn( data.item ) ) {
-				consumable.consume( value.item, evt.name );
+				conversionApi.consumable.consume( value.item, evt.name );
 			}
 
 			viewElement.getCustomProperty( 'addHighlight' )( viewElement, descriptor, conversionApi.writer );

+ 6 - 6
packages/ckeditor5-engine/src/conversion/downcast-selection-converters.js

@@ -21,14 +21,14 @@
  * @returns {Function} Selection converter.
  */
 export function convertRangeSelection() {
-	return ( evt, data, consumable, conversionApi ) => {
+	return ( evt, data, conversionApi ) => {
 		const selection = data.selection;
 
 		if ( selection.isCollapsed ) {
 			return;
 		}
 
-		if ( !consumable.consume( selection, 'selection' ) ) {
+		if ( !conversionApi.consumable.consume( selection, 'selection' ) ) {
 			return;
 		}
 
@@ -66,14 +66,14 @@ export function convertRangeSelection() {
  * @returns {Function} Selection converter.
  */
 export function convertCollapsedSelection() {
-	return ( evt, data, consumable, conversionApi ) => {
+	return ( evt, data, conversionApi ) => {
 		const selection = data.selection;
 
 		if ( !selection.isCollapsed ) {
 			return;
 		}
 
-		if ( !consumable.consume( selection, 'selection' ) ) {
+		if ( !conversionApi.consumable.consume( selection, 'selection' ) ) {
 			return;
 		}
 
@@ -111,7 +111,7 @@ export function convertCollapsedSelection() {
  * @returns {Function} Selection converter.
  */
 export function clearAttributes() {
-	return ( evt, data, consumable, conversionApi ) => {
+	return ( evt, data, conversionApi ) => {
 		const viewWriter = conversionApi.writer;
 		const viewSelection = viewWriter.document.selection;
 
@@ -133,5 +133,5 @@ export function clearAttributes() {
  * {@link module:engine/model/selection~Selection model selection} conversion.
  */
 export function clearFakeSelection() {
-	return ( evt, data, consumable, conversionApi ) => conversionApi.writer.setFakeSelection( false );
+	return ( evt, data, conversionApi ) => conversionApi.writer.setFakeSelection( false );
 }

+ 42 - 19
packages/ckeditor5-engine/src/conversion/downcastdispatcher.js

@@ -79,9 +79,9 @@ import extend from '@ckeditor/ckeditor5-utils/src/lib/lodash/extend';
  * Example of a custom converter for `DowncastDispatcher`:
  *
  *		// We will convert inserting "paragraph" model element into the model.
- *		downcastDispatcher.on( 'insert:paragraph', ( evt, data, consumable, conversionApi ) => {
+ *		downcastDispatcher.on( 'insert:paragraph', ( evt, data, conversionApi ) => {
  *			// Remember to check whether the change has not been consumed yet and consume it.
- *			if ( consumable.consume( data.item, 'insert' ) ) {
+ *			if ( conversionApi.consumable.consume( data.item, 'insert' ) ) {
  *				return;
  *			}
  *
@@ -180,6 +180,8 @@ export default class DowncastDispatcher {
 				this._testAndFire( `attribute:${ key }`, data, consumable );
 			}
 		}
+
+		this._clearConversionApi();
 	}
 
 	/**
@@ -194,6 +196,8 @@ export default class DowncastDispatcher {
 		this.conversionApi.writer = writer;
 
 		this.fire( 'remove:' + name, { position, length }, this.conversionApi );
+
+		this._clearConversionApi();
 	}
 
 	/**
@@ -228,6 +232,8 @@ export default class DowncastDispatcher {
 
 			this._testAndFire( `attribute:${ key }`, data, consumable );
 		}
+
+		this._clearConversionApi();
 	}
 
 	/**
@@ -239,16 +245,16 @@ export default class DowncastDispatcher {
 	 * @fires addMarker
 	 * @fires attribute
 	 * @param {module:engine/model/selection~Selection} selection Selection to convert.
-	 * @param {module:engine/model/selection~Selection} Array<module:engine/model/markercollection~Marker> markers
-	 * Array of markers containing model markers.
+	 * @param {Array.<module:engine/model/markercollection~Marker>} markers Array of markers containing model markers.
 	 * @param {module:engine/view/writer~Writer} writer View writer that should be used to modify view document.
 	 */
 	convertSelection( selection, markers, writer ) {
-		this.conversionApi.writer = writer;
 		const markersAtSelection = Array.from( markers.getMarkersAtPosition( selection.getFirstPosition() ) );
-		const consumable = this._createSelectionConsumable( selection, markersAtSelection );
 
-		this.fire( 'selection', { selection }, consumable, this.conversionApi );
+		this.conversionApi.writer = writer;
+		this.conversionApi.consumable = this._createSelectionConsumable( selection, markersAtSelection );
+
+		this.fire( 'selection', { selection }, this.conversionApi );
 
 		if ( !selection.isCollapsed ) {
 			return;
@@ -267,8 +273,8 @@ export default class DowncastDispatcher {
 				markerRange
 			};
 
-			if ( consumable.test( selection, 'addMarker:' + marker.name ) ) {
-				this.fire( 'addMarker:' + marker.name, data, consumable, this.conversionApi );
+			if ( this.conversionApi.consumable.test( selection, 'addMarker:' + marker.name ) ) {
+				this.fire( 'addMarker:' + marker.name, data, this.conversionApi );
 			}
 		}
 
@@ -282,10 +288,12 @@ export default class DowncastDispatcher {
 			};
 
 			// Do not fire event if the attribute has been consumed.
-			if ( consumable.test( selection, 'attribute:' + data.attributeKey ) ) {
-				this.fire( 'attribute:' + data.attributeKey, data, consumable, this.conversionApi );
+			if ( this.conversionApi.consumable.test( selection, 'attribute:' + data.attributeKey ) ) {
+				this.fire( 'attribute:' + data.attributeKey, data, this.conversionApi );
 			}
 		}
+
+		this._clearConversionApi();
 	}
 
 	/**
@@ -313,28 +321,29 @@ export default class DowncastDispatcher {
 			const consumable = new Consumable();
 			consumable.add( markerRange, eventName );
 
-			this.fire( eventName, {
-				markerName,
-				markerRange
-			}, consumable, this.conversionApi );
+			this.conversionApi.consumable = consumable;
+
+			this.fire( eventName, { markerName, markerRange }, this.conversionApi );
 
 			return;
 		}
 
 		// Create consumable for each item in range.
-		const consumable = this._createConsumableForRange( markerRange, eventName );
+		this.conversionApi.consumable = this._createConsumableForRange( markerRange, eventName );
 
 		// Create separate event for each node in the range.
 		for ( const item of markerRange.getItems() ) {
 			// Do not fire event for already consumed items.
-			if ( !consumable.test( item, eventName ) ) {
+			if ( !this.conversionApi.consumable.test( item, eventName ) ) {
 				continue;
 			}
 
 			const data = { item, range: Range.createOn( item ), markerName, markerRange };
 
-			this.fire( eventName, data, consumable, this.conversionApi );
+			this.fire( eventName, data, this.conversionApi );
 		}
+
+		this._clearConversionApi();
 	}
 
 	/**
@@ -354,6 +363,8 @@ export default class DowncastDispatcher {
 		this.conversionApi.writer = writer;
 
 		this.fire( 'removeMarker:' + markerName, { markerName, markerRange }, this.conversionApi );
+
+		this._clearConversionApi();
 	}
 
 	/**
@@ -440,7 +451,19 @@ export default class DowncastDispatcher {
 
 		const name = data.item.name || '$text';
 
-		this.fire( type + ':' + name, data, consumable, this.conversionApi );
+		this.conversionApi.consumable = consumable;
+
+		this.fire( type + ':' + name, data, this.conversionApi );
+	}
+
+	/**
+	 * Clears conversion API object.
+	 *
+	 * @private
+	 */
+	_clearConversionApi() {
+		delete this.conversionApi.writer;
+		delete this.conversionApi.consumable;
 	}
 
 	/**

+ 3 - 3
packages/ckeditor5-engine/src/conversion/modelconsumable.js

@@ -53,9 +53,9 @@ import TextProxy from '../model/textproxy';
  *		//   ├─ <img />
  *		//   └─ <caption>
  *		//       └─ foo
- *		modelConversionDispatcher.on( 'insert:image', ( evt, data, consumable, conversionApi ) => {
+ *		modelConversionDispatcher.on( 'insert:image', ( evt, data, conversionApi ) => {
  *			// First, consume the `image` element.
- *			consumable.consume( data.item, 'insert' );
+ *			conversionApi.consumable.consume( data.item, 'insert' );
  *
  *			// Just create normal image element for the view.
  *			// Maybe it will be "decorated" later.
@@ -69,7 +69,7 @@ import TextProxy from '../model/textproxy';
  *				// `modelCaption` insertion change is consumed from consumable values.
  *				// It will not be converted by other converters, but it's children (probably some text) will be.
  *				// Through mapping, converters for text will know where to insert contents of `modelCaption`.
- *				if ( consumable.consume( modelCaption, 'insert' ) ) {
+ *				if ( conversionApi.consumable.consume( modelCaption, 'insert' ) ) {
  *					const viewCaption = new ViewElement( 'figcaption' );
  *
  *					const viewImageHolder = new ViewElement( 'figure', null, [ viewImage, viewCaption ] );

+ 2 - 2
packages/ckeditor5-engine/src/dev-utils/model.js

@@ -209,7 +209,7 @@ export function stringify( node, selectionOrPositionOrRange = null ) {
 	mapper.bindElements( node.root, viewRoot );
 
 	downcastDispatcher.on( 'insert:$text', insertText() );
-	downcastDispatcher.on( 'attribute', ( evt, data, consumable, conversionApi ) => {
+	downcastDispatcher.on( 'attribute', ( evt, data, conversionApi ) => {
 		if ( data.item instanceof ModelSelection || data.item instanceof DocumentSelection || data.item.is( 'textProxy' ) ) {
 			const converter = wrap( ( modelAttributeValue, viewWriter ) => {
 				return viewWriter.createAttributeElement(
@@ -218,7 +218,7 @@ export function stringify( node, selectionOrPositionOrRange = null ) {
 				);
 			} );
 
-			converter( evt, data, consumable, conversionApi );
+			converter( evt, data, conversionApi );
 		}
 	} );
 	downcastDispatcher.on( 'insert', insertElement( modelItem => {

+ 8 - 8
packages/ckeditor5-engine/tests/conversion/downcast-converters.js

@@ -579,8 +579,8 @@ describe( 'downcast-converters', () => {
 		} );
 
 		it( 'should be possible to override it', () => {
-			dispatcher.on( 'insert:$text', ( evt, data, consumable ) => {
-				consumable.consume( data.item, 'insert' );
+			dispatcher.on( 'insert:$text', ( evt, data, conversionApi ) => {
+				conversionApi.consumable.consume( data.item, 'insert' );
 			}, { priority: 'high' } );
 
 			model.change( writer => {
@@ -675,8 +675,8 @@ describe( 'downcast-converters', () => {
 		it( 'should be possible to override setAttribute', () => {
 			const modelElement = new ModelElement( 'paragraph', { class: 'foo' }, new ModelText( 'foobar' ) );
 
-			dispatcher.on( 'attribute:class', ( evt, data, consumable ) => {
-				consumable.consume( data.item, 'attribute:class' );
+			dispatcher.on( 'attribute:class', ( evt, data, conversionApi ) => {
+				conversionApi.consumable.consume( data.item, 'attribute:class' );
 			}, { priority: 'high' } );
 
 			model.change( writer => {
@@ -861,8 +861,8 @@ describe( 'downcast-converters', () => {
 					( data, viewWriter ) => viewWriter.createUIElement( 'span', { 'class': 'marker' } ) )
 				);
 
-				dispatcher.on( 'addMarker:marker', ( evt, data, consumable ) => {
-					consumable.consume( data.markerRange, 'addMarker:marker' );
+				dispatcher.on( 'addMarker:marker', ( evt, data, conversionApi ) => {
+					conversionApi.consumable.consume( data.markerRange, 'addMarker:marker' );
 				}, { priority: 'high' } );
 
 				model.change( writer => {
@@ -969,8 +969,8 @@ describe( 'downcast-converters', () => {
 				sinon.spy( dispatcher, 'fire' );
 
 				dispatcher.on( 'addMarker:marker', insertUIElement( creator ) );
-				dispatcher.on( 'addMarker:marker', ( evt, data, consumable ) => {
-					consumable.consume( data.item, 'addMarker:marker' );
+				dispatcher.on( 'addMarker:marker', ( evt, data, conversionApi ) => {
+					conversionApi.consumable.consume( data.item, 'addMarker:marker' );
 				}, { priority: 'high' } );
 
 				model.change( writer => {

+ 9 - 9
packages/ckeditor5-engine/tests/conversion/downcast-selection-converters.js

@@ -152,8 +152,8 @@ describe( 'downcast-selection-converters', () => {
 			it( 'consumes consumable values properly', () => {
 				// Add callback that will fire before default ones.
 				// This should prevent default callback doing anything.
-				dispatcher.on( 'selection', ( evt, data, consumable ) => {
-					expect( consumable.consume( data.selection, 'selection' ) ).to.be.true;
+				dispatcher.on( 'selection', ( evt, data, conversionApi ) => {
+					expect( conversionApi.consumable.consume( data.selection, 'selection' ) ).to.be.true;
 				}, { priority: 'high' } );
 
 				// Similar test case as the first in this suite.
@@ -371,12 +371,12 @@ describe( 'downcast-selection-converters', () => {
 			it( 'consumes consumable values properly', () => {
 				// Add callbacks that will fire before default ones.
 				// This should prevent default callbacks doing anything.
-				dispatcher.on( 'selection', ( evt, data, consumable ) => {
-					expect( consumable.consume( data.selection, 'selection' ) ).to.be.true;
+				dispatcher.on( 'selection', ( evt, data, conversionApi ) => {
+					expect( conversionApi.consumable.consume( data.selection, 'selection' ) ).to.be.true;
 				}, { priority: 'high' } );
 
-				dispatcher.on( 'attribute:bold', ( evt, data, consumable ) => {
-					expect( consumable.consume( data.item, 'attribute:bold' ) ).to.be.true;
+				dispatcher.on( 'attribute:bold', ( evt, data, conversionApi ) => {
+					expect( conversionApi.consumable.consume( data.item, 'attribute:bold' ) ).to.be.true;
 				}, { priority: 'high' } );
 
 				// Similar test case as above.
@@ -509,10 +509,10 @@ describe( 'downcast-selection-converters', () => {
 			dispatcher.on( 'insert:td', tableConverter );
 
 			// Special converter for table cells.
-			dispatcher.on( 'selection', ( evt, data, consumable, conversionApi ) => {
+			dispatcher.on( 'selection', ( evt, data, conversionApi ) => {
 				const selection = data.selection;
 
-				if ( !consumable.test( selection, 'selection' ) || selection.isCollapsed ) {
+				if ( !conversionApi.consumable.test( selection, 'selection' ) || selection.isCollapsed ) {
 					return;
 				}
 
@@ -520,7 +520,7 @@ describe( 'downcast-selection-converters', () => {
 					const node = range.start.nodeAfter;
 
 					if ( node == range.end.nodeBefore && node instanceof ModelElement && node.name == 'td' ) {
-						consumable.consume( selection, 'selection' );
+						conversionApi.consumable.consume( selection, 'selection' );
 
 						const viewNode = conversionApi.mapper.toViewElement( node );
 						conversionApi.writer.addClass( 'selected', viewNode );

+ 17 - 17
packages/ckeditor5-engine/tests/conversion/downcastdispatcher.js

@@ -163,7 +163,7 @@ describe( 'DowncastDispatcher', () => {
 			const loggedEvents = [];
 
 			// We will check everything connected with insert event:
-			dispatcher.on( 'insert', ( evt, data, consumable ) => {
+			dispatcher.on( 'insert', ( evt, data, conversionApi ) => {
 				// Check if the item is correct.
 				const itemId = data.item.name ? data.item.name : '$text:' + data.item.data;
 				// Check if the range is correct.
@@ -174,11 +174,11 @@ describe( 'DowncastDispatcher', () => {
 				// Check if the event name is correct.
 				expect( evt.name ).to.equal( 'insert:' + ( data.item.name || '$text' ) );
 				// Check if model consumable is correct.
-				expect( consumable.consume( data.item, 'insert' ) ).to.be.true;
+				expect( conversionApi.consumable.consume( data.item, 'insert' ) ).to.be.true;
 			} );
 
 			// Same here.
-			dispatcher.on( 'attribute', ( evt, data, consumable ) => {
+			dispatcher.on( 'attribute', ( evt, data, conversionApi ) => {
 				const itemId = data.item.name ? data.item.name : '$text:' + data.item.data;
 				const key = data.attributeKey;
 				const value = data.attributeNewValue;
@@ -187,7 +187,7 @@ describe( 'DowncastDispatcher', () => {
 				loggedEvents.push( log );
 
 				expect( evt.name ).to.equal( 'attribute:' + key + ':' + ( data.item.name || '$text' ) );
-				expect( consumable.consume( data.item, 'attribute:' + key ) ).to.be.true;
+				expect( conversionApi.consumable.consume( data.item, 'attribute:' + key ) ).to.be.true;
 			} );
 
 			dispatcher.convertInsert( range );
@@ -214,9 +214,9 @@ describe( 'DowncastDispatcher', () => {
 
 			sinon.spy( dispatcher, 'fire' );
 
-			dispatcher.on( 'insert:image', ( evt, data, consumable ) => {
-				consumable.consume( data.item.getChild( 0 ), 'insert' );
-				consumable.consume( data.item, 'attribute:bold' );
+			dispatcher.on( 'insert:image', ( evt, data, conversionApi ) => {
+				conversionApi.consumable.consume( data.item.getChild( 0 ), 'insert' );
+				conversionApi.consumable.consume( data.item, 'attribute:bold' );
 			} );
 
 			const range = ModelRange.createIn( root );
@@ -278,10 +278,10 @@ describe( 'DowncastDispatcher', () => {
 				writer.setAttribute( 'italic', true, ModelRange.createFromParentsAndOffsets( root, 4, root, 5 ) );
 			} );
 
-			dispatcher.on( 'selection', ( evt, data, consumable ) => {
-				expect( consumable.test( data.selection, 'selection' ) ).to.be.true;
-				expect( consumable.test( data.selection, 'attribute:bold' ) ).to.be.true;
-				expect( consumable.test( data.selection, 'attribute:italic' ) ).to.be.null;
+			dispatcher.on( 'selection', ( evt, data, conversionApi ) => {
+				expect( conversionApi.consumable.test( data.selection, 'selection' ) ).to.be.true;
+				expect( conversionApi.consumable.test( data.selection, 'attribute:bold' ) ).to.be.true;
+				expect( conversionApi.consumable.test( data.selection, 'attribute:italic' ) ).to.be.null;
 			} );
 
 			dispatcher.convertSelection( doc.selection, model.markers, [] );
@@ -331,8 +331,8 @@ describe( 'DowncastDispatcher', () => {
 				writer.setAttribute( 'italic', true, ModelRange.createFromParentsAndOffsets( root, 4, root, 5 ) );
 			} );
 
-			dispatcher.on( 'selection', ( evt, data, consumable ) => {
-				consumable.consume( data.selection, 'attribute:bold' );
+			dispatcher.on( 'selection', ( evt, data, conversionApi ) => {
+				conversionApi.consumable.consume( data.selection, 'attribute:bold' );
 			} );
 
 			sinon.spy( dispatcher, 'fire' );
@@ -423,8 +423,8 @@ describe( 'DowncastDispatcher', () => {
 
 			sinon.spy( dispatcher, 'fire' );
 
-			dispatcher.on( 'addMarker:foo', ( evt, data, consumable ) => {
-				consumable.consume( data.item, 'addMarker:bar' );
+			dispatcher.on( 'addMarker:foo', ( evt, data, conversionApi ) => {
+				conversionApi.consumable.consume( data.item, 'addMarker:bar' );
 			} );
 
 			const markers = Array.from( model.markers.getMarkersAtPosition( doc.selection.getFirstPosition() ) );
@@ -478,10 +478,10 @@ describe( 'DowncastDispatcher', () => {
 
 			const items = [];
 
-			dispatcher.on( 'addMarker:name', ( evt, data, consumable ) => {
+			dispatcher.on( 'addMarker:name', ( evt, data, conversionApi ) => {
 				expect( data.markerName ).to.equal( 'name' );
 				expect( data.markerRange.isEqual( range ) ).to.be.true;
-				expect( consumable.test( data.item, 'addMarker:name' ) );
+				expect( conversionApi.consumable.test( data.item, 'addMarker:name' ) );
 
 				items.push( data.item );
 			} );

+ 1 - 1
packages/ckeditor5-engine/tests/manual/highlight.js

@@ -49,7 +49,7 @@ class FancyWidget extends Plugin {
 
 		conversion.for( 'editingDowncast' ).add( downcastElementToElement( {
 			model: 'fancywidget',
-			view: ( modelItem, consumable, conversionApi ) => {
+			view: ( modelItem, conversionApi ) => {
 				const viewWriter = conversionApi.writer;
 				const widgetElement = viewWriter.createContainerElement( 'figure', { class: 'fancy-widget' } );
 				viewWriter.insert( ViewPosition.createAt( widgetElement ), viewWriter.createText( 'widget' ) );

+ 1 - 1
packages/ckeditor5-engine/tests/manual/nestededitable.js

@@ -58,7 +58,7 @@ class NestedEditable extends Plugin {
 
 		editor.conversion.for( 'downcast' ).add( downcastElementToElement( {
 			model: 'figcaption',
-			view: ( modelItem, consumable, conversionApi ) => {
+			view: ( modelItem, conversionApi ) => {
 				const viewWriter = conversionApi.writer;
 				const element = viewWriter.createEditableElement( 'figcaption', { contenteditable: 'true' } );
 

+ 2 - 2
packages/ckeditor5-engine/tests/manual/tickets/ckeditor5-721/1.js

@@ -43,7 +43,7 @@ ClassicEditor
 		editor.conversion.for( 'downcast' )
 			.add( downcastElementToElement( {
 				model: 'widget',
-				view: ( modelItem, consumable, conversionApi ) => {
+				view: ( modelItem, conversionApi ) => {
 					const writer = conversionApi.writer;
 					const b = writer.createAttributeElement( 'b' );
 					const div = writer.createContainerElement( 'div' );
@@ -55,7 +55,7 @@ ClassicEditor
 			} ) )
 			.add( downcastElementToElement( {
 				model: 'nested',
-				view: ( item, consumable, api ) => api.writer.createEditableElement( 'figcaption', { contenteditable: true } )
+				view: ( item, api ) => api.writer.createEditableElement( 'figcaption', { contenteditable: true } )
 			} ) );
 
 		setData( editor.model,

+ 1 - 1
packages/ckeditor5-engine/tests/view/manual/uielement.js

@@ -45,7 +45,7 @@ class UIElementTestPlugin extends Plugin {
 		const editing = editor.editing;
 
 		// Add some UIElement to each paragraph.
-		editing.downcastDispatcher.on( 'insert:paragraph', ( evt, data, consumable, conversionApi ) => {
+		editing.downcastDispatcher.on( 'insert:paragraph', ( evt, data, conversionApi ) => {
 			const viewP = conversionApi.mapper.toViewElement( data.item );
 			viewP.appendChildren( createEndingUIElement( conversionApi.writer ) );
 		}, { priority: 'lowest' } );