# UpcastDispatcher

class

Upcast dispatcher is a central point of the view-to-model conversion, which is a process of converting a given [view document fragment](module_engine_view_documentfragment-ViewDocumentFragment.md) or [view element](module_engine_view_element-ViewElement.md) into a correct model structure.

During the conversion process, the dispatcher fires events for all [view nodes](module_engine_view_node-ViewNode.md) from the converted view document fragment. Special callbacks called "converters" should listen to these events in order to convert the view nodes.

The second parameter of the callback is the `data` object with the following properties:

* `data.viewItem` contains a [view node](module_engine_view_node-ViewNode.md) or a [view document fragment](module_engine_view_documentfragment-ViewDocumentFragment.md) that is converted at the moment and might be handled by the callback.
* `data.modelRange` is used to point to the result of the current conversion (e.g. the element that is being inserted) and is always a [`ModelRange`](module_engine_model_range-ModelRange.md) when the conversion succeeds.
* `data.modelCursor` is a [position](module_engine_model_position-ModelPosition.md) on which the converter should insert the newly created items.

The third parameter of the callback is an instance of [`UpcastConversionApi`](module_engine_conversion_upcastdispatcher-UpcastConversionApi.md) which provides additional tools for converters.

You can read more about conversion in the [Upcast conversion](../framework/deep-dive/conversion/upcast.md) guide.

Examples of event-based converters:

```typescript
// A converter for links (<a>).
editor.data.upcastDispatcher.on( 'element:a', ( evt, data, conversionApi ) => {
	if ( conversionApi.consumable.consume( data.viewItem, { name: true, attributes: [ 'href' ] } ) ) {
		// The <a> element is inline and is represented by an attribute in the model.
		// This is why you need to convert only children.
		const { modelRange } = conversionApi.convertChildren( data.viewItem, data.modelCursor );

		for ( let item of modelRange.getItems() ) {
			if ( conversionApi.schema.checkAttribute( item, 'linkHref' ) ) {
				conversionApi.writer.setAttribute( 'linkHref', data.viewItem.getAttribute( 'href' ), item );
			}
		}
	}
} );

// Convert <p> element's font-size style.
// Note: You should use a low-priority observer in order to ensure that
// it is executed after the element-to-element converter.
editor.data.upcastDispatcher.on( 'element:p', ( evt, data, conversionApi ) => {
	const { consumable, schema, writer } = conversionApi;

	if ( !consumable.consume( data.viewItem, { style: 'font-size' } ) ) {
		return;
	}

	const fontSize = data.viewItem.getStyle( 'font-size' );

	// Do not go for the model element after data.modelCursor because it might happen
	// that a single view element was converted to multiple model elements. Get all of them.
	for ( const item of data.modelRange.getItems( { shallow: true } ) ) {
		if ( schema.checkAttribute( item, 'fontSize' ) ) {
			writer.setAttribute( 'fontSize', fontSize, item );
		}
	}
}, { priority: 'low' } );

// Convert all elements which have no custom converter into a paragraph (autoparagraphing).
editor.data.upcastDispatcher.on( 'element', ( evt, data, conversionApi ) => {
	// Check if an element can be converted.
	if ( !conversionApi.consumable.test( data.viewItem, { name: data.viewItem.name } ) ) {
		// When an element is already consumed by higher priority converters, do nothing.
		return;
	}

	const paragraph = conversionApi.writer.createElement( 'paragraph' );

	// Try to safely insert a paragraph at the model cursor - it will find an allowed parent for the current element.
	if ( !conversionApi.safeInsert( paragraph, data.modelCursor ) ) {
		// When an element was not inserted, it means that you cannot insert a paragraph at this position.
		return;
	}

	// Consume the inserted element.
	conversionApi.consumable.consume( data.viewItem, { name: data.viewItem.name } ) );

	// Convert the children to a paragraph.
	const { modelRange } = conversionApi.convertChildren( data.viewItem,  paragraph ) );

	// Update `modelRange` and `modelCursor` in the `data` as a conversion result.
	conversionApi.updateConversionResult( paragraph, data );
}, { priority: 'low' } );
```

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/conversion/upcastdispatcher.ts#L126)

<a id="properties">

## Properties

<a id="member-conversionApi">

### `conversionApi: UpcastConversionApi`

An interface passed by the dispatcher to the event callbacks.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/conversion/upcastdispatcher.ts#L130)

<a id="member-_cursorParents">

### `_cursorParents: Map<ModelNode, ModelElement | ModelDocumentFragment>` _(private)_

The list of cursor parent elements that were created during splitting.

After the conversion process the list is cleared.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/conversion/upcastdispatcher.ts#L144)

<a id="member-_emptyElementsToKeep">

### `_emptyElementsToKeep: Set<ModelElement>` _(private)_

The list of elements that were created during the splitting but should not get removed on conversion end even if they are empty.

The list is cleared after the conversion process.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/conversion/upcastdispatcher.ts#L158)

<a id="member-_modelCursor">

### `_modelCursor: ModelPosition | null` _(private)_

The position in the temporary structure where the converted content is inserted. The structure reflects the context of the target position where the content will be inserted. This property is built based on the context parameter of the convert method.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/conversion/upcastdispatcher.ts#L151)

<a id="member-_splitParts">

### `_splitParts: Map<ModelElement, Array<ModelElement>>` _(private)_

The list of elements that were created during splitting.

After the conversion process, the list is cleared.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/conversion/upcastdispatcher.ts#L137)

<a id="methods">

## Methods

<a id="function-constructor">

### `constructor( conversionApi )`

Creates an upcast dispatcher that operates using the passed API.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/conversion/upcastdispatcher.ts#L167)

#### Parameters

* `conversionApi: Pick<UpcastConversionApi, 'schema'>`

  Additional properties for an interface that will be passed to events fired by the upcast dispatcher.

#### Related:

* [UpcastConversionApi](module_engine_conversion_upcastdispatcher-UpcastConversionApi.md)

<a id="function-convert">

### `convert( viewElement, writer, context ) → ModelDocumentFragment`

Starts the conversion process. The entry point for the conversion.

**Note:** The default `context` value is `[ '$root' ]`, which only matches the generic root. When the editor uses a custom root [`modelElement`](module_core_editor_editorconfig-RootConfig.md#member-modelElement), pass the target [root element](module_engine_model_rootelement-ModelRootElement.md) (or its configured model element name) explicitly, otherwise the conversion result may be wrong. See the [Custom root elements](../framework/deep-dive/schema.md#custom-root-elements) section of the [Schema deep-dive](../framework/deep-dive/schema.md) guide for more details.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/conversion/upcastdispatcher.ts#L206)

#### Parameters

* `viewElement: ViewElement | ViewDocumentFragment`

  The part of the view to be converted.

* `writer: ModelWriter`

  An instance of the model writer.

* `context: ModelSchemaContextDefinition`

  Elements will be converted according to this context.

  Defaults to `...`

#### Returns

* `ModelDocumentFragment`

  Model data that is the result of the conversion process wrapped in `DocumentFragment`. Converted marker elements will be set as the document fragment's [static markers map](module_engine_model_documentfragment-ModelDocumentFragment.md#member-markers).

#### Fires

* [element](#event-element)
* [text](#event-text)
* [documentFragment](#event-documentFragment)

<a id="function-delegate">

### `delegate( events ) → EmitterMixinDelegateChain` _(inherited)_

Delegates selected events to another [`Emitter`](module_utils_emittermixin-Emitter.md). For instance:

```typescript
emitterA.delegate( 'eventX' ).to( emitterB );
emitterA.delegate( 'eventX', 'eventY' ).to( emitterC );
```

then `eventX` is delegated (fired by) `emitterB` and `emitterC` along with `data`:

```typescript
emitterA.fire( 'eventX', data );
```

and `eventY` is delegated (fired by) `emitterC` along with `data`:

```typescript
emitterA.fire( 'eventY', data );
```

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-utils/src/emittermixin.ts#L539)

#### Parameters

* `events: Array<string>`

  Event names that will be delegated to another emitter.

#### Returns

* `EmitterMixinDelegateChain`

<a id="function-fire">

### `fire( eventOrInfo, args ) → GetEventInfo<TEvent>[ 'return' ]` _(inherited)_

Fires an event, executing all callbacks registered for it.

The first parameter passed to callbacks is an [`EventInfo`](module_utils_eventinfo-EventInfo.md) object, followed by the optional `args` provided in the `fire()` method call.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-utils/src/emittermixin.ts#L512)

#### Type parameters

* `TEvent: extends BaseEvent`

  The type describing the event. See [`BaseEvent`](module_utils_emittermixin-BaseEvent.md).

#### Parameters

* `eventOrInfo: GetNameOrEventInfo<TEvent>`

  The name of the event or `EventInfo` object if event is delegated.

* `args: TEvent[ 'args' ]`

  Additional arguments to be passed to the callbacks.

#### Returns

* `GetEventInfo<TEvent>[ 'return' ]`

  By default the method returns `undefined`. However, the return value can be changed by listeners through modification of the [`evt.return`](module_utils_eventinfo-EventInfo.md#member-return)'s property (the event info is the first param of every callback).

<a id="function-listenTo:BASE_EMITTER">

### `listenTo( emitter, event, callback, options? ) → void` _(inherited)_

Registers a callback function to be executed when an event is fired in a specific (emitter) object.

Events can be grouped in namespaces using `:`. When namespaced event is fired, it additionally fires all callbacks for that namespace.

```typescript
// myEmitter.on( ... ) is a shorthand for myEmitter.listenTo( myEmitter, ... ).
myEmitter.on( 'myGroup', genericCallback );
myEmitter.on( 'myGroup:myEvent', specificCallback );

// genericCallback is fired.
myEmitter.fire( 'myGroup' );
// both genericCallback and specificCallback are fired.
myEmitter.fire( 'myGroup:myEvent' );
// genericCallback is fired even though there are no callbacks for "foo".
myEmitter.fire( 'myGroup:foo' );
```

An event callback can [stop the event](module_utils_eventinfo-EventInfo.md#member-stop) and set the [return value](module_utils_eventinfo-EventInfo.md#member-return) of the [`fire`](#function-fire) method.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-utils/src/emittermixin.ts#L475)

#### Type parameters

* `TEvent: extends BaseEvent`

  The type describing the event. See [`BaseEvent`](module_utils_emittermixin-BaseEvent.md).

#### Parameters

* `emitter: Emitter`

  The object that fires the event.

* `event: TEvent[ 'name' ]`

  The name of the event.

* `callback: GetCallback<TEvent>`

  The function to be called on event.

* `options?: GetCallbackOptions<TEvent>`

  Additional options.

#### Returns

* `void`

<a id="function-off">

### `off( event, callback ) → void` _(inherited)_

Stops executing the callback on the given event. Shorthand for [`this.stopListening( this, event, callback )`](#function-stopListening:BASE_STOP).

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-utils/src/emittermixin.ts#L444)

#### Parameters

* `event: string`

  The name of the event.

* `callback: Function`

  The function to stop being called.

#### Returns

* `void`

<a id="function-on">

### `on( event, callback, options? ) → void` _(inherited)_

Registers a callback function to be executed when an event is fired.

Shorthand for [`this.listenTo( this, event, callback, options )`](#function-listenTo:BASE_EMITTER) (it makes the emitter listen on itself).

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-utils/src/emittermixin.ts#L416)

#### Type parameters

* `TEvent: extends BaseEvent`

  The type descibing the event. See [`BaseEvent`](module_utils_emittermixin-BaseEvent.md).

#### Parameters

* `event: TEvent[ 'name' ]`

  The name of the event.

* `callback: GetCallback<TEvent>`

  The function to be called on event.

* `options?: GetCallbackOptions<TEvent>`

  Additional options.

#### Returns

* `void`

<a id="function-once">

### `once( event, callback, options? ) → void` _(inherited)_

Registers a callback function to be executed on the next time the event is fired only. This is similar to calling [`on`](#function-on) followed by [`off`](#function-off) in the callback.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-utils/src/emittermixin.ts#L431)

#### Type parameters

* `TEvent: extends BaseEvent`

  The type descibing the event. See [`BaseEvent`](module_utils_emittermixin-BaseEvent.md).

#### Parameters

* `event: TEvent[ 'name' ]`

  The name of the event.

* `callback: GetCallback<TEvent>`

  The function to be called on event.

* `options?: GetCallbackOptions<TEvent>`

  Additional options.

#### Returns

* `void`

<a id="function-stopDelegating">

### `stopDelegating( event?, emitter? ) → void` _(inherited)_

Stops delegating events. It can be used at different levels:

* To stop delegating all events.
* To stop delegating a specific event to all emitters.
* To stop delegating a specific event to a specific emitter.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-utils/src/emittermixin.ts#L552)

#### Parameters

* `event?: string`

  The name of the event to stop delegating. If omitted, stops it all delegations.

* `emitter?: Emitter`

  (requires `event`) The object to stop delegating a particular event to. If omitted, stops delegation of `event` to all emitters.

#### Returns

* `void`

<a id="function-stopListening:BASE_STOP">

### `stopListening( emitter?, event?, callback? ) → void` _(inherited)_

Stops listening for events. It can be used at different levels:

* To stop listening to a specific callback.
* To stop listening to a specific event.
* To stop listening to all events fired by a specific object.
* To stop listening to all events fired by all objects.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-utils/src/emittermixin.ts#L497)

#### Parameters

* `emitter?: Emitter`

  The object to stop listening to. If omitted, stops it for all objects.

* `event?: string`

  (Requires the `emitter`) The name of the event to stop listening to. If omitted, stops it for all events from `emitter`.

* `callback?: Function`

  (Requires the `event`) The function to be removed from the call list for the given `event`.

#### Returns

* `void`

<a id="function-_convertChildren">

### `_convertChildren( viewItem, elementOrModelCursor ) → object` _(private)_

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/conversion/upcastdispatcher.ts#L311)

#### Parameters

* `viewItem: ViewElement | ViewDocumentFragment`
* `elementOrModelCursor: ModelElement | ModelPosition`

#### Returns

* `object`

#### Related:

* [UpcastConversionApi#convertChildren](module_engine_conversion_upcastdispatcher-UpcastConversionApi.md#function-convertChildren)

<a id="function-_convertItem">

### `_convertItem( viewItem, modelCursor ) → object` _(private)_

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/conversion/upcastdispatcher.ts#L267)

#### Parameters

* `viewItem: ViewDocumentFragment | ViewItem`
* `modelCursor: ModelPosition`

#### Returns

* `object`

#### Related:

* [UpcastConversionApi#convertItem](module_engine_conversion_upcastdispatcher-UpcastConversionApi.md#function-convertItem)

<a id="function-_getSplitParts">

### `_getSplitParts( element ) → Array<ModelElement>` _(private)_

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/conversion/upcastdispatcher.ts#L485)

#### Parameters

* `element: ModelElement`

#### Returns

* `Array<ModelElement>`

#### Related:

* [UpcastConversionApi#getSplitParts](module_engine_conversion_upcastdispatcher-UpcastConversionApi.md#function-getSplitParts)

<a id="function-_keepEmptyElement">

### `_keepEmptyElement( element ) → void` _(private)_

Mark an element that were created during the splitting to not get removed on conversion end even if it is empty.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/conversion/upcastdispatcher.ts#L500)

#### Parameters

* `element: ModelElement`

#### Returns

* `void`

<a id="function-_registerSplitPair">

### `_registerSplitPair( originalPart, splitPart ) → void` _(private)_

Registers that a `splitPart` element is a split part of the `originalPart` element.

The data set by this method is used by [`_getSplitParts`](#function-_getSplitParts) and [`_removeEmptyElements`](#function-_removeEmptyElements).

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/conversion/upcastdispatcher.ts#L471)

#### Parameters

* `originalPart: ModelElement`
* `splitPart: ModelElement`

#### Returns

* `void`

<a id="function-_removeEmptyElements">

### `_removeEmptyElements() → void` _(private)_

Checks if there are any empty elements created while splitting and removes them.

This method works recursively to re-check empty elements again after at least one element was removed in the initial call, as some elements might have become empty after other empty elements were removed from them.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/conversion/upcastdispatcher.ts#L510)

#### Returns

* `void`

<a id="function-_safeInsert">

### `_safeInsert( modelNode, position ) → boolean` _(private)_

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/conversion/upcastdispatcher.ts#L338)

#### Parameters

* `modelNode: ModelNode`
* `position: ModelPosition`

#### Returns

* `boolean`

#### Related:

* [UpcastConversionApi#safeInsert](module_engine_conversion_upcastdispatcher-UpcastConversionApi.md#function-safeInsert)

<a id="function-_splitToAllowedParent">

### `_splitToAllowedParent( node, modelCursor ) → object | null` _(private)_

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/conversion/upcastdispatcher.ts#L394)

#### Parameters

* `node: ModelNode`
* `modelCursor: ModelPosition`

#### Returns

* `object | null`

#### Related:

* [UpcastConversionApi#splitToAllowedParent](module_engine_conversion_upcastdispatcher-UpcastConversionApi.md#function-splitToAllowedParent)

<a id="function-_updateConversionResult">

### `_updateConversionResult( modelElement, data ) → void` _(private)_

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/conversion/upcastdispatcher.ts#L361)

#### Parameters

* `modelElement: ModelElement`
* `data: UpcastConversionData`

#### Returns

* `void`

#### Related:

* [UpcastConversionApi#updateConversionResult](module_engine_conversion_upcastdispatcher-UpcastConversionApi.md#function-updateConversionResult)

<a id="events">

## Events

<a id="event-documentFragment">

### `documentFragment( eventInfo, data, conversionApi )`

Fired when a [`ViewDocumentFragment`](module_engine_view_documentfragment-ViewDocumentFragment.md) is converted.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/conversion/upcastdispatcher.ts#L607)

#### Parameters

* `eventInfo: EventInfo`

  An object containing information about the fired event.

* `data: UpcastConversionData<TItem>`

* `conversionApi: UpcastConversionApi`

#### Related:

* [UpcastDispatcher#event:element](#event-element)

<a id="event-element">

### `element( eventInfo, data, conversionApi )`

Fired when an [`ViewElement`](module_engine_view_element-ViewElement.md) is converted.

`element` is a namespace event for a class of events. Names of actually called events follow the pattern of `element:<elementName>` where `elementName` is the name of the converted element. This way listeners may listen to a conversion of all or just specific elements.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/conversion/upcastdispatcher.ts#L591)

#### Parameters

* `eventInfo: EventInfo`

  An object containing information about the fired event.

* `data: UpcastConversionData<TItem>`

  The conversion data. Keep in mind that this object is shared by reference between all callbacks that will be called. This means that callbacks can override values if needed, and these values will be available in other callbacks.

* `conversionApi: UpcastConversionApi`

  Conversion utilities to be used by the callback.

<a id="event-text">

### `text( eventInfo, data, conversionApi )`

Fired when a [`ViewText`](module_engine_view_text-ViewText.md) is converted.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/conversion/upcastdispatcher.ts#L599)

#### Parameters

* `eventInfo: EventInfo`

  An object containing information about the fired event.

* `data: UpcastConversionData<TItem>`

* `conversionApi: UpcastConversionApi`

#### Related:

* [UpcastDispatcher#event:element](#event-element)

<a id="event-viewCleanup">

### `viewCleanup( eventInfo, viewItem )`

Fired before the first conversion event, at the beginning of the upcast (view-to-model conversion) process.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/conversion/upcastdispatcher.ts#L542)

#### Parameters

* `eventInfo: EventInfo`

  An object containing information about the fired event.

* `viewItem: ViewElement | ViewDocumentFragment`

  A part of the view to be converted.

---

Full index of the CKEditor 5 API reference: [llms.txt](llms.txt)
