ModelLivePosition
ModelLivePosition is a type of Position that updates itself as document is changed through operations. It may be used as a bookmark.
Note: Contrary to ModelPosition, ModelLivePosition works only in roots that are ModelRootElement. If ModelDocumentFragment is passed, error will be thrown.
Note: Be very careful when dealing with ModelLivePosition. Each ModelLivePosition instance bind events that might have to be unbound. Use detach whenever you don't need ModelLivePosition anymore.
Properties
index : numberreadonlyinheritedmodule:engine/model/liveposition~ModelLivePosition#indexisAtEnd : booleanreadonlyinheritedmodule:engine/model/liveposition~ModelLivePosition#isAtEndIs
trueif position is at the end of its parent,falseotherwise.isAtStart : booleanreadonlyinheritedmodule:engine/model/liveposition~ModelLivePosition#isAtStartIs
trueif position is at the beginning of its parent,falseotherwise.module:engine/model/liveposition~ModelLivePosition#nodeAfterNode directly after this position. Returns
nullif this position is at the end of its parent, or if it is in a text node.nodeBefore : null | ModelNodereadonlyinheritedmodule:engine/model/liveposition~ModelLivePosition#nodeBeforeNode directly before this position. Returns
nullif this position is at the start of its parent, or if it is in a text node.offset : numberinheritedmodule:engine/model/liveposition~ModelLivePosition#offsetparent : ModelElement | ModelDocumentFragmentreadonlyinheritedmodule:engine/model/liveposition~ModelLivePosition#parentParent element of this position.
Keep in mind that
parentvalue is calculated when the property is accessed. If position path leads to a non-existing element,parentproperty will throw error.Also it is a good idea to cache
parentproperty if it is used frequently in an algorithm (i.e. in a long loop).path : readonly Array<number>readonlyinheritedmodule:engine/model/liveposition~ModelLivePosition#pathPosition of the node in the tree. Path contains offsets, not indexes.
Position can be placed before, after or in a node if that node has
offsetSizegreater than1. Items in position path are starting offsets of position ancestors, starting from direct root children, down to the position offset in it's parent.ROOT |- P before: [ 0 ] after: [ 1 ] |- UL before: [ 1 ] after: [ 2 ] |- LI before: [ 1, 0 ] after: [ 1, 1 ] | |- foo before: [ 1, 0, 0 ] after: [ 1, 0, 3 ] |- LI before: [ 1, 1 ] after: [ 1, 2 ] |- bar before: [ 1, 1, 0 ] after: [ 1, 1, 3 ]Copy codefooandbarare representing text nodes. Since text nodes has offset size greater than1you can place position offset between their start and end:ROOT |- P |- UL |- LI | |- f^o|o ^ has path: [ 1, 0, 1 ] | has path: [ 1, 0, 2 ] |- LI |- b^a|r ^ has path: [ 1, 1, 1 ] | has path: [ 1, 1, 2 ]Copy coderoot : ModelRootElementreadonlymodule:engine/model/liveposition~ModelLivePosition#rootRoot of the position path.
stickiness : ModelPositionStickinessinheritedmodule:engine/model/liveposition~ModelLivePosition#stickinessPosition stickiness. See
ModelPositionStickiness.module:engine/model/liveposition~ModelLivePosition#textNodeReturns text node instance in which this position is placed or
nullif this position is not in a text node.
Static properties
_createAfter : ( item: ModelDocumentFragment | ModelItem, stickiness: ModelPositionStickiness ) => ModelLivePositioninternalreadonlystaticmodule:engine/model/liveposition~ModelLivePosition._createAfter_createAt : ( itemOrPosition: ModelDocumentFragment | ModelPosition | ModelItem, offset: ModelPositionOffset, stickiness: ModelPositionStickiness ) => ModelLivePositioninternalreadonlystaticmodule:engine/model/liveposition~ModelLivePosition._createAt_createBefore : ( item: ModelDocumentFragment | ModelItem, stickiness: ModelPositionStickiness ) => ModelLivePositioninternalreadonlystaticmodule:engine/model/liveposition~ModelLivePosition._createBefore
Methods
constructor( root, path, stickiness )module:engine/model/liveposition~ModelLivePosition#constructorCreates a live position.
Parameters
root : ModelRootElementpath : Array<number>stickiness : ModelPositionStickinessDefaults to
'toNone'
Related:
clone() → thisinheritedmodule:engine/model/liveposition~ModelLivePosition#clonecompareWith( otherPosition ) → ModelPositionRelationinheritedmodule:engine/model/liveposition~ModelLivePosition#compareWithChecks whether this position is before or after given position.
This method is safe to use it on non-existing positions (for example during operational transformation).
Parameters
otherPosition : ModelPosition
Returns
delegate( events ) → EmitterMixinDelegateChaininheritedmodule:engine/model/liveposition~ModelLivePosition#delegateDelegates selected events to another
Emitter. For instance:emitterA.delegate( 'eventX' ).to( emitterB ); emitterA.delegate( 'eventX', 'eventY' ).to( emitterC );Copy codethen
eventXis delegated (fired by)emitterBandemitterCalong withdata:emitterA.fire( 'eventX', data );Copy codeand
eventYis delegated (fired by)emitterCalong withdata:emitterA.fire( 'eventY', data );Copy codeParameters
events : Array<string>Event names that will be delegated to another emitter.
Returns
detach() → voidmodule:engine/model/liveposition~ModelLivePosition#detachUnbinds all events previously bound by
ModelLivePosition. Use it whenever you don't needModelLivePositioninstance anymore (i.e. when leaving scope in which it was declared or before re-assigning variable that was referring to it).Returns
void
findAncestor( parentName ) → null | ModelElementinheritedmodule:engine/model/liveposition~ModelLivePosition#findAncestorReturns the parent element of the given name. Returns null if the position is not inside the desired parent.
Parameters
parentName : stringThe name of the parent element to find.
Returns
null | ModelElement
fire( eventOrInfo, args ) → GetEventInfo<TEvent>[ 'return' ]inheritedmodule:engine/model/liveposition~ModelLivePosition#fireFires an event, executing all callbacks registered for it.
The first parameter passed to callbacks is an
EventInfoobject, followed by the optionalargsprovided in thefire()method call.Type parameters
Parameters
eventOrInfo : GetNameOrEventInfo<TEvent>The name of the event or
EventInfoobject 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 theevt.return's property (the event info is the first param of every callback).
getAncestors() → Array<ModelElement | ModelDocumentFragment>inheritedmodule:engine/model/liveposition~ModelLivePosition#getAncestorsReturns ancestors array of this position, that is this position's parent and its ancestors.
Returns
Array<ModelElement | ModelDocumentFragment>Array with ancestors.
getCommonAncestor( position ) → null | ModelElement | ModelDocumentFragmentinheritedmodule:engine/model/liveposition~ModelLivePosition#getCommonAncestorReturns an
ModelElementorModelDocumentFragmentwhich is a common ancestor of both positions. The roots of these two positions must be identical.Parameters
position : ModelPositionThe second position.
Returns
null | ModelElement | ModelDocumentFragment
getCommonPath( position ) → Array<number>inheritedmodule:engine/model/liveposition~ModelLivePosition#getCommonPathReturns the slice of two position paths which is identical. The roots of these two paths must be identical.
This method is safe to use it on non-existing positions (for example during operational transformation).
Parameters
position : ModelPositionThe second position.
Returns
Array<number>The common path.
getLastMatchingPosition( skip, options ) → ModelPositioninheritedmodule:engine/model/liveposition~ModelLivePosition#getLastMatchingPositionGets the farthest position which matches the callback using TreeWalker.
For example:
getLastMatchingPosition( value => value.type == 'text' ); // <paragraph>[]foo</paragraph> -> <paragraph>foo[]</paragraph> getLastMatchingPosition( value => value.type == 'text', { direction: 'backward' } ); // <paragraph>foo[]</paragraph> -> <paragraph>[]foo</paragraph> getLastMatchingPosition( value => false ); // Do not move the position.Copy codeParameters
skip : ( value: ModelTreeWalkerValue ) => booleanCallback function. Gets
ModelTreeWalkerValueand should returntrueif the value should be skipped orfalseif not.options : ModelTreeWalkerOptionsObject with configuration options. See
ModelTreeWalker.Defaults to
{}
Returns
ModelPositionThe position after the last item which matches the
skipcallback test.
getParentPath() → Array<number>inheritedmodule:engine/model/liveposition~ModelLivePosition#getParentPathReturns a path to this position's parent. Parent path is equal to position path but without the last item.
This method is safe to use it on non-existing positions (for example during operational transformation).
Returns
Array<number>Path to the parent.
getShiftedBy( shift ) → ModelPositioninheritedmodule:engine/model/liveposition~ModelLivePosition#getShiftedByReturns a new instance of
Position, that has same parent but it's offset is shifted byshiftvalue (can be a negative value).This method is safe to use it on non-existing positions (for example during operational transformation).
Parameters
shift : numberOffset shift. Can be a negative value.
Returns
ModelPositionShifted position.
getTransformedByOperation( operation ) → ModelPositioninheritedmodule:engine/model/liveposition~ModelLivePosition#getTransformedByOperationReturns a copy of this position that is transformed by given
operation.The new position's parameters are updated accordingly to the effect of the
operation.For example, if
nnodes are inserted before the position, the returned positionoffsetwill be increased byn. If the position was in a merged element, it will be accordingly moved to the new element, etc.This method is safe to use it on non-existing positions (for example during operational transformation).
Parameters
operation : OperationOperation to transform by.
Returns
ModelPositionTransformed position.
hasSameParentAs( position ) → booleaninheritedmodule:engine/model/liveposition~ModelLivePosition#hasSameParentAsChecks if two positions are in the same parent.
This method is safe to use it on non-existing positions (for example during operational transformation).
Parameters
position : ModelPositionPosition to compare with.
Returns
booleantrueif positions have the same parent,falseotherwise.
is( type ) → this is ModelElement | ModelRootElementinheritedmodule:engine/model/liveposition~ModelLivePosition#is:ELEMENTChecks whether the object is of type
ModelElementor its subclass.element.is( 'element' ); // -> true element.is( 'node' ); // -> true element.is( 'model:element' ); // -> true element.is( 'model:node' ); // -> true element.is( 'view:element' ); // -> false element.is( 'documentSelection' ); // -> falseCopy codeAssuming that the object being checked is an element, you can also check its name:
element.is( 'element', 'imageBlock' ); // -> true if this is an <imageBlock> element text.is( 'element', 'imageBlock' ); -> falseCopy codeParameters
type : 'element' | 'model:element'
Returns
this is ModelElement | ModelRootElement
module:engine/model/liveposition~ModelLivePosition#is:TEXTChecks whether the object is of type
ModelText.text.is( '$text' ); // -> true text.is( 'node' ); // -> true text.is( 'model:$text' ); // -> true text.is( 'model:node' ); // -> true text.is( 'view:$text' ); // -> false text.is( 'documentSelection' ); // -> falseCopy codeNote: Until version 20.0.0 this method wasn't accepting
'$text'type. The legacy'text'type is still accepted for backward compatibility.Parameters
type : '$text' | 'model:$text'
Returns
this is ModelText
is( type ) → this is ModelRootElementinheritedmodule:engine/model/liveposition~ModelLivePosition#is:ROOT_ELEMENTChecks whether the object is of type
ModelRootElement.rootElement.is( 'rootElement' ); // -> true rootElement.is( 'element' ); // -> true rootElement.is( 'node' ); // -> true rootElement.is( 'model:rootElement' ); // -> true rootElement.is( 'model:element' ); // -> true rootElement.is( 'model:node' ); // -> true rootElement.is( 'view:element' ); // -> false rootElement.is( 'documentFragment' ); // -> falseCopy codeAssuming that the object being checked is an element, you can also check its name:
rootElement.is( 'rootElement', '$root' ); // -> same as aboveCopy codeParameters
type : 'rootElement' | 'model:rootElement'
Returns
this is ModelRootElement
is( type ) → this is ModelLiveRangeinheritedmodule:engine/model/liveposition~ModelLivePosition#is:LIVE_RANGEChecks whether the object is of type
ModelLiveRange.liveRange.is( 'range' ); // -> true liveRange.is( 'model:range' ); // -> true liveRange.is( 'liveRange' ); // -> true liveRange.is( 'model:liveRange' ); // -> true liveRange.is( 'view:range' ); // -> false liveRange.is( 'documentSelection' ); // -> falseCopy codeParameters
type : 'liveRange' | 'model:liveRange'
Returns
this is ModelLiveRange
is( type ) → this is ModelRange | ModelLiveRangeinheritedmodule:engine/model/liveposition~ModelLivePosition#is:RANGEChecks whether the object is of type
ModelRangeor its subclass.range.is( 'range' ); // -> true range.is( 'model:range' ); // -> true range.is( 'view:range' ); // -> false range.is( 'documentSelection' ); // -> falseCopy codeParameters
type : 'range' | 'model:range'
Returns
this is ModelRange | ModelLiveRange
is( type ) → this is ModelLivePositioninheritedmodule:engine/model/liveposition~ModelLivePosition#is:LIVE_POSITIONChecks whether the object is of type
ModelLivePosition.livePosition.is( 'position' ); // -> true livePosition.is( 'model:position' ); // -> true livePosition.is( 'liveposition' ); // -> true livePosition.is( 'model:livePosition' ); // -> true livePosition.is( 'view:position' ); // -> false livePosition.is( 'documentSelection' ); // -> falseCopy codeParameters
type : 'livePosition' | 'model:livePosition'
Returns
this is ModelLivePosition
is( type ) → this is ModelPosition | ModelLivePositioninheritedmodule:engine/model/liveposition~ModelLivePosition#is:POSITIONChecks whether the object is of type
ModelPositionor its subclass.position.is( 'position' ); // -> true position.is( 'model:position' ); // -> true position.is( 'view:position' ); // -> false position.is( 'documentSelection' ); // -> falseCopy codeParameters
type : 'position' | 'model:position'
Returns
this is ModelPosition | ModelLivePosition
is( type ) → this is ModelSelection | ModelDocumentSelectioninheritedmodule:engine/model/liveposition~ModelLivePosition#is:SELECTIONChecks whether the object is of type
ModelSelectionorModelDocumentSelection.selection.is( 'selection' ); // -> true selection.is( 'model:selection' ); // -> true selection.is( 'view:selection' ); // -> false selection.is( 'range' ); // -> falseCopy codeParameters
type : 'selection' | 'model:selection'
Returns
this is ModelSelection | ModelDocumentSelection
is( type, name ) → booleaninheritedmodule:engine/model/liveposition~ModelLivePosition#is:ELEMENT_NAMEChecks whether the object is of type
ModelElementor its subclass and has the specifiedname.element.is( 'element', 'imageBlock' ); // -> true if this is an <imageBlock> element text.is( 'element', 'imageBlock' ); -> falseCopy codeType parameters
N : extends string
Parameters
type : 'element' | 'model:element'name : N
Returns
boolean
is( type, name ) → booleaninheritedmodule:engine/model/liveposition~ModelLivePosition#is:ROOT_ELEMENT_NAMEChecks whether the object is of type
ModelRootElementand has the specifiedname.rootElement.is( 'rootElement', '$root' );Copy codeType parameters
N : extends string
Parameters
type : 'rootElement' | 'model:rootElement'name : N
Returns
boolean
is( type ) → this is ModelTextProxyinheritedmodule:engine/model/liveposition~ModelLivePosition#is:TEXT_PROXYChecks whether the object is of type
ModelTextProxy.textProxy.is( '$textProxy' ); // -> true textProxy.is( 'model:$textProxy' ); // -> true textProxy.is( 'view:$textProxy' ); // -> false textProxy.is( 'range' ); // -> falseCopy codeNote: Until version 20.0.0 this method wasn't accepting
'$textProxy'type. The legacy'textProxt'type is still accepted for backward compatibility.Parameters
type : '$textProxy' | 'model:$textProxy'
Returns
this is ModelTextProxy
module:engine/model/liveposition~ModelLivePosition#is:MARKERis( type ) → this is ModelDocumentSelectioninheritedmodule:engine/model/liveposition~ModelLivePosition#is:DOCUMENT_SELECTIONChecks whether the object is of type
ModelDocumentSelection.selection.is( 'selection' ); // -> true selection.is( 'documentSelection' ); // -> true selection.is( 'model:selection' ); // -> true selection.is( 'model:documentSelection' ); // -> true selection.is( 'view:selection' ); // -> false selection.is( 'element' ); // -> false selection.is( 'node' ); // -> falseCopy codeParameters
type : 'documentSelection' | 'model:documentSelection'
Returns
this is ModelDocumentSelection
is( type ) → this is ModelDocumentFragmentinheritedmodule:engine/model/liveposition~ModelLivePosition#is:DOCUMENT_FRAGMENTChecks whether the object is of type
ModelDocumentFragment.docFrag.is( 'documentFragment' ); // -> true docFrag.is( 'model:documentFragment' ); // -> true docFrag.is( 'view:documentFragment' ); // -> false docFrag.is( 'element' ); // -> false docFrag.is( 'node' ); // -> falseCopy codeParameters
type : 'documentFragment' | 'model:documentFragment'
Returns
this is ModelDocumentFragment
is( type ) → this is ModelNode | ModelText | ModelElement | ModelRootElementinheritedmodule:engine/model/liveposition~ModelLivePosition#is:NODEChecks whether the object is of type
ModelNodeor its subclass.This method is useful when processing model objects that are of unknown type. For example, a function may return a
ModelDocumentFragmentor aModelNodethat can be either a text node or an element. This method can be used to check what kind of object is returned.someObject.is( 'element' ); // -> true if this is an element someObject.is( 'node' ); // -> true if this is a node (a text node or an element) someObject.is( 'documentFragment' ); // -> true if this is a document fragmentCopy codeSince this method is also available on a range of view objects, you can prefix the type of the object with
model:orview:to check, for example, if this is the model's or view's element:modelElement.is( 'model:element' ); // -> true modelElement.is( 'view:element' ); // -> falseCopy codeBy using this method it is also possible to check a name of an element:
imageElement.is( 'element', 'imageBlock' ); // -> true imageElement.is( 'element', 'imageBlock' ); // -> same as above imageElement.is( 'model:element', 'imageBlock' ); // -> same as above, but more preciseCopy codeParameters
type : 'node' | 'model:node'
Returns
this is ModelNode | ModelText | ModelElement | ModelRootElement
isAfter( otherPosition ) → booleaninheritedmodule:engine/model/liveposition~ModelLivePosition#isAfterChecks whether this position is after given position.
This method is safe to use it on non-existing positions (for example during operational transformation).
Parameters
otherPosition : ModelPositionPosition to compare with.
Returns
booleanTrue if this position is after given position.
Related:
isBefore( otherPosition ) → booleaninheritedmodule:engine/model/liveposition~ModelLivePosition#isBeforeChecks whether this position is before given position.
Note: watch out when using negation of the value returned by this method, because the negation will also be
trueif positions are in different roots and you might not expect this. You should probably usea.isAfter( b ) || a.isEqual( b )or!a.isBefore( p ) && a.root == b.rootin most scenarios. If your condition uses multipleisAfterandisBeforechecks, build them so they do not use negated values, i.e.:if ( a.isBefore( b ) && c.isAfter( d ) ) { // do A. } else { // do B. }Copy codeor, if you have only one if-branch:
if ( !( a.isBefore( b ) && c.isAfter( d ) ) { // do B. }Copy coderather than:
if ( !a.isBefore( b ) || && !c.isAfter( d ) ) { // do B. } else { // do A. }Copy codeThis method is safe to use it on non-existing positions (for example during operational transformation).
Parameters
otherPosition : ModelPositionPosition to compare with.
Returns
booleanTrue if this position is before given position.
isEqual( otherPosition ) → booleaninheritedmodule:engine/model/liveposition~ModelLivePosition#isEqualChecks whether this position is equal to given position.
This method is safe to use it on non-existing positions (for example during operational transformation).
Parameters
otherPosition : ModelPositionPosition to compare with.
Returns
booleanTrue if positions are same.
isTouching( otherPosition ) → booleaninheritedmodule:engine/model/liveposition~ModelLivePosition#isTouchingChecks whether this position is touching given position. Positions touch when there are no text nodes or empty nodes in a range between them. Technically, those positions are not equal but in many cases they are very similar or even indistinguishable.
Parameters
otherPosition : ModelPositionPosition to compare with.
Returns
booleanTrue if positions touch.
isValid() → booleaninheritedmodule:engine/model/liveposition~ModelLivePosition#isValidChecks whether the position is valid in current model tree, that is whether it points to an existing place in the model.
Returns
boolean
listenTo( emitter, event, callback, [ options ] ) → voidinheritedmodule:engine/model/liveposition~ModelLivePosition#listenTo:BASE_EMITTERRegisters 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.// 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' );Copy codeAn event callback can stop the event and set the return value of the
firemethod.Type parameters
Parameters
emitter : EmitterThe 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
off( event, callback ) → voidinheritedmodule:engine/model/liveposition~ModelLivePosition#offStops executing the callback on the given event. Shorthand for
this.stopListening( this, event, callback ).Parameters
event : stringThe name of the event.
callback : FunctionThe function to stop being called.
Returns
void
on( event, callback, [ options ] ) → voidinheritedmodule:engine/model/liveposition~ModelLivePosition#onRegisters a callback function to be executed when an event is fired.
Shorthand for
this.listenTo( this, event, callback, options )(it makes the emitter listen on itself).Type parameters
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
once( event, callback, [ options ] ) → voidinheritedmodule:engine/model/liveposition~ModelLivePosition#onceRegisters a callback function to be executed on the next time the event is fired only. This is similar to calling
onfollowed byoffin the callback.Type parameters
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
stopDelegating( [ event ], [ emitter ] ) → voidinheritedmodule:engine/model/liveposition~ModelLivePosition#stopDelegatingStops 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.
Parameters
[ event ] : stringThe 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 ofeventto all emitters.
Returns
void
stopListening( [ emitter ], [ event ], [ callback ] ) → voidinheritedmodule:engine/model/liveposition~ModelLivePosition#stopListening:BASE_STOPStops 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.
Parameters
[ emitter ] : EmitterThe 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 fromemitter.[ callback ] : Function(Requires the
event) The function to be removed from the call list for the givenevent.
Returns
void
toJSON() → unknowninheritedmodule:engine/model/liveposition~ModelLivePosition#toJSONmodule:engine/model/liveposition~ModelLivePosition#toPositionCreates a position instance, which is equal to this live position.
Returns
_getCombined( source, target ) → ModelPositioninternalinheritedmodule:engine/model/liveposition~ModelLivePosition#_getCombinedReturns a new position that is a combination of this position and given positions.
The combined position is a copy of this position transformed by moving a range starting at
sourceposition to thetargetposition. It is expected that this position is inside the moved range.Example:
let original = model.createPositionFromPath( root, [ 2, 3, 1 ] ); let source = model.createPositionFromPath( root, [ 2, 2 ] ); let target = model.createPositionFromPath( otherRoot, [ 1, 1, 3 ] ); original._getCombined( source, target ); // path is [ 1, 1, 4, 1 ], root is `otherRoot`Copy codeExplanation:
We have a position
[ 2, 3, 1 ]and move some nodes from[ 2, 2 ]to[ 1, 1, 3 ]. The original position was inside moved nodes and now should point to the new place. The moved nodes will be after positions[ 1, 1, 3 ],[ 1, 1, 4 ],[ 1, 1, 5 ]. Since our position was in the second moved node, the transformed position will be in a sub-tree of a node at[ 1, 1, 4 ]. Looking at original path, we took care of[ 2, 3 ]part of it. Now we have to add the rest of the original path to the transformed path. Finally, the transformed position will point to[ 1, 1, 4, 1 ].Parameters
source : ModelPositionBeginning of the moved range.
target : ModelPositionPosition where the range is moved.
Returns
ModelPositionCombined position.
_getTransformedByDeletion( deletePosition, howMany ) → null | ModelPositioninternalinheritedmodule:engine/model/liveposition~ModelLivePosition#_getTransformedByDeletionReturns a copy of this position that is updated by removing
howManynodes starting fromdeletePosition. It may happen that this position is in a removed node. If that is the case,nullis returned instead.Parameters
deletePosition : ModelPositionPosition before the first removed node.
howMany : numberHow many nodes are removed.
Returns
null | ModelPositionTransformed position or
null.
_getTransformedByInsertOperation( operation ) → ModelPositioninternalinheritedmodule:engine/model/liveposition~ModelLivePosition#_getTransformedByInsertOperationReturns a copy of this position transformed by an insert operation.
Parameters
operation : InsertOperation
Returns
_getTransformedByInsertion( insertPosition, howMany ) → ModelPositioninternalinheritedmodule:engine/model/liveposition~ModelLivePosition#_getTransformedByInsertionReturns a copy of this position that is updated by inserting
howManynodes atinsertPosition.Parameters
insertPosition : ModelPositionPosition where nodes are inserted.
howMany : numberHow many nodes are inserted.
Returns
ModelPositionTransformed position.
_getTransformedByMergeOperation( operation ) → ModelPositioninternalinheritedmodule:engine/model/liveposition~ModelLivePosition#_getTransformedByMergeOperationReturns a copy of this position transformed by merge operation.
Parameters
operation : MergeOperation
Returns
_getTransformedByMove( sourcePosition, targetPosition, howMany ) → ModelPositioninternalinheritedmodule:engine/model/liveposition~ModelLivePosition#_getTransformedByMoveReturns a copy of this position that is updated by moving
howManynodes fromsourcePositiontotargetPosition.Parameters
sourcePosition : ModelPositionPosition before the first element to move.
targetPosition : ModelPositionPosition where moved elements will be inserted.
howMany : numberHow many consecutive nodes to move, starting from
sourcePosition.
Returns
ModelPositionTransformed position.
_getTransformedByMoveOperation( operation ) → ModelPositioninternalinheritedmodule:engine/model/liveposition~ModelLivePosition#_getTransformedByMoveOperationReturns a copy of this position transformed by a move operation.
Parameters
operation : MoveOperation
Returns
_getTransformedBySplitOperation( operation ) → ModelPositioninternalinheritedmodule:engine/model/liveposition~ModelLivePosition#_getTransformedBySplitOperationReturns a copy of this position transformed by a split operation.
Parameters
operation : SplitOperation
Returns
Static methods
fromJSON( json, doc ) → ModelPositioninheritedstaticmodule:engine/model/liveposition~ModelLivePosition.fromJSONCreates a
Positioninstance from given plain object (i.e. parsed JSON string).Parameters
json : anyPlain object to be converted to
Position.doc : ModelDocumentDocument object that will be position owner.
Returns
ModelPositionPositioninstance created using given plain object.
fromPosition( position, [ stickiness ] ) → ModelLivePositionstaticmodule:engine/model/liveposition~ModelLivePosition.fromPositionCreates a
ModelLivePositioninstance that is equal to position.Parameters
position : ModelPosition[ stickiness ] : ModelPositionStickiness
Returns
Events
change( eventInfo, oldPosition )module:engine/model/liveposition~ModelLivePosition#event:changeFired when
ModelLivePositioninstance is changed due to changes onModelDocument.Parameters
eventInfo : EventInfoAn object containing information about the fired event.
oldPosition : ModelPositionPosition equal to this live position before it got changed.