# CKEDITOR.dom.range

class

Represents a delimited piece of content in a DOM Document. It is contiguous in the sense that it can be characterized as selecting all of the content between a pair of boundary-points.

This class shares much of the W3C Document Object Model Range ideas and features, adding several range manipulation tools to it, but it's not intended to be compatible with it.

// Create a range for the entire contents of the editor document body.
var range = new CKEDITOR.dom.range( editor.document );
range.selectNodeContents( editor.document.getBody() );
// Delete the contents.
range.deleteContents();


Usually you will want to work on a ranges rooted in the editor's editable element. Such ranges can be created with a shorthand method – editor.createRange.

var range = editor.createRange();
range.root.equals( editor.editable() ); // -> true


Note that the root of a range is an important property, which limits many algorithms implemented in range's methods. Therefore it is crucial, especially when using ranges inside inline editors, to specify correct root, so using the CKEDITOR.editor.createRange method is highly recommended.

###### Selection

Range is only a logical representation of a piece of content in a DOM. It should not be confused with a selection which represents "physically marked" content. It is possible to create unlimited number of various ranges, when only one real selection may exist at a time in a document. Ranges are used to read position of selection in the DOM and to move selection to new positions.

The editor selection may be retrieved using the CKEDITOR.editor.getSelection method:

var sel = editor.getSelection(),
ranges = sel.getRanges(); // CKEDITOR.dom.rangeList instance.

var range = ranges[ 0 ];
range.root; // -> editor's editable element.


A range can also be selected:

var range = editor.createRange();
range.selectNodeContents( editor.editable() );
sel.selectRanges( [ range ] );


## Properties

• ### collapsed : BooleanCKEDITOR.dom.range#collapsed

Indicates that this is a collapsed range. A collapsed range has its start and end boundaries at the very same point so nothing is contained in it.

var range = new CKEDITOR.dom.range( editor.document );
range.selectNodeContents( editor.document.getBody() );
range.collapse();


Defaults to true

• ### document : documentCKEDITOR.dom.range#document

The document within which the range can be used.

// Selects the body contents of the range document.
range.selectNodeContents( range.document.getBody() );

• ### endContainer : element | textCKEDITOR.dom.range#endContainer

Node within which the range ends.

var range = new CKEDITOR.dom.range( editor.document );
range.selectNodeContents( editor.document.getBody() );

• ### endOffset : NumberCKEDITOR.dom.range#endOffset

Offset within the ending node of the range.

var range = new CKEDITOR.dom.range( editor.document );
range.selectNodeContents( editor.document.getBody() );
alert( range.endOffset ); // == editor.document.getBody().getChildCount()

• ### root : elementCKEDITOR.dom.range#root

The ancestor DOM element within which the range manipulation are limited.

• ### startContainer : element | textCKEDITOR.dom.range#startContainer

Node within which the range begins.

var range = new CKEDITOR.dom.range( editor.document );
range.selectNodeContents( editor.document.getBody() );

• ### startOffset : NumberCKEDITOR.dom.range#startOffset

Offset within the starting node of the range.

var range = new CKEDITOR.dom.range( editor.document );
range.selectNodeContents( editor.document.getBody() );


## Methods

• ### constructor( root ) → rangeCKEDITOR.dom.range#constructor

Creates a CKEDITOR.dom.range instance that can be used inside a specific DOM Document.

#### Parameters

root : document | element

The document or element within which the range will be scoped. global "TODO" - precise algorithms descriptions needed for the most complex methods like enlarge.

#### Returns

range
• ### checkBoundaryOfElement( element, checkType ) → BooleanCKEDITOR.dom.range#checkBoundaryOfElement

Check whether a range boundary is at the inner boundary of a given element.

#### Parameters

element : element

The target element to check.

checkType : Number

The boundary to check for both the range and the element. It can be CKEDITOR.START or CKEDITOR.END.

#### Returns

Boolean

true if the range boundary is at the inner boundary of the element.

• ### checkEndOfBlock() → BooleanCKEDITOR.dom.range#checkEndOfBlock

Note: Calls to this function may produce changes to the DOM. The range may be updated to reflect such changes.

#### Returns

Boolean
• ### checkReadOnly() → BooleanCKEDITOR.dom.range#checkReadOnly

Check if elements at which the range boundaries anchor are read-only, with respect to contenteditable attribute.

#### Returns

Boolean
• ### checkStartOfBlock() → BooleanCKEDITOR.dom.range#checkStartOfBlock

Note: Calls to this function may produce changes to the DOM. The range may be updated to reflect such changes.

#### Returns

Boolean
• ### clone() → rangeCKEDITOR.dom.range#clone

Clones this range.

#### Returns

range
• ### cloneContents( [ cloneId ] ) → documentFragmentCKEDITOR.dom.range#cloneContents

Clones content nodes of the range and adds them to a document fragment, which is returned.

#### Parameters

[ cloneId ] : Boolean

Whether to preserve ID attributes in the clone.

Defaults to true

#### Returns

documentFragment

Document fragment containing a clone of range's content.

• ### collapse( toStart )CKEDITOR.dom.range#collapse

Makes the range collapsed by moving its start point (or end point if toStart==true) to the second end.

#### Parameters

toStart : Boolean

Collapse range "to start".

• ### createBookmark( [ serializable ] ) → ObjectCKEDITOR.dom.range#createBookmark

Creates a bookmark object, which can be later used to restore the range by using the moveToBookmark function.

This is an "intrusive" way to create a bookmark. It includes <span> tags in the range boundaries. The advantage of it is that it is possible to handle DOM mutations when moving back to the bookmark.

Note: The inclusion of nodes in the DOM is a design choice and should not be changed as there are other points in the code that may be using those nodes to perform operations.

#### Parameters

[ serializable ] : Boolean

Indicates that the bookmark nodes must contain IDs, which can be used to restore the range even when these nodes suffer mutations (like cloning or innerHTML change).

#### Returns

Object

And object representing a bookmark.

Properties
startNode : node | String

Node or element ID.

endNode : node | String

Node or element ID.

serializable : Boolean
collapsed : Boolean
• ### createBookmark2( [ normalized ] ) → ObjectCKEDITOR.dom.range#createBookmark2

Creates a "non intrusive" and "mutation sensible" bookmark. This kind of bookmark should be used only when the DOM is supposed to remain stable after its creation.

#### Parameters

[ normalized ] : Boolean

Indicates that the bookmark must be normalized. When normalized, the successive text nodes are considered a single node. To successfully load a normalized bookmark, the DOM tree must also be normalized before calling moveToBookmark.

#### Returns

Object

An object representing the bookmark.

Properties
start : Array

end : Array

startOffset : Number
endOffset : Number
collapsed : Boolean
normalized : Boolean
is2 : Boolean

This is "bookmark2".

• ### createIterator() → iteratorCKEDITOR.dom.range#createIterator

Creates a CKEDITOR.dom.iterator instance for this range.

#### Returns

iterator
• ### deleteContents( [ mergeThen ] )CKEDITOR.dom.range#deleteContents

Deletes the content nodes of the range permanently from the DOM tree.

#### Parameters

[ mergeThen ] : Boolean

Merge any split elements result in DOM true due to partial selection.

• ### endPath() → elementPathCKEDITOR.dom.range#endPath

#### Returns

elementPath
• ### enlarge( unit, [ excludeBrs ] )CKEDITOR.dom.range#enlarge

Expands the range so that partial units are completely contained.

#### Parameters

unit : Number

The unit type to expand with. Use one of following values: CKEDITOR.ENLARGE_BLOCK_CONTENTS, CKEDITOR.ENLARGE_ELEMENT, CKEDITOR.ENLARGE_INLINE, CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS.

[ excludeBrs ] : Boolean

Whether include line-breaks when expanding.

Defaults to false

• ### equals( range ) → BooleanCKEDITOR.dom.range#equals

since 4.13.0

Whether this range is the same as another passed range.

#### Parameters

range : range

A range to be compared with this range.

#### Returns

Boolean

Whether ranges are identical.

• ### extractContents( [ mergeThen ], [ cloneId ] ) → documentFragmentCKEDITOR.dom.range#extractContents

The content nodes of the range are cloned and added to a document fragment, meanwhile they are removed permanently from the DOM tree.

Note: Setting the cloneId parameter to false works for partially selected elements only. If an element with an ID attribute is fully enclosed in a range, it will keep the ID attribute regardless of the cloneId parameter value, because it is not cloned — it is moved to the returned document fragment.

#### Parameters

[ mergeThen ] : Boolean

Merge any split elements result in DOM true due to partial selection.

[ cloneId ] : Boolean

Whether to preserve ID attributes in the extracted content.

Defaults to true

#### Returns

documentFragment

Document fragment containing extracted content.

• ### fixBlock( isStart, blockTag ) → elementCKEDITOR.dom.range#fixBlock

Wraps inline content found around the range's start or end boundary with a block element.

// Assuming the following range:
// <h1>foo</h1>ba^r<br />bom<p>foo</p>
// The result of executing:
range.fixBlock( true, 'p' );
// will be:
// <h1>foo</h1><p>ba^r<br />bom</p><p>foo</p>


Non-collapsed range:

// Assuming the following range:
// ba[r<p>foo</p>bo]m
// The result of executing:
range.fixBlock( false, 'p' );
// will be:
// ba[r<p>foo</p><p>bo]m</p>


#### Parameters

isStart : Boolean

Whether the start or end boundary of a range should be checked.

blockTag : String

The name of a block element in which content will be wrapped. For example: 'p'.

#### Returns

element

Created block wrapper.

• ### getBoundaryNodes() → ObjectCKEDITOR.dom.range#getBoundaryNodes

Returns two nodes which are on the boundaries of this range.

#### Returns

Object
Properties
startNode : node
endNode : node

precise desc/algorithm

• ### getClientRects( [ isAbsolute ] ) → rect[]CKEDITOR.dom.range#getClientRects

since 4.10.0

Returns an array of CKEDITOR.dom.rect elements that are represented as rectangles which are covered by ranges. Rectangles represent the area of the screen occupied by the elements contained within the range.

In the following example:

 <p><span>first {span</span><span> second span</span></p>
<p><span>very long }span</span></p>


Brackets represent the beginning and the end of the selection.

Returned rectangles would be represented by areas like below:

first [span][ second span]
[very long ]span


where each pair of brackets represents one rectangle.

Note: Various browsers might return a different list of rectangles.

Internet Explorer 8 does not have the native range.getClientRects() method, which is a base for this method, implemented. As a workaround it will return an array containing only one rectangle which would start in the top left-hand corner of the selection and end in the bottom right-hand corner. Possible cases when the returned rectangle does not fully cover ranges are presented below:

#### Parameters

[ isAbsolute ] : Boolean

The function will retrieve an absolute rectangle of the element, i.e. a position relative to the upper-left corner of the topmost viewport.

#### Returns

rect[]
• ### getCommonAncestor( [ includeSelf ], [ ignoreTextNode ] ) → elementCKEDITOR.dom.range#getCommonAncestor

Find the node which fully contains the range.

#### Parameters

[ includeSelf ] : Boolean

Defaults to false

[ ignoreTextNode ] : Boolean

Whether ignore CKEDITOR.NODE_TEXT type.

Defaults to false

#### Returns

element
• ### getEnclosedNode() → nodeCKEDITOR.dom.range#getEnclosedNode

Get the single node enclosed within the range if there's one.

#### Returns

node
• ### getNextEditableNode() → element | textCKEDITOR.dom.range#getNextEditableNode

since 4.3.0

Gets next node which can be a container of a selection. This methods mimics a behavior of right/left arrow keys in case of collapsed selection. It does not return an exact position (with offset) though, but just a selection's container.

Note: use this method on a collapsed range.

#### Returns

element | text
• ### getNextNode( evaluator, [ guard ], [ boundary ] ) → element | nullCKEDITOR.dom.range#getNextNode

Traverse with CKEDITOR.dom.walker to retrieve the next element before the range start.

#### Parameters

evaluator : Function

Function used as the walker's evaluator.

[ guard ] : Function

Function used as the walker's guard.

[ boundary ] : element

A range ancestor element in which the traversal is limited, default to the root editable if not defined.

#### Returns

element | null

The returned node from the traversal.

• ### getPreviousEditableNode() → element | textCKEDITOR.dom.range#getPreviousEditableNode

since 4.3.0

#### Returns

element | text
• ### getPreviousNode( evaluator, [ guard ], [ boundary ] ) → element | nullCKEDITOR.dom.range#getPreviousNode

Traverse with CKEDITOR.dom.walker to retrieve the previous element before the range start.

#### Parameters

evaluator : Function

Function used as the walker's evaluator.

[ guard ] : Function

Function used as the walker's guard.

[ boundary ] : element

A range ancestor element in which the traversal is limited, default to the root editable if not defined.

#### Returns

element | null

The returned node from the traversal.

• ### getTouchedEndNode() → nodeCKEDITOR.dom.range#getTouchedEndNode

Get the node adjacent to the range end or endContainer.

#### Returns

node
• ### getTouchedStartNode() → nodeCKEDITOR.dom.range#getTouchedStartNode

Get the node adjacent to the range start or startContainer.

#### Returns

node
• ### insertNode( node )CKEDITOR.dom.range#insertNode

Inserts a node at the start of the range. The range will be expanded to contain the node.

#### Parameters

node : node
• ### moveToBookmark( bookmark )CKEDITOR.dom.range#moveToBookmark

Moves this range to the given bookmark. See createBookmark and createBookmark2.

If serializable bookmark passed, then its <span> markers will be removed.

#### Parameters

bookmark : Object
• ### moveToClosestEditablePosition( [ element ], [ isMoveForward ] ) → BooleanCKEDITOR.dom.range#moveToClosestEditablePosition

since 4.3.0

Moves the range boundaries to the closest editing point after/before an element or the current range position (depends on whether the element was specified).

For example, if the start element has id="start", <p><b>foo</b><span id="start">start</start></p>, the closest previous editing point is <p><b>foo</b>^<span id="start">start</start></p> (between <b> and <span>).

#### Parameters

[ element ] : element

The starting element. If not specified, the current range position will be used.

[ isMoveForward ] : Boolean

Whether move to the end of editable. Otherwise, look back.

#### Returns

Boolean

Whether the range was moved.

• ### moveToElementEditEnd( target ) → BooleanCKEDITOR.dom.range#moveToElementEditEnd

#### Parameters

target : Object

#### Returns

Boolean

Whether range was moved.

• ### moveToElementEditStart( target ) → BooleanCKEDITOR.dom.range#moveToElementEditStart

#### Parameters

target : Object

#### Returns

Boolean

Whether range was moved.

• ### moveToElementEditablePosition( el, isMoveToEnd ) → BooleanCKEDITOR.dom.range#moveToElementEditablePosition

Moves the range boundaries to the first/end editing point inside an element.

For example, in an element tree like <p><b><i></i></b> Text</p>, the start editing point is <p><b><i>^</i></b> Text</p> (inside <i>).

#### Parameters

el : element

The element into which look for the editing spot.

isMoveToEnd : Boolean

Whether move to the end editable position.

#### Returns

Boolean

Whether range was moved.

• ### moveToPosition( node, position )CKEDITOR.dom.range#moveToPosition

Moves the range to a given position according to the specified node.

// HTML: <p>Foo <b>bar</b></p>
range.moveToPosition( elB, CKEDITOR.POSITION_BEFORE_START );
// Range will be moved to: <p>Foo ^<b>bar</b></p>


#### Parameters

node : node

The node according to which the position will be set.

position : Number
• ### moveToRange( range )CKEDITOR.dom.range#moveToRange

Moves the range to the exact position of the specified range.

#### Parameters

range : range
• ### optimize()CKEDITOR.dom.range#optimize

Transforms the startContainer and endContainer properties from text nodes to element nodes, whenever possible. This is actually possible if either of the boundary containers point to a text node, and its offset is set to zero, or after the last char in the node.

• ### optimizeBookmark()CKEDITOR.dom.range#optimizeBookmark

Move the range out of bookmark nodes if they'd been the container.

• ### removeEmptyBlocksAtEnd( atEnd )CKEDITOR.dom.range#removeEmptyBlocksAtEnd

Recursively remove any empty path blocks at the range boundary.

#### Parameters

atEnd : Boolean

Removal to perform at the end boundary, otherwise to perform at the start.

• ### scrollIntoView()CKEDITOR.dom.range#scrollIntoView

Scrolls the start of current range into view.

• ### select() → selectionCKEDITOR.dom.range#select

Select this range as the only one with CKEDITOR.dom.selection.selectRanges.

#### Returns

selection
• ### selectNodeContents( node )CKEDITOR.dom.range#selectNodeContents

Select nodes content. Range will start and end inside this node.

#### Parameters

node : node
• ### setEnd( endNode, endOffset )CKEDITOR.dom.range#setEnd

Sets the end position of a Range.

#### Parameters

endNode : node

The node to end the range.

endOffset : Number

An integer greater than or equal to zero representing the offset for the end of the range from the start of endNode.

• ### setEndAfter( node )CKEDITOR.dom.range#setEndAfter

Sets end of this range after the specified node.

// Range: <p>foo^<b>bar</b></p>
range.setEndAfter( elB );
// The range will be changed to:
// <p>foo[<b>bar</b>]</p>


#### Parameters

node : node
• ### setEndAt( node, position )CKEDITOR.dom.range#setEndAt

Moves the end of this range to given position according to specified node.

// HTML: <p>^Foo <b>bar</b></p>
range.setEndAt( textBar, CKEDITOR.POSITION_BEFORE_START );
// The range will be changed to:
// <p>[Foo <b>]bar</b></p>


#### Parameters

node : node

The node according to which position will be set.

position : Number
• ### setEndBefore( node )CKEDITOR.dom.range#setEndBefore

Sets end of this range before the specified node.

// Range: <p>^foo<b>bar</b></p>
range.setStartAfter( textBar );
// The range will be changed to:
// <p>[foo<b>]bar</b></p>


#### Parameters

node : node
• ### setStart( startNode, startOffset )CKEDITOR.dom.range#setStart

Sets the start position of a range.

#### Parameters

startNode : node

The node to start the range.

startOffset : Number

An integer greater than or equal to zero representing the offset for the start of the range from the start of startNode.

• ### setStartAfter( node )CKEDITOR.dom.range#setStartAfter

Sets start of this range after the specified node.

// Range: <p>foo<b>bar</b>^</p>
range.setStartAfter( textFoo );
// The range will be changed to:
// <p>foo[<b>bar</b>]</p>


#### Parameters

node : node
• ### setStartAt( node, position )CKEDITOR.dom.range#setStartAt

Moves the start of this range to given position according to specified node.

// HTML: <p>Foo <b>bar</b>^</p>
range.setStartAt( elB, CKEDITOR.POSITION_AFTER_START );
// The range will be changed to:
// <p>Foo <b>[bar</b>]</p>


#### Parameters

node : node

The node according to which position will be set.

position : Number
• ### setStartBefore( node )CKEDITOR.dom.range#setStartBefore

Sets start of this range after the specified node.

// Range: <p>foo<b>bar</b>^</p>
range.setStartBefore( elB );
// The range will be changed to:
// <p>foo[<b>bar</b>]</p>


#### Parameters

node : node
• ### shrink( mode, [ selectContents ], [ options ] )CKEDITOR.dom.range#shrink

Decreases the range to make sure that boundaries always anchor beside text nodes or the innermost element.

#### Parameters

mode : Number

The shrinking mode (CKEDITOR.SHRINK_ELEMENT or CKEDITOR.SHRINK_TEXT).

• CKEDITOR.SHRINK_ELEMENT – Shrinks the range boundaries to the edge of the innermost element.
• CKEDITOR.SHRINK_TEXT – Shrinks the range boundaries to anchor by the side of enclosed text node. The range remains if there are no text nodes available on boundaries.
[ selectContents ] : Boolean

Whether the resulting range anchors at the inner OR outer boundary of the node.

Defaults to false

[ options ] : Boolean | Object

If this parameter is of a Boolean type, it is treated as options.shrinkOnBlockBoundary. This parameter was added in 4.7.0.

Properties
[ shrinkOnBlockBoundary ] : Boolean

Whether the block boundary should be included in the shrunk range.

Defaults to true

[ skipBogus ] : Boolean

Whether bogus <br> elements should be ignored while mode is set to CKEDITOR.SHRINK_TEXT. This option was added in 4.7.0.

Defaults to false

Defaults to true

• ### splitBlock( [ cloneId ] )CKEDITOR.dom.range#splitBlock

#### Parameters

[ cloneId ] : Boolean

Whether to preserve ID attributes in the result blocks.

Defaults to false

• ### splitElement( element, [ cloneId ] ) → elementCKEDITOR.dom.range#splitElement

Branch the specified element from the collapsed range position and place the caret between the two result branches.

Note: The range must be collapsed and been enclosed by this element.

#### Parameters

element : element
[ cloneId ] : Boolean

Whether to preserve ID attributes in the result elements.

Defaults to false

#### Returns

element

Root element of the new branch after the split.

• ### startPath() → elementPathCKEDITOR.dom.range#startPath

#### Returns

elementPath
• ### trim( [ ignoreStart ], [ ignoreEnd ] )CKEDITOR.dom.range#trim

#### Parameters

[ ignoreStart ] : Boolean

Defaults to false

[ ignoreEnd ] : Boolean

precise desc/algorithm

Defaults to false

• ### _find( query, [ includeNonEditables ] ) → element[]CKEDITOR.dom.range#_find

since 4.5.11 private

Looks for elements matching the query selector within a range.

#### Parameters

query : String

A valid CSS selector.

[ includeNonEditables ] : Boolean

Whether elements with contenteditable set to false should be included.

Defaults to false

#### Returns

element[]
• ### _getTableElement( [ tableElements ] ) → element | nullCKEDITOR.dom.range#_getTableElement

since 4.7.0 private

Returns any table element, like td, tbody, table etc. from a given range. The element is returned only if the range is contained within one table (might be a nested table, but it cannot be two different tables on the same DOM level).

#### Parameters

[ tableElements ] : Object

Mapping of element names that should be considered.

#### Returns

element | null
• ### _setEndContainer( endContainer )CKEDITOR.dom.range#_setEndContainer

since 4.4.6 private

Setter for the endContainer.

#### Parameters

endContainer : element
• ### _setStartContainer( startContainer )CKEDITOR.dom.range#_setStartContainer

since 4.4.6 private

Setter for the startContainer.

#### Parameters

startContainer : element

• ### mergeRanges( ranges ) → range[]CKEDITOR.dom.range#mergeRanges

since 4.7.0 static

Merges every subsequent range in given set, returning a smaller array of ranges.

Note that each range in the returned value will be enlarged with CKEDITOR.ENLARGE_ELEMENT value.

#### Parameters

ranges : range[]

#### Returns

range[]

Set of merged ranges.