# Differ

class

Calculates the difference between two model states.

Receives operations that are to be applied on the model document. Marks parts of the model document tree which are changed and saves the state of these elements before the change. Then, it compares saved elements with the changed elements, after all changes are applied on the model document. Calculates the diff between saved elements and new ones and returns a change set.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L37)

<a id="properties">

## Properties

<a id="member-isEmpty">

### `isEmpty: boolean` _(readonly)_

Informs whether there are any changes buffered in `Differ`.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L154)

<a id="member-_cachedChanges">

### `_cachedChanges: Array<DifferItem> | null` _(private)_

For efficiency purposes, `Differ` stores the change set returned by the differ after [`getChanges`](#function-getChanges) call. Cache is reset each time a new operation is buffered. If the cache has not been reset, [`getChanges`](#function-getChanges) will return the cached value instead of calculating it again.

This property stores those changes that did not take place in graveyard root.

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

<a id="member-_cachedChangesWithGraveyard">

### `_cachedChangesWithGraveyard: Array<DifferItem> | null` _(private)_

For efficiency purposes, `Differ` stores the change set returned by the differ after the [`getChanges`](#function-getChanges) call. The cache is reset each time a new operation is buffered. If the cache has not been reset, [`getChanges`](#function-getChanges) will return the cached value instead of calculating it again.

This property stores all changes evaluated by `Differ`, including those that took place in the graveyard.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L135)

<a id="member-_changeCount">

### `_changeCount: number` _(private)_

Stores the number of changes that were processed. Used to order the changes chronologically. It is important when changes are sorted.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L117)

<a id="member-_changedMarkers">

### `_changedMarkers: Map<string, object>` _(private)_

A map that stores all changed markers.

The keys of the map are marker names.

The values of the map are objects with the following properties:

* `oldMarkerData`,
* `newMarkerData`.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L104)

<a id="member-_changedRoots">

### `_changedRoots: Map<string, DifferItemRoot>` _(private)_

A map that stores all roots that have been changed.

The keys are the names of the roots while value represents the changes.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L111)

<a id="member-_changesInElement">

### `_changesInElement: Map<ModelElement | ModelDocumentFragment, Array<ChangeItem>>` _(private)_

A map that stores changes that happened in a given element.

The keys of the map are references to the model elements. The values of the map are arrays with changes that were done on this element.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L55)

<a id="member-_elementChildrenSnapshots">

### `_elementChildrenSnapshots: Map<ModelElement | ModelDocumentFragment, Array<DifferSnapshot>>` _(private)_

For each element or document fragment inside which there was a change, it stores a snapshot of the child nodes list (an array of children snapshots that represent the state in the element / fragment before any change has happened).

This complements [`_elementsSnapshots`](#member-_elementsSnapshots).

See also [`DifferSnapshot`](module_engine_model_differ-DifferSnapshot.md).

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L74)

<a id="member-_elementState">

### `_elementState: Map<ModelElement, 'refresh' | 'move' | 'rename'>` _(private)_

Keeps the state for a given element, describing how the element was changed so far. It is used to evaluate the `action` property of diff items returned by [`getChanges`](#function-getChanges).

Possible values, in the order from the lowest priority to the highest priority:

* `'refresh'` - element was refreshed,
* `'rename'` - element was renamed,
* `'move'` - element was moved (or, usually, removed, that is moved to the graveyard).

Element that was refreshed, may change its state to `'rename'` if it was later renamed, or to `'move'` if it was removed. But the element cannot change its state from `'move'` to `'rename'`, or from `'rename'` to `'refresh'`.

Only already existing elements are registered in `_elementState`. If a new element was inserted as a result of a buffered operation, it is not be registered in `_elementState`.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L92)

<a id="member-_elementsSnapshots">

### `_elementsSnapshots: Map<ModelNode, DifferSnapshot>` _(private)_

Stores a snapshot for these model nodes that might have changed.

This complements [`_elementChildrenSnapshots`](#member-_elementChildrenSnapshots).

See also [`DifferSnapshot`](module_engine_model_differ-DifferSnapshot.md).

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L64)

<a id="member-_markerCollection">

### `_markerCollection: MarkerCollection` _(private)_

Reference to the model's marker collection.

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

<a id="member-_refreshedItems">

### `_refreshedItems: Set<ModelItem>` _(private)_

Set of model items that were marked to get refreshed in [`_refreshItem`](#function-_refreshItem).

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L140)

#### Static properties

<a id="static-member-_statesPriority">

### `_statesPriority: Array<string | undefined>` _(private)_

Priority of the [element states](#member-_elementState). States on higher indexes of the array can overwrite states on the lower indexes.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L42)

<a id="methods">

## Methods

<a id="function-constructor">

### `constructor( markerCollection )`

Creates a `Differ` instance.

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

#### Parameters

* `markerCollection: MarkerCollection`

  Model's marker collection.

<a id="function-bufferMarkerChange">

### `bufferMarkerChange( markerName, oldMarkerData, newMarkerData ) → void`

Buffers a marker change.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L360)

#### Parameters

* `markerName: string`

  The name of the marker that changed.

* `oldMarkerData: MarkerData`

  Marker data before the change.

* `newMarkerData: MarkerData`

  Marker data after the change.

#### Returns

* `void`

<a id="function-bufferOperation">

### `bufferOperation( operationToBuffer ) → void`

Buffers the given operation. **An operation has to be buffered before it is executed.**

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L163)

#### Parameters

* `operationToBuffer: Operation`

  An operation to buffer.

#### Returns

* `void`

<a id="function-getChangedMarkers">

### `getChangedMarkers() → Array<object>`

Returns all markers which changed.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L423)

#### Returns

* `Array<object>`

<a id="function-getChangedRoots">

### `getChangedRoots() → Array<DifferItemRoot>`

Returns all roots that have changed (either were attached, or detached, or their attributes changed).

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L679)

#### Returns

* `Array<DifferItemRoot>`

  Diff between the old and the new roots state.

<a id="function-getChanges">

### `getChanges( options = { options.includeChangesInGraveyard? } ) → Array<DifferItem>`

Calculates the diff between the old model tree state (the state before the first buffered operations since the last [`reset`](#function-reset) call) and the new model tree state (actual one). It should be called after all buffered operations are executed.

The diff set is returned as an array of [diff items](module_engine_model_differ-DifferItem.md), each describing a change done on the model. The items are sorted by the position on which the change happened. If a position [is before](module_engine_model_position-ModelPosition.md#function-isBefore) another one, it will be on an earlier index in the diff set.

**Note**: Elements inside inserted element will not have a separate diff item, only the top most element change will be reported.

Because calculating the diff is a costly operation, the result is cached. If no new operation was buffered since the previous [`getChanges`](#function-getChanges) call, the next call will return the cached value.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L498)

#### Parameters

* `options: object`

  Additional options.

  Properties

  * `options.includeChangesInGraveyard?: boolean`

    If set to `true`, also changes that happened in the graveyard root will be returned. By default, changes in the graveyard root are not returned.

  Defaults to `{}`

#### Returns

* `Array<DifferItem>`

  Diff between the old and the new model tree state.

<a id="function-getMarkersToAdd">

### `getMarkersToAdd() → Array<object>`

Returns all markers which should be added as a result of buffered changes.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L408)

#### Returns

* `Array<object>`

  Markers to add. Each array item is an object containing the `name` and `range` properties.

<a id="function-getMarkersToRemove">

### `getMarkersToRemove() → Array<object>`

Returns all markers that should be removed as a result of buffered changes.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L391)

#### Returns

* `Array<object>`

  Markers to remove. Each array item is an object containing the `name` and `range` properties.

<a id="function-getRefreshedItems">

### `getRefreshedItems() → Set<ModelItem>`

Returns a set of model items that were marked to get refreshed.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L701)

#### Returns

* `Set<ModelItem>`

<a id="function-hasDataChanges">

### `hasDataChanges() → boolean`

Checks whether some of the buffered changes affect the editor data.

Types of changes which affect the editor data:

* model structure changes,
* attribute changes,
* a root is added or detached,
* changes of markers which were defined as `affectsData`,
* changes of markers' `affectsData` property.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L452)

#### Returns

* `boolean`

<a id="function-reset">

### `reset() → void`

Resets `Differ`. Removes all buffered changes.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L708)

#### Returns

* `void`

<a id="function-_bufferRootLoad">

### `_bufferRootLoad( root ) → void` _(internal)_

Buffers all the data related to given root like it was all just added to the editor.

Following changes are buffered:

* root is attached,
* all root content is inserted,
* all root attributes are added,
* all markers inside the root are added.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L761)

#### Parameters

* `root: ModelRootElement`

#### Returns

* `void`

<a id="function-_refreshItem">

### `_refreshItem( item ) → void` _(internal)_

Marks the given `item` in differ to be "refreshed". It means that the item will be marked as removed and inserted in the differ changes set, so it will be effectively re-converted when the differ changes are handled by a dispatcher.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L726)

#### Parameters

* `item: ModelItem`

  Item to refresh.

#### Returns

* `void`

<a id="function-_bufferRootAttributeChange">

### `_bufferRootAttributeChange( rootName, key, oldValue, newValue ) → void` _(private)_

Buffers a root attribute change.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L816)

#### Parameters

* `rootName: string`
* `key: string`
* `oldValue: unknown`
* `newValue: unknown`

#### Returns

* `void`

<a id="function-_bufferRootStateChange">

### `_bufferRootStateChange( rootName, isAttached ) → void` _(private)_

Buffers the root state change after the root was attached or detached

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L789)

#### Parameters

* `rootName: string`
* `isAttached: boolean`

#### Returns

* `void`

<a id="function-_getAttributesDiff">

### `_getAttributesDiff( range, oldAttributes, newAttributes ) → Array<DifferItemAttribute & DifferItemInternal>` _(private)_

Returns an array of objects where each one is a single attribute change description.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L1300)

#### Parameters

* `range: ModelRange`

  The range where the change happened.

* `oldAttributes: Map<string, unknown>`

  A map, map iterator or compatible object that contains attributes before the change.

* `newAttributes: Map<string, unknown>`

  A map, map iterator or compatible object that contains attributes after the change.

#### Returns

* `Array<DifferItemAttribute & DifferItemInternal>`

  An array containing one or more diff items.

<a id="function-_getChangesForElement">

### `_getChangesForElement( element ) → Array<ChangeItem>` _(private)_

Gets an array of changes that have already been saved for a given element.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L974)

#### Parameters

* `element: ModelElement | ModelDocumentFragment`

#### Returns

* `Array<ChangeItem>`

<a id="function-_getDiffActionForNode">

### `_getDiffActionForNode( node, diffItemType ) → DifferItemAction` _(private)_

Returns a value for [`action`](module_engine_model_differ-DifferItemAction.md) property for diff items returned by [`getChanges`](#function-getChanges). This method aims to return `'rename'` or `'refresh'` when it should, and `diffItemType` ("default action") in all other cases.

It bases on a few factors:

* for text nodes, the method always returns `diffItemType`,
* for newly inserted element, the method returns `diffItemType`,
* if [element state](#member-_elementState) was not recorded, the method returns `diffItemType`,
* if state was recorded, and it was `'move'` (default action), the method returns `diffItemType`,
* finally, if state was `'refresh'` or `'rename'`, the method returns the state value.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L951)

#### Parameters

* `node: ModelNode`
* `diffItemType: 'insert' | 'remove'`

#### Returns

* `DifferItemAction`

<a id="function-_getInsertDiff">

### `_getInsertDiff( parent, offset, action, elementSnapshot, elementSnapshotBefore? ) → DifferItemInsert & DifferItemInternal` _(private)_

Returns an object with a single insert change description.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L1239)

#### Parameters

* `parent: ModelElement | ModelDocumentFragment`

  The element in which the change happened.

* `offset: number`

  The offset at which change happened.

* `action: DifferItemAction`

  Further specifies what kind of action led to generating this change.

* `elementSnapshot: DifferSnapshot`

  Snapshot of the inserted node after changes.

* `elementSnapshotBefore?: DifferSnapshot`

  Snapshot of the inserted node before changes.

#### Returns

* `DifferItemInsert & DifferItemInternal`

  The diff item.

<a id="function-_getRemoveDiff">

### `_getRemoveDiff( parent, offset, action, elementSnapshot ) → DifferItemRemove & DifferItemInternal` _(private)_

Returns an object with a single remove change description.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L1275)

#### Parameters

* `parent: ModelElement | ModelDocumentFragment`

  The element in which change happened.

* `offset: number`

  The offset at which change happened.

* `action: DifferItemAction`

  Further specifies what kind of action led to generating this change.

* `elementSnapshot: DifferSnapshot`

  The snapshot of the removed node before changes.

#### Returns

* `DifferItemRemove & DifferItemInternal`

  The diff item.

<a id="function-_handleChange">

### `_handleChange( inc, changes ) → void` _(private)_

For a given newly saved change, compares it with a change already done on the element and modifies the incoming change and/or the old change.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L1012)

#### Parameters

* `inc: ChangeItem`

  Incoming (new) change.

* `changes: Array<ChangeItem>`

  An array containing all the changes done on that element.

#### Returns

* `void`

<a id="function-_isInInsertedElement">

### `_isInInsertedElement( element ) → boolean` _(private)_

Checks whether given element or any of its parents is an element that is buffered as an inserted element.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L1356)

#### Parameters

* `element: ModelElement | ModelDocumentFragment`

#### Returns

* `boolean`

<a id="function-_makeSnapshots">

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

Creates and saves a snapshot for all children of the given element.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L991)

#### Parameters

* `element: ModelElement | ModelDocumentFragment`

#### Returns

* `void`

<a id="function-_markAttribute">

### `_markAttribute( item ) → void` _(private)_

Saves and handles an attribute change.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L883)

#### Parameters

* `item: ModelItem`

#### Returns

* `void`

<a id="function-_markChange">

### `_markChange( parent, changeItem ) → void` _(private)_

Saves and handles a model change.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L896)

#### Parameters

* `parent: ModelElement | ModelDocumentFragment`
* `changeItem: ChangeItem`

#### Returns

* `void`

<a id="function-_markInsert">

### `_markInsert( parent, offset, howMany ) → void` _(private)_

Saves and handles an insert change.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L855)

#### Parameters

* `parent: ModelElement | ModelDocumentFragment`
* `offset: number`
* `howMany: number`

#### Returns

* `void`

<a id="function-_markRemove">

### `_markRemove( parent, offset, howMany ) → void` _(private)_

Saves and handles a remove change.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L868)

#### Parameters

* `parent: ModelElement | ModelDocumentFragment`
* `offset: number`
* `howMany: number`

#### Returns

* `void`

<a id="function-_removeAllNestedChanges">

### `_removeAllNestedChanges( parent, offset, howMany ) → void` _(private)_

Removes deeply all buffered changes that are registered in elements from range specified by `parent`, `offset` and `howMany`.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L1381)

#### Parameters

* `parent: ModelElement | ModelDocumentFragment`
* `offset: number`
* `howMany: number`

#### Returns

* `void`

<a id="function-_setElementState">

### `_setElementState( node, state ) → void` _(private)_

Tries to set given state for given item.

This method does simple validation (it sets the state only for model elements, not for text proxy nodes). It also follows state setting rules, that is, `'refresh'` cannot overwrite `'rename'`, and `'rename'` cannot overwrite `'move'`.

[See source](https://github.com/ckeditor/ckeditor5/blob/master/packages/ckeditor5-engine/src/model/differ.ts#L926)

#### Parameters

* `node: ModelItem`
* `state: 'refresh' | 'move' | 'rename'`

#### Returns

* `void`

---

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