# Mapper

class

Maps elements, positions and markers between the [view](module_engine_view_document-ViewDocument.md) and the [model](module_engine_model_model.md).

The instance of the Mapper used for the editing pipeline is available in [`editor.editing.mapper`](module_engine_controller_editingcontroller-EditingController.md#member-mapper).

Mapper uses bound elements to find corresponding elements and positions, so, to get proper results, all model elements should be [bound](#function-bindElements).

To map the complex model to/from view relations, you may provide custom callbacks for the [modelToViewPosition event](#event-modelToViewPosition) and [viewToModelPosition event](#event-viewToModelPosition) that are fired whenever a position mapping request occurs. Those events are fired by the [toViewPosition](#function-toViewPosition) and [toModelPosition](#function-toModelPosition) methods. `Mapper` adds its own default callbacks with `'lowest'` priority. To override default `Mapper` mapping, add custom callback with higher priority and stop the event.

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

<a id="properties">

## Properties

<a id="member-_cache">

### `_cache: MapperCache` _(private)_

Manages dynamic cache for the `Mapper` to improve the performance.

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

<a id="member-_deferredBindingRemovals">

### `_deferredBindingRemovals: Map<ViewElement, ViewElement | ViewDocumentFragment>` _(private)_

The map of removed view elements with their current root (used for deferred unbinding).

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

<a id="member-_elementToMarkerNames">

### `_elementToMarkerNames: Map<ViewElement, Set<string>>` _(private)_

View element to model marker names mapping.

This is reverse to [`_markerNameToElements`](#member-_markerNameToElements) map.

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

<a id="member-_markerNameToElements">

### `_markerNameToElements: Map<string, Set<ViewElement>>` _(private)_

Model marker name to view elements mapping.

Keys are `String`s while values are `Set`s with [view elements](module_engine_view_element-ViewElement.md). One marker (name) can be mapped to multiple elements.

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

<a id="member-_modelToViewMapping">

### `_modelToViewMapping: WeakMap<ModelElement | ModelDocumentFragment, ViewElement | ViewDocumentFragment>` _(private)_

Model element to view element mapping.

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

<a id="member-_unboundMarkerNames">

### `_unboundMarkerNames: Set<string>` _(private)_

Stores marker names of markers which have changed due to unbinding a view element (so it is assumed that the view element has been removed, moved or renamed).

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

<a id="member-_viewToModelLengthCallbacks">

### `_viewToModelLengthCallbacks: Map<string, ( element: ViewElement ) => number>` _(private)_

A map containing callbacks between view element names and functions evaluating length of view elements in model.

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

<a id="member-_viewToModelMapping">

### `_viewToModelMapping: WeakMap<ViewElement | ViewDocumentFragment, ModelElement | ModelDocumentFragment>` _(private)_

View element to model element mapping.

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

<a id="methods">

## Methods

<a id="function-constructor">

### `constructor()`

Creates an instance of the mapper.

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

<a id="function-bindElementToMarker">

### `bindElementToMarker( element, name ) → void`

Binds the given marker name with the given [view element](module_engine_view_element-ViewElement.md). The element will be added to the current set of elements bound with the given marker name.

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

#### Parameters

* `element: ViewElement`

  Element to bind.

* `name: string`

  Marker name.

#### Returns

* `void`

<a id="function-bindElements">

### `bindElements( modelElement, viewElement ) → void`

Marks model and view elements as corresponding. Corresponding elements can be retrieved by using the [toModelElement](#function-toModelElement:ELEMENT) and [toViewElement](#function-toViewElement:ELEMENT) methods. The information that elements are bound is also used to translate positions.

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

#### Parameters

* `modelElement: ModelElement | ModelDocumentFragment`

  Model element.

* `viewElement: ViewElement | ViewDocumentFragment`

  View element.

#### Returns

* `void`

<a id="function-clearBindings">

### `clearBindings() → void`

Removes all model to view and view to model bindings.

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

#### Returns

* `void`

<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-findMappedViewAncestor">

### `findMappedViewAncestor( viewPosition ) → ViewElement`

For the given `viewPosition`, finds and returns the closest ancestor of this position that has a mapping to the model.

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

#### Parameters

* `viewPosition: ViewPosition`

  Position for which a mapped ancestor should be found.

#### Returns

* `ViewElement`

<a id="function-findPositionIn">

### `findPositionIn( viewContainer, modelOffset ) → ViewPosition`

Finds the position in a view element or view document fragment node (or in its children) with the expected model offset.

If the passed `viewContainer` is bound to model, `Mapper` will use caching mechanism to improve performance.

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

#### Parameters

* `viewContainer: ViewElement | ViewDocumentFragment`

  Tree view element in which we are looking for the position.

* `modelOffset: number`

  Expected offset.

#### Returns

* `ViewPosition`

  Found position.

<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-flushDeferredBindings">

### `flushDeferredBindings() → void`

Unbinds all deferred binding removals of view elements that in the meantime were not re-attached to some root or document fragment.

See: [`unbindViewElement()`](#function-unbindViewElement).

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

#### Returns

* `void`

<a id="function-flushUnboundMarkerNames">

### `flushUnboundMarkerNames() → Array<string>`

Returns all marker names of markers which have changed due to unbinding a view element (so it is assumed that the view element has been removed, moved or renamed) since the last flush. After returning, the marker names list is cleared.

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

#### Returns

* `Array<string>`

<a id="function-getModelLength">

### `getModelLength( viewNode ) → number`

Gets the length of the view element in the model.

The length is calculated as follows:

* if a [length mapping callback](#function-registerViewToModelLength) is provided for the given `viewNode`, it is used to evaluate the model length (`viewNode` is used as first and only parameter passed to the callback),
* length of a [text node](module_engine_view_text-ViewText.md) is equal to the length of its [data](module_engine_view_text-ViewText.md#member-data),
* length of a [ui element](module_engine_view_uielement-ViewUIElement.md) is equal to 0,
* length of a mapped [element](module_engine_view_element-ViewElement.md) is equal to 1,
* length of a non-mapped [element](module_engine_view_element-ViewElement.md) is equal to the length of its children.

Examples:

```
foo                          -> 3 // Text length is equal to its data length.
<p>foo</p>                   -> 1 // Length of an element which is mapped is by default equal to 1.
<b>foo</b>                   -> 3 // Length of an element which is not mapped is a length of its children.
<div><p>x</p><p>y</p></div>  -> 2 // Assuming that <div> is not mapped and <p> are mapped.
```

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

#### Parameters

* `viewNode: ViewNode | ViewDocumentFragment`

  View node.

#### Returns

* `number`

  Length of the node in the tree model.

<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-markerNameToElements">

### `markerNameToElements( name ) → Set<ViewElement> | null`

Gets all view elements bound to the given marker name.

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

#### Parameters

* `name: string`

  Marker name.

#### Returns

* `Set<ViewElement> | null`

  View elements bound with the given marker name or `null` if no elements are bound to the given marker name.

<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-registerViewToModelLength">

### `registerViewToModelLength( viewElementName, lengthCallback ) → void` _(deprecated)_

**This method is deprecated and will be removed in one of the future CKEditor 5 releases.**

**Using this method will turn off `Mapper` caching system and may degrade performance when operating on bigger documents.**

Registers a callback that evaluates the length in the model of a view element with the given name.

The callback is fired with one argument, which is a view element instance. The callback is expected to return a number representing the length of the view element in the model.

```typescript
// List item in view may contain nested list, which have other list items. In model though,
// the lists are represented by flat structure. Because of those differences, length of list view element
// may be greater than one. In the callback it's checked how many nested list items are in evaluated list item.

function getViewListItemLength( element ) {
	let length = 1;

	for ( let child of element.getChildren() ) {
		if ( child.name == 'ul' || child.name == 'ol' ) {
			for ( let item of child.getChildren() ) {
				length += getViewListItemLength( item );
			}
		}
	}

	return length;
}

mapper.registerViewToModelLength( 'li', getViewListItemLength );
```

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

#### Parameters

* `viewElementName: string`

  Name of view element for which callback is registered.

* `lengthCallback: ( element: ViewElement ) => number`

  Function return a length of view element instance in model.

#### 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-toModelElement:DOCUMENT_FRAGMENT">

### `toModelElement( viewDocumentFragment ) → ModelDocumentFragment | undefined`

Gets the corresponding model document fragment.

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

#### Parameters

* `viewDocumentFragment: ViewDocumentFragment`

  View document fragment.

#### Returns

* `ModelDocumentFragment | undefined`

  Corresponding model document fragment or `undefined` if not found.

<a id="function-toModelElement:ELEMENT">

### `toModelElement( viewElement ) → ModelElement | undefined`

Gets the corresponding model element.

**Note:** [`ViewUIElement`](module_engine_view_uielement-ViewUIElement.md) does not have corresponding element in model.

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

#### Parameters

* `viewElement: ViewElement`

  View element.

#### Returns

* `ModelElement | undefined`

  Corresponding model element or `undefined` if not found.

<a id="function-toModelPosition">

### `toModelPosition( viewPosition ) → ModelPosition`

Gets the corresponding model position.

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

#### Parameters

* `viewPosition: ViewPosition`

  View position.

#### Returns

* `ModelPosition`

  Corresponding model position.

#### Fires

* [viewToModelPosition](#event-viewToModelPosition)

<a id="function-toModelRange">

### `toModelRange( viewRange ) → ModelRange`

Gets the corresponding model range.

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

#### Parameters

* `viewRange: ViewRange`

  View range.

#### Returns

* `ModelRange`

  Corresponding model range.

<a id="function-toViewElement:DOCUMENT_FRAGMENT">

### `toViewElement( modelDocumentFragment ) → ViewDocumentFragment | undefined`

Gets the corresponding view document fragment.

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

#### Parameters

* `modelDocumentFragment: ModelDocumentFragment`

  Model document fragment.

#### Returns

* `ViewDocumentFragment | undefined`

  Corresponding view document fragment or `undefined` if not found.

<a id="function-toViewElement:ELEMENT">

### `toViewElement( modelElement ) → ViewElement | undefined`

Gets the corresponding view element.

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

#### Parameters

* `modelElement: ModelElement`

  Model element.

#### Returns

* `ViewElement | undefined`

  Corresponding view element or `undefined` if not found.

<a id="function-toViewPosition">

### `toViewPosition( modelPosition, options = { options.isPhantom? } ) → ViewPosition`

Gets the corresponding view position.

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

#### Parameters

* `modelPosition: ModelPosition`

  Model position.

* `options: object`

  Additional options for position mapping process.

  Properties

  * `options.isPhantom?: boolean`

    Should be set to `true` if the model position to map is pointing to a place in model tree which no longer exists. For example, it could be an end of a removed model range.

  Defaults to `{}`

#### Returns

* `ViewPosition`

  Corresponding view position.

#### Fires

* [modelToViewPosition](#event-modelToViewPosition)

<a id="function-toViewRange">

### `toViewRange( modelRange ) → ViewRange`

Gets the corresponding view range.

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

#### Parameters

* `modelRange: ModelRange`

  Model range.

#### Returns

* `ViewRange`

  Corresponding view range.

<a id="function-unbindElementFromMarkerName">

### `unbindElementFromMarkerName( element, name ) → void`

Unbinds an element from given marker name.

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

#### Parameters

* `element: ViewElement`

  Element to unbind.

* `name: string`

  Marker name.

#### Returns

* `void`

<a id="function-unbindModelElement">

### `unbindModelElement( modelElement ) → void`

Unbinds the given [model element](module_engine_model_element-ModelElement.md) from the map.

**Note:** the model-to-view binding will be removed, if it existed. However, the corresponding view-to-model binding will be removed only if the view element is still bound to the passed `modelElement`.

This behavior lets for re-binding view element to another model element without fear of losing the new binding when the previously bound model element is unbound.

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

#### Parameters

* `modelElement: ModelElement`

  Model element to unbind.

#### Returns

* `void`

<a id="function-unbindViewElement">

### `unbindViewElement( viewElement, options = { options.defer? } ) → void`

Unbinds the given [view element](module_engine_view_element-ViewElement.md) from the map.

**Note:** view-to-model binding will be removed, if it existed. However, corresponding model-to-view binding will be removed only if model element is still bound to the passed `viewElement`.

This behavior allows for re-binding model element to another view element without fear of losing the new binding when the previously bound view element is unbound.

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

#### Parameters

* `viewElement: ViewElement`

  View element to unbind.

* `options: object`

  The options object.

  Properties

  * `options.defer?: boolean`

    Controls whether the binding should be removed immediately or deferred until a [`flushDeferredBindings()`](#function-flushDeferredBindings) call.

  Defaults to `{}`

#### Returns

* `void`

<a id="function-_findPositionStartingFrom">

### `_findPositionStartingFrom( startViewPosition, startModelOffset, targetModelOffset, viewContainer, useCache ) → ViewPosition` _(private)_

Performs most of the logic for `Mapper#findPositionIn()`.

It allows to start looking for the requested model offset from a given starting position, to enable caching. Using the cache, you can set the starting point and skip all the calculations that were already previously done.

This method uses recursion to find positions inside deep structures. Example:

```
<p>fo<b>bar</b>bom</p>  -> target offset: 4
<p>|fo<b>bar</b>bom</p> -> target offset: 4, traversed offset: 0
<p>fo|<b>bar</b>bom</p> -> target offset: 4, traversed offset: 2
<p>fo<b>bar</b>|bom</p> -> target offset: 4, traversed offset: 5 -> we are too far, look recursively in <b>.

<p>fo<b>|bar</b>bom</p> -> target offset: 4, traversed offset: 2
<p>fo<b>bar|</b>bom</p> -> target offset: 4, traversed offset: 5 -> we are too far, look inside "bar".

<p>fo<b>ba|r</b>bom</p> -> target offset: 4, traversed offset: 2 -> position is inside text node at offset 4-2 = 2.
```

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

#### Parameters

* `startViewPosition: ViewPosition`

  View position to start looking from.

* `startModelOffset: number`

  Model offset related to `startViewPosition`.

* `targetModelOffset: number`

  Target model offset to find.

* `viewContainer: ViewElement | ViewDocumentFragment`

  Mapped ancestor of `startViewPosition`. `startModelOffset` is the offset inside a model element or model document fragment mapped to `viewContainer`.

* `useCache: boolean`

  Whether `Mapper` should cache positions while traversing the view tree looking for `expectedModelOffset`.

#### Returns

* `ViewPosition`

  View position mapped to `targetModelOffset`.

<a id="function-_getModelLengthAndCache">

### `_getModelLengthAndCache( viewNode, viewContainer, modelOffset ) → number` _(private)_

Gets the length of the view element in the model and updates cache values after each view item it visits.

See also [`getModelLength`](#function-getModelLength).

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

#### Parameters

* `viewNode: ViewNode`

  View node.

* `viewContainer: ViewElement | ViewDocumentFragment`

  Ancestor of `viewNode` that is a mapped view element.

* `modelOffset: number`

  Model offset at which the `viewNode` starts.

#### Returns

* `number`

  Length of the node in the tree model.

<a id="function-_moveViewPositionToTextNode">

### `_moveViewPositionToTextNode( viewPosition ) → ViewPosition` _(private)_

Because we prefer positions in the text nodes over positions next to text nodes, if the view position was next to a text node, it moves it into the text node instead.

```
<p>[]<b>foo</b></p> -> <p>[]<b>foo</b></p> // do not touch if position is not directly next to text
<p>foo[]<b>foo</b></p> -> <p>foo{}<b>foo</b></p> // move to text node
<p><b>[]foo</b></p> -> <p><b>{}foo</b></p> // move to text node
```

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

#### Parameters

* `viewPosition: ViewPosition`

  Position potentially next to the text node.

#### Returns

* `ViewPosition`

  Position in the text node if possible.

<a id="function-_toModelOffset">

### `_toModelOffset( viewParent, viewOffset, viewBlock ) → number` _(private)_

Calculates model offset based on the view position and the block element.

Example:

```html
<p>foo<b>ba|r</b></p> // _toModelOffset( b, 2, p ) -> 5
```

Is a sum of:

```html
<p>foo|<b>bar</b></p> // _toModelOffset( p, 3, p ) -> 3
<p>foo<b>ba|r</b></p> // _toModelOffset( b, 2, b ) -> 2
```

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

#### Parameters

* `viewParent: ViewElement`

  Position parent.

* `viewOffset: number`

  Position offset.

* `viewBlock: ViewElement | ViewDocumentFragment`

  Block used as a base to calculate offset.

#### Returns

* `number`

  Offset in the model.

<a id="events">

## Events

<a id="event-modelToViewPosition">

### `modelToViewPosition( eventInfo, <anonymous> )`

Fired for each model-to-view position mapping request. The purpose of this event is to enable custom model-to-view position mapping. Callbacks added to this event take [model position](module_engine_model_position-ModelPosition.md) and are expected to calculate the [view position](module_engine_view_position-ViewPosition.md). The calculated view position should be added as a `viewPosition` value in the `data` object that is passed as one of parameters to the event callback.

```typescript
// Assume that "captionedImage" model element is converted to <img> and following <span> elements in view,
// and the model element is bound to <img> element. Force mapping model positions inside "captionedImage" to that
// <span> element.
mapper.on( 'modelToViewPosition', ( evt, data ) => {
	const positionParent = modelPosition.parent;

	if ( positionParent.name == 'captionedImage' ) {
		const viewImg = data.mapper.toViewElement( positionParent );
		const viewCaption = viewImg.nextSibling; // The <span> element.

		data.viewPosition = new ViewPosition( viewCaption, modelPosition.offset );

		// Stop the event if other callbacks should not modify calculated value.
		evt.stop();
	}
} );
```

**Note:** keep in mind that sometimes a "phantom" model position is being converted. A "phantom" model position is a position that points to a nonexistent place in model. Such a position might still be valid for conversion, though (it would point to a correct place in the view when converted). One example of such a situation is when a range is removed from the model, there may be a need to map the range's end (which is no longer a valid model position). To handle such situations, check the `data.isPhantom` flag:

```typescript
// Assume that there is a "customElement" model element and whenever the position is before it,
// we want to move it to the inside of the view element bound to "customElement".
mapper.on( 'modelToViewPosition', ( evt, data ) => {
	if ( data.isPhantom ) {
		return;
	}

	// Below line might crash for phantom position that does not exist in model.
	const sibling = data.modelPosition.nodeBefore;

	// Check if this is the element we are interested in.
	if ( !sibling.is( 'element', 'customElement' ) ) {
		return;
	}

	const viewElement = data.mapper.toViewElement( sibling );

	data.viewPosition = new ViewPosition( sibling, 0 );

	evt.stop();
} );
```

**Note:** the default mapping callback is provided with a `low` priority setting and does not cancel the event, so it is possible to attach a custom callback after a default callback and also use `data.viewPosition` calculated by the default callback (for example to fix it).

**Note:** the default mapping callback will not fire if `data.viewPosition` is already set.

**Note:** these callbacks are called **very often**. For efficiency reasons, it is advised to use them only when position mapping between the given model and view elements is unsolvable by using just elements mapping and default algorithm. Also, the condition that checks if a special case scenario happened should be as simple as possible.

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

#### Parameters

* `eventInfo: EventInfo`

  An object containing information about the fired event.

* `<anonymous>: MapperModelToViewPositionEventData`

<a id="event-viewToModelPosition">

### `viewToModelPosition( eventInfo, <anonymous> )`

Fired for each view-to-model position mapping request. See [event-modelToViewPosition](#event-modelToViewPosition).

```typescript
// See example in `modelToViewPosition` event description.
// This custom mapping will map positions from <span> element next to <img> to the "captionedImage" element.
mapper.on( 'viewToModelPosition', ( evt, data ) => {
	const positionParent = viewPosition.parent;

	if ( positionParent.hasClass( 'image-caption' ) ) {
		const viewImg = positionParent.previousSibling;
		const modelImg = data.mapper.toModelElement( viewImg );

		data.modelPosition = new ModelPosition( modelImg, viewPosition.offset );
		evt.stop();
	}
} );
```

**Note:** the default mapping callback is provided with a `low` priority setting and does not cancel the event, so it is possible to attach a custom callback after the default callback and also use `data.modelPosition` calculated by the default callback (for example to fix it).

**Note:** the default mapping callback will not fire if `data.modelPosition` is already set.

**Note:** these callbacks are called **very often**. For efficiency reasons, it is advised to use them only when position mapping between the given model and view elements is unsolvable by using just elements mapping and default algorithm. Also, the condition that checks if special case scenario happened should be as simple as possible.

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

#### Parameters

* `eventInfo: EventInfo`

  An object containing information about the fired event.

* `<anonymous>: MapperViewToModelPositionEventData`

---

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