+ var firstCursor = this._cursors[0] ;\r
+ var lastCursor = this._cursors[ this._cursors.length - 1 ] ;\r
+ var domRange = new FCKDomRange( FCKTools.GetElementWindow( firstCursor.GetTextNode() ) ) ;\r
+ var w3cRange = domRange._Range = domRange.CreateRange() ;\r
+ w3cRange.setStart( firstCursor.GetTextNode(), firstCursor.GetIndex() ) ;\r
+ w3cRange.setEnd( lastCursor.GetTextNode(), lastCursor.GetIndex() + 1 ) ;\r
+ domRange._UpdateElementInfo() ;\r
+ return domRange ;\r
+ },\r
+\r
+ Highlight : function()\r
+ {\r
+ if ( this._cursors.length < 1 )\r
+ return ;\r
+\r
+ var domRange = this.ToDomRange() ;\r
+ HighlightStyle.ApplyToRange( domRange, false, true ) ;\r
+ this._highlightRange = domRange ;\r
+\r
+ var charRange = CharacterRange.CreateFromDomRange( domRange ) ;\r
+ var focusNode = domRange.StartNode ;\r
+ if ( focusNode.nodeType != 1 )\r
+ focusNode = focusNode.parentNode ;\r
+ FCKDomTools.ScrollIntoView( focusNode, false ) ;\r
+ this._cursors = charRange._cursors ;\r
+ },\r
+\r
+ RemoveHighlight : function()\r
+ {\r
+ if ( this._highlightRange )\r
+ {\r
+ HighlightStyle.RemoveFromRange( this._highlightRange, false, true ) ;\r
+ var charRange = CharacterRange.CreateFromDomRange( this._highlightRange ) ;\r
+ this._cursors = charRange._cursors ;\r
+ this._highlightRange = null ;\r
+ }\r
+ },\r
+\r
+ GetHighlightDomRange : function()\r
+ {\r
+ return this._highlightRange;\r
+ },\r
+\r
+ MoveNext : function()\r
+ {\r
+ var next = this._cursors[ this._cursors.length - 1 ].Clone() ;\r
+ var retval = next.MoveNext() ;\r
+ if ( retval )\r
+ this._cursors = [] ;\r
+ this._cursors.push( next ) ;\r
+ if ( this._cursors.length > this._maxLength )\r
+ this._cursors.shift() ;\r
+ return retval ;\r
+ },\r
+\r
+ MoveBack : function()\r
+ {\r
+ var prev = this._cursors[0].Clone() ;\r
+ var retval = prev.MoveBack() ;\r
+ if ( retval )\r
+ this._cursors = [] ;\r
+ this._cursors.unshift( prev ) ;\r
+ if ( this._cursors.length > this._maxLength )\r
+ this._cursors.pop() ;\r
+ return retval ;\r
+ },\r
+\r
+ GetEndCharacter : function()\r
+ {\r
+ if ( this._cursors.length < 1 )\r
+ return null ;\r
+ var retval = this._cursors[ this._cursors.length - 1 ].GetCharacter() ;\r
+ return retval ;\r
+ },\r
+\r
+ GetNextRange : function( len )\r
+ {\r
+ if ( this._cursors.length == 0 )\r
+ return null ;\r
+ var cur = this._cursors[ this._cursors.length - 1 ].Clone() ;\r
+ cur.MoveNext() ;\r
+ return new CharacterRange( cur, len ) ;\r
+ },\r
+\r
+ GetCursors : function()\r
+ {\r
+ return this._cursors ;\r
+ }\r
+} ;\r
+\r
+CharacterRange.CreateFromDomRange = function( domRange )\r
+{\r
+ var w3cRange = domRange._Range ;\r
+ var startContainer = w3cRange.startContainer ;\r
+ var endContainer = w3cRange.endContainer ;\r
+ var startTextNode, startIndex, endTextNode, endIndex ;\r
+\r
+ if ( startContainer.nodeType == 3 )\r
+ {\r
+ startTextNode = startContainer ;\r
+ startIndex = w3cRange.startOffset ;\r
+ }\r
+ else if ( domRange.StartNode.nodeType == 3 )\r
+ {\r
+ startTextNode = domRange.StartNode ;\r
+ startIndex = 0 ;\r
+ }\r
+ else\r
+ {\r
+ startTextNode = GetNextNonEmptyTextNode( domRange.StartNode, domRange.StartNode.parentNode ) ;\r
+ if ( !startTextNode )\r
+ return null ;\r
+ startIndex = 0 ;\r
+ }\r
+\r
+ if ( endContainer.nodeType == 3 && w3cRange.endOffset > 0 )\r
+ {\r
+ endTextNode = endContainer ;\r
+ endIndex = w3cRange.endOffset - 1 ;\r
+ }\r
+ else\r
+ {\r
+ endTextNode = domRange.EndNode ;\r
+ while ( endTextNode.nodeType != 3 )\r
+ endTextNode = endTextNode.lastChild ;\r
+ endIndex = endTextNode.length - 1 ;\r
+ }\r
+\r
+ var cursors = [] ;\r
+ var current = new CharacterCursor( startTextNode, startIndex ) ;\r
+ cursors.push( current ) ;\r
+ if ( !( current.GetTextNode() == endTextNode && current.GetIndex() == endIndex ) && !domRange.CheckIsEmpty() )\r
+ {\r
+ do\r