update address standardization for cust_location changes
[freeside.git] / rt / share / html / NoAuth / RichText / FCKeditor / editor / _source / classes / fckdomrange.js
diff --git a/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/classes/fckdomrange.js b/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/classes/fckdomrange.js
deleted file mode 100644 (file)
index b0912eb..0000000
+++ /dev/null
@@ -1,935 +0,0 @@
-/*\r
- * FCKeditor - The text editor for Internet - http://www.fckeditor.net\r
- * Copyright (C) 2003-2009 Frederico Caldeira Knabben\r
- *\r
- * == BEGIN LICENSE ==\r
- *\r
- * Licensed under the terms of any of the following licenses at your\r
- * choice:\r
- *\r
- *  - GNU General Public License Version 2 or later (the "GPL")\r
- *    http://www.gnu.org/licenses/gpl.html\r
- *\r
- *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")\r
- *    http://www.gnu.org/licenses/lgpl.html\r
- *\r
- *  - Mozilla Public License Version 1.1 or later (the "MPL")\r
- *    http://www.mozilla.org/MPL/MPL-1.1.html\r
- *\r
- * == END LICENSE ==\r
- *\r
- * Class for working with a selection range, much like the W3C DOM Range, but\r
- * it is not intended to be an implementation of the W3C interface.\r
- */\r
-\r
-var FCKDomRange = function( sourceWindow )\r
-{\r
-       this.Window = sourceWindow ;\r
-       this._Cache = {} ;\r
-}\r
-\r
-FCKDomRange.prototype =\r
-{\r
-\r
-       _UpdateElementInfo : function()\r
-       {\r
-               var innerRange = this._Range ;\r
-\r
-               if ( !innerRange )\r
-                       this.Release( true ) ;\r
-               else\r
-               {\r
-                       // For text nodes, the node itself is the StartNode.\r
-                       var eStart      = innerRange.startContainer ;\r
-\r
-                       var oElementPath = new FCKElementPath( eStart ) ;\r
-                       this.StartNode                  = eStart.nodeType == 3 ? eStart : eStart.childNodes[ innerRange.startOffset ] ;\r
-                       this.StartContainer             = eStart ;\r
-                       this.StartBlock                 = oElementPath.Block ;\r
-                       this.StartBlockLimit    = oElementPath.BlockLimit ;\r
-\r
-                       if ( innerRange.collapsed )\r
-                       {\r
-                               this.EndNode            = this.StartNode ;\r
-                               this.EndContainer       = this.StartContainer ;\r
-                               this.EndBlock           = this.StartBlock ;\r
-                               this.EndBlockLimit      = this.StartBlockLimit ;\r
-                       }\r
-                       else\r
-                       {\r
-                               var eEnd        = innerRange.endContainer ;\r
-\r
-                               if ( eStart != eEnd )\r
-                                       oElementPath = new FCKElementPath( eEnd ) ;\r
-\r
-                               // The innerRange.endContainer[ innerRange.endOffset ] is not\r
-                               // usually part of the range, but the marker for the range end. So,\r
-                               // let's get the previous available node as the real end.\r
-                               var eEndNode = eEnd ;\r
-                               if ( innerRange.endOffset == 0 )\r
-                               {\r
-                                       while ( eEndNode && !eEndNode.previousSibling )\r
-                                               eEndNode = eEndNode.parentNode ;\r
-\r
-                                       if ( eEndNode )\r
-                                               eEndNode = eEndNode.previousSibling ;\r
-                               }\r
-                               else if ( eEndNode.nodeType == 1 )\r
-                                       eEndNode = eEndNode.childNodes[ innerRange.endOffset - 1 ] ;\r
-\r
-                               this.EndNode                    = eEndNode ;\r
-                               this.EndContainer               = eEnd ;\r
-                               this.EndBlock                   = oElementPath.Block ;\r
-                               this.EndBlockLimit              = oElementPath.BlockLimit ;\r
-                       }\r
-               }\r
-\r
-               this._Cache = {} ;\r
-       },\r
-\r
-       CreateRange : function()\r
-       {\r
-               return new FCKW3CRange( this.Window.document ) ;\r
-       },\r
-\r
-       DeleteContents : function()\r
-       {\r
-               if ( this._Range )\r
-               {\r
-                       this._Range.deleteContents() ;\r
-                       this._UpdateElementInfo() ;\r
-               }\r
-       },\r
-\r
-       ExtractContents : function()\r
-       {\r
-               if ( this._Range )\r
-               {\r
-                       var docFrag = this._Range.extractContents() ;\r
-                       this._UpdateElementInfo() ;\r
-                       return docFrag ;\r
-               }\r
-               return null ;\r
-       },\r
-\r
-       CheckIsCollapsed : function()\r
-       {\r
-               if ( this._Range )\r
-                       return this._Range.collapsed ;\r
-\r
-               return false ;\r
-       },\r
-\r
-       Collapse : function( toStart )\r
-       {\r
-               if ( this._Range )\r
-                       this._Range.collapse( toStart ) ;\r
-\r
-               this._UpdateElementInfo() ;\r
-       },\r
-\r
-       Clone : function()\r
-       {\r
-               var oClone = FCKTools.CloneObject( this ) ;\r
-\r
-               if ( this._Range )\r
-                       oClone._Range = this._Range.cloneRange() ;\r
-\r
-               return oClone ;\r
-       },\r
-\r
-       MoveToNodeContents : function( targetNode )\r
-       {\r
-               if ( !this._Range )\r
-                       this._Range = this.CreateRange() ;\r
-\r
-               this._Range.selectNodeContents( targetNode ) ;\r
-\r
-               this._UpdateElementInfo() ;\r
-       },\r
-\r
-       MoveToElementStart : function( targetElement )\r
-       {\r
-               this.SetStart(targetElement,1) ;\r
-               this.SetEnd(targetElement,1) ;\r
-       },\r
-\r
-       // Moves to the first editing point inside a element. For example, in a\r
-       // element tree like "<p><b><i></i></b> Text</p>", the start editing point\r
-       // is "<p><b><i>^</i></b> Text</p>" (inside <i>).\r
-       MoveToElementEditStart : function( targetElement )\r
-       {\r
-               var editableElement ;\r
-\r
-               while ( targetElement && targetElement.nodeType == 1 )\r
-               {\r
-                       if ( FCKDomTools.CheckIsEditable( targetElement ) )\r
-                               editableElement = targetElement ;\r
-                       else if ( editableElement )\r
-                               break ;         // If we already found an editable element, stop the loop.\r
-\r
-                       targetElement = targetElement.firstChild ;\r
-               }\r
-\r
-               if ( editableElement )\r
-                       this.MoveToElementStart( editableElement ) ;\r
-       },\r
-\r
-       InsertNode : function( node )\r
-       {\r
-               if ( this._Range )\r
-                       this._Range.insertNode( node ) ;\r
-       },\r
-\r
-       CheckIsEmpty : function()\r
-       {\r
-               if ( this.CheckIsCollapsed() )\r
-                       return true ;\r
-\r
-               // Inserts the contents of the range in a div tag.\r
-               var eToolDiv = this.Window.document.createElement( 'div' ) ;\r
-               this._Range.cloneContents().AppendTo( eToolDiv ) ;\r
-\r
-               FCKDomTools.TrimNode( eToolDiv ) ;\r
-\r
-               return ( eToolDiv.innerHTML.length == 0 ) ;\r
-       },\r
-\r
-       /**\r
-        * Checks if the start boundary of the current range is "visually" (like a\r
-        * selection caret) at the beginning of the block. It means that some\r
-        * things could be brefore the range, like spaces or empty inline elements,\r
-        * but it would still be considered at the beginning of the block.\r
-        */\r
-       CheckStartOfBlock : function()\r
-       {\r
-               var cache = this._Cache ;\r
-               var bIsStartOfBlock = cache.IsStartOfBlock ;\r
-\r
-               if ( bIsStartOfBlock != undefined )\r
-                       return bIsStartOfBlock ;\r
-\r
-               // Take the block reference.\r
-               var block = this.StartBlock || this.StartBlockLimit ;\r
-\r
-               var container   = this._Range.startContainer ;\r
-               var offset              = this._Range.startOffset ;\r
-               var currentNode ;\r
-\r
-               if ( offset > 0 )\r
-               {\r
-                       // First, check the start container. If it is a text node, get the\r
-                       // substring of the node value before the range offset.\r
-                       if ( container.nodeType == 3 )\r
-                       {\r
-                               var textValue = container.nodeValue.substr( 0, offset ).Trim() ;\r
-\r
-                               // If we have some text left in the container, we are not at\r
-                               // the end for the block.\r
-                               if ( textValue.length != 0 )\r
-                                       return cache.IsStartOfBlock = false ;\r
-                       }\r
-                       else\r
-                               currentNode = container.childNodes[ offset - 1 ] ;\r
-               }\r
-\r
-               // We'll not have a currentNode if the container was a text node, or\r
-               // the offset is zero.\r
-               if ( !currentNode )\r
-                       currentNode = FCKDomTools.GetPreviousSourceNode( container, true, null, block ) ;\r
-\r
-               while ( currentNode )\r
-               {\r
-                       switch ( currentNode.nodeType )\r
-                       {\r
-                               case 1 :\r
-                                       // It's not an inline element.\r
-                                       if ( !FCKListsLib.InlineChildReqElements[ currentNode.nodeName.toLowerCase() ] )\r
-                                               return cache.IsStartOfBlock = false ;\r
-\r
-                                       break ;\r
-\r
-                               case 3 :\r
-                                       // It's a text node with real text.\r
-                                       if ( currentNode.nodeValue.Trim().length > 0 )\r
-                                               return cache.IsStartOfBlock = false ;\r
-                       }\r
-\r
-                       currentNode = FCKDomTools.GetPreviousSourceNode( currentNode, false, null, block ) ;\r
-               }\r
-\r
-               return cache.IsStartOfBlock = true ;\r
-       },\r
-\r
-       /**\r
-        * Checks if the end boundary of the current range is "visually" (like a\r
-        * selection caret) at the end of the block. It means that some things\r
-        * could be after the range, like spaces, empty inline elements, or a\r
-        * single <br>, but it would still be considered at the end of the block.\r
-        */\r
-       CheckEndOfBlock : function( refreshSelection )\r
-       {\r
-               var isEndOfBlock = this._Cache.IsEndOfBlock ;\r
-\r
-               if ( isEndOfBlock != undefined )\r
-                       return isEndOfBlock ;\r
-\r
-               // Take the block reference.\r
-               var block = this.EndBlock || this.EndBlockLimit ;\r
-\r
-               var container   = this._Range.endContainer ;\r
-               var offset                      = this._Range.endOffset ;\r
-               var currentNode ;\r
-\r
-               // First, check the end container. If it is a text node, get the\r
-               // substring of the node value after the range offset.\r
-               if ( container.nodeType == 3 )\r
-               {\r
-                       var textValue = container.nodeValue ;\r
-                       if ( offset < textValue.length )\r
-                       {\r
-                               textValue = textValue.substr( offset ) ;\r
-\r
-                               // If we have some text left in the container, we are not at\r
-                               // the end for the block.\r
-                               if ( textValue.Trim().length != 0 )\r
-                                       return this._Cache.IsEndOfBlock = false ;\r
-                       }\r
-               }\r
-               else\r
-                       currentNode = container.childNodes[ offset ] ;\r
-\r
-               // We'll not have a currentNode if the container was a text node, of\r
-               // the offset is out the container children limits (after it probably).\r
-               if ( !currentNode )\r
-                       currentNode = FCKDomTools.GetNextSourceNode( container, true, null, block ) ;\r
-\r
-               var hadBr = false ;\r
-\r
-               while ( currentNode )\r
-               {\r
-                       switch ( currentNode.nodeType )\r
-                       {\r
-                               case 1 :\r
-                                       var nodeName = currentNode.nodeName.toLowerCase() ;\r
-\r
-                                       // It's an inline element.\r
-                                       if ( FCKListsLib.InlineChildReqElements[ nodeName ] )\r
-                                               break ;\r
-\r
-                                       // It is the first <br> found.\r
-                                       if ( nodeName == 'br' && !hadBr )\r
-                                       {\r
-                                               hadBr = true ;\r
-                                               break ;\r
-                                       }\r
-\r
-                                       return this._Cache.IsEndOfBlock = false ;\r
-\r
-                               case 3 :\r
-                                       // It's a text node with real text.\r
-                                       if ( currentNode.nodeValue.Trim().length > 0 )\r
-                                               return this._Cache.IsEndOfBlock = false ;\r
-                       }\r
-\r
-                       currentNode = FCKDomTools.GetNextSourceNode( currentNode, false, null, block ) ;\r
-               }\r
-\r
-               if ( refreshSelection )\r
-                       this.Select() ;\r
-\r
-               return this._Cache.IsEndOfBlock = true ;\r
-       },\r
-\r
-       // This is an "intrusive" way to create a bookmark. It includes <span> tags\r
-       // in the range boundaries. The advantage of it is that it is possible to\r
-       // handle DOM mutations when moving back to the bookmark.\r
-       // Attention: the inclusion of nodes in the DOM is a design choice and\r
-       // should not be changed as there are other points in the code that may be\r
-       // using those nodes to perform operations. See GetBookmarkNode.\r
-       // For performance, includeNodes=true if intended to SelectBookmark.\r
-       CreateBookmark : function( includeNodes )\r
-       {\r
-               // Create the bookmark info (random IDs).\r
-               var oBookmark =\r
-               {\r
-                       StartId : (new Date()).valueOf() + Math.floor(Math.random()*1000) + 'S',\r
-                       EndId   : (new Date()).valueOf() + Math.floor(Math.random()*1000) + 'E'\r
-               } ;\r
-\r
-               var oDoc = this.Window.document ;\r
-               var eStartSpan ;\r
-               var eEndSpan ;\r
-               var oClone ;\r
-\r
-               // For collapsed ranges, add just the start marker.\r
-               if ( !this.CheckIsCollapsed() )\r
-               {\r
-                       eEndSpan = oDoc.createElement( 'span' ) ;\r
-                       eEndSpan.style.display = 'none' ;\r
-                       eEndSpan.id = oBookmark.EndId ;\r
-                       eEndSpan.setAttribute( '_fck_bookmark', true ) ;\r
-\r
-                       // For IE, it must have something inside, otherwise it may be\r
-                       // removed during DOM operations.\r
-//                     if ( FCKBrowserInfo.IsIE )\r
-                               eEndSpan.innerHTML = '&nbsp;' ;\r
-\r
-                       oClone = this.Clone() ;\r
-                       oClone.Collapse( false ) ;\r
-                       oClone.InsertNode( eEndSpan ) ;\r
-               }\r
-\r
-               eStartSpan = oDoc.createElement( 'span' ) ;\r
-               eStartSpan.style.display = 'none' ;\r
-               eStartSpan.id = oBookmark.StartId ;\r
-               eStartSpan.setAttribute( '_fck_bookmark', true ) ;\r
-\r
-               // For IE, it must have something inside, otherwise it may be removed\r
-               // during DOM operations.\r
-//             if ( FCKBrowserInfo.IsIE )\r
-                       eStartSpan.innerHTML = '&nbsp;' ;\r
-\r
-               oClone = this.Clone() ;\r
-               oClone.Collapse( true ) ;\r
-               oClone.InsertNode( eStartSpan ) ;\r
-\r
-               if ( includeNodes )\r
-               {\r
-                       oBookmark.StartNode = eStartSpan ;\r
-                       oBookmark.EndNode = eEndSpan ;\r
-               }\r
-\r
-               // Update the range position.\r
-               if ( eEndSpan )\r
-               {\r
-                       this.SetStart( eStartSpan, 4 ) ;\r
-                       this.SetEnd( eEndSpan, 3 ) ;\r
-               }\r
-               else\r
-                       this.MoveToPosition( eStartSpan, 4 ) ;\r
-\r
-               return oBookmark ;\r
-       },\r
-\r
-       // This one should be a part of a hypothetic "bookmark" object.\r
-       GetBookmarkNode : function( bookmark, start )\r
-       {\r
-               var doc = this.Window.document ;\r
-\r
-               if ( start )\r
-                       return bookmark.StartNode || doc.getElementById( bookmark.StartId ) ;\r
-               else\r
-                       return bookmark.EndNode || doc.getElementById( bookmark.EndId ) ;\r
-       },\r
-\r
-       MoveToBookmark : function( bookmark, preserveBookmark )\r
-       {\r
-               var eStartSpan  = this.GetBookmarkNode( bookmark, true ) ;\r
-               var eEndSpan    = this.GetBookmarkNode( bookmark, false ) ;\r
-\r
-               this.SetStart( eStartSpan, 3 ) ;\r
-\r
-               if ( !preserveBookmark )\r
-                       FCKDomTools.RemoveNode( eStartSpan ) ;\r
-\r
-               // If collapsed, the end span will not be available.\r
-               if ( eEndSpan )\r
-               {\r
-                       this.SetEnd( eEndSpan, 3 ) ;\r
-\r
-                       if ( !preserveBookmark )\r
-                               FCKDomTools.RemoveNode( eEndSpan ) ;\r
-               }\r
-               else\r
-                       this.Collapse( true ) ;\r
-\r
-               this._UpdateElementInfo() ;\r
-       },\r
-\r
-       // Non-intrusive bookmark algorithm\r
-       CreateBookmark2 : function()\r
-       {\r
-               // If there is no range then get out of here.\r
-               // It happens on initial load in Safari #962 and if the editor it's hidden also in Firefox\r
-               if ( ! this._Range )\r
-                       return { "Start" : 0, "End" : 0 } ;\r
-\r
-               // First, we record down the offset values\r
-               var bookmark =\r
-               {\r
-                       "Start" : [ this._Range.startOffset ],\r
-                       "End" : [ this._Range.endOffset ]\r
-               } ;\r
-               // Since we're treating the document tree as normalized, we need to backtrack the text lengths\r
-               // of previous text nodes into the offset value.\r
-               var curStart = this._Range.startContainer.previousSibling ;\r
-               var curEnd = this._Range.endContainer.previousSibling ;\r
-\r
-               // Also note that the node that we use for "address base" would change during backtracking.\r
-               var addrStart = this._Range.startContainer ;\r
-               var addrEnd = this._Range.endContainer ;\r
-               while ( curStart && curStart.nodeType == 3 && addrStart.nodeType == 3 )\r
-               {\r
-                       bookmark.Start[0] += curStart.length ;\r
-                       addrStart = curStart ;\r
-                       curStart = curStart.previousSibling ;\r
-               }\r
-               while ( curEnd && curEnd.nodeType == 3 && addrEnd.nodeType == 3 )\r
-               {\r
-                       bookmark.End[0] += curEnd.length ;\r
-                       addrEnd = curEnd ;\r
-                       curEnd = curEnd.previousSibling ;\r
-               }\r
-\r
-               // If the object pointed to by the startOffset and endOffset are text nodes, we need\r
-               // to backtrack and add in the text offset to the bookmark addresses.\r
-               if ( addrStart.nodeType == 1 && addrStart.childNodes[bookmark.Start[0]] && addrStart.childNodes[bookmark.Start[0]].nodeType == 3 )\r
-               {\r
-                       var curNode = addrStart.childNodes[bookmark.Start[0]] ;\r
-                       var offset = 0 ;\r
-                       while ( curNode.previousSibling && curNode.previousSibling.nodeType == 3 )\r
-                       {\r
-                               curNode = curNode.previousSibling ;\r
-                               offset += curNode.length ;\r
-                       }\r
-                       addrStart = curNode ;\r
-                       bookmark.Start[0] = offset ;\r
-               }\r
-               if ( addrEnd.nodeType == 1 && addrEnd.childNodes[bookmark.End[0]] && addrEnd.childNodes[bookmark.End[0]].nodeType == 3 )\r
-               {\r
-                       var curNode = addrEnd.childNodes[bookmark.End[0]] ;\r
-                       var offset = 0 ;\r
-                       while ( curNode.previousSibling && curNode.previousSibling.nodeType == 3 )\r
-                       {\r
-                               curNode = curNode.previousSibling ;\r
-                               offset += curNode.length ;\r
-                       }\r
-                       addrEnd = curNode ;\r
-                       bookmark.End[0] = offset ;\r
-               }\r
-\r
-               // Then, we record down the precise position of the container nodes\r
-               // by walking up the DOM tree and counting their childNode index\r
-               bookmark.Start = FCKDomTools.GetNodeAddress( addrStart, true ).concat( bookmark.Start ) ;\r
-               bookmark.End = FCKDomTools.GetNodeAddress( addrEnd, true ).concat( bookmark.End ) ;\r
-               return bookmark;\r
-       },\r
-\r
-       MoveToBookmark2 : function( bookmark )\r
-       {\r
-               // Reverse the childNode counting algorithm in CreateBookmark2()\r
-               var curStart = FCKDomTools.GetNodeFromAddress( this.Window.document, bookmark.Start.slice( 0, -1 ), true ) ;\r
-               var curEnd = FCKDomTools.GetNodeFromAddress( this.Window.document, bookmark.End.slice( 0, -1 ), true ) ;\r
-\r
-               // Generate the W3C Range object and update relevant data\r
-               this.Release( true ) ;\r
-               this._Range = new FCKW3CRange( this.Window.document ) ;\r
-               var startOffset = bookmark.Start[ bookmark.Start.length - 1 ] ;\r
-               var endOffset = bookmark.End[ bookmark.End.length - 1 ] ;\r
-               while ( curStart.nodeType == 3 && startOffset > curStart.length )\r
-               {\r
-                       if ( ! curStart.nextSibling || curStart.nextSibling.nodeType != 3 )\r
-                               break ;\r
-                       startOffset -= curStart.length ;\r
-                       curStart = curStart.nextSibling ;\r
-               }\r
-               while ( curEnd.nodeType == 3 && endOffset > curEnd.length )\r
-               {\r
-                       if ( ! curEnd.nextSibling || curEnd.nextSibling.nodeType != 3 )\r
-                               break ;\r
-                       endOffset -= curEnd.length ;\r
-                       curEnd = curEnd.nextSibling ;\r
-               }\r
-               this._Range.setStart( curStart, startOffset ) ;\r
-               this._Range.setEnd( curEnd, endOffset ) ;\r
-               this._UpdateElementInfo() ;\r
-       },\r
-\r
-       MoveToPosition : function( targetElement, position )\r
-       {\r
-               this.SetStart( targetElement, position ) ;\r
-               this.Collapse( true ) ;\r
-       },\r
-\r
-       /*\r
-        * Moves the position of the start boundary of the range to a specific position\r
-        * relatively to a element.\r
-        *              @position:\r
-        *                      1 = After Start         <target>^contents</target>\r
-        *                      2 = Before End          <target>contents^</target>\r
-        *                      3 = Before Start        ^<target>contents</target>\r
-        *                      4 = After End           <target>contents</target>^\r
-        */\r
-       SetStart : function( targetElement, position, noInfoUpdate )\r
-       {\r
-               var oRange = this._Range ;\r
-               if ( !oRange )\r
-                       oRange = this._Range = this.CreateRange() ;\r
-\r
-               switch( position )\r
-               {\r
-                       case 1 :                // After Start          <target>^contents</target>\r
-                               oRange.setStart( targetElement, 0 ) ;\r
-                               break ;\r
-\r
-                       case 2 :                // Before End           <target>contents^</target>\r
-                               oRange.setStart( targetElement, targetElement.childNodes.length ) ;\r
-                               break ;\r
-\r
-                       case 3 :                // Before Start         ^<target>contents</target>\r
-                               oRange.setStartBefore( targetElement ) ;\r
-                               break ;\r
-\r
-                       case 4 :                // After End            <target>contents</target>^\r
-                               oRange.setStartAfter( targetElement ) ;\r
-               }\r
-\r
-               if ( !noInfoUpdate )\r
-                       this._UpdateElementInfo() ;\r
-       },\r
-\r
-       /*\r
-        * Moves the position of the start boundary of the range to a specific position\r
-        * relatively to a element.\r
-        *              @position:\r
-        *                      1 = After Start         <target>^contents</target>\r
-        *                      2 = Before End          <target>contents^</target>\r
-        *                      3 = Before Start        ^<target>contents</target>\r
-        *                      4 = After End           <target>contents</target>^\r
-        */\r
-       SetEnd : function( targetElement, position, noInfoUpdate )\r
-       {\r
-               var oRange = this._Range ;\r
-               if ( !oRange )\r
-                       oRange = this._Range = this.CreateRange() ;\r
-\r
-               switch( position )\r
-               {\r
-                       case 1 :                // After Start          <target>^contents</target>\r
-                               oRange.setEnd( targetElement, 0 ) ;\r
-                               break ;\r
-\r
-                       case 2 :                // Before End           <target>contents^</target>\r
-                               oRange.setEnd( targetElement, targetElement.childNodes.length ) ;\r
-                               break ;\r
-\r
-                       case 3 :                // Before Start         ^<target>contents</target>\r
-                               oRange.setEndBefore( targetElement ) ;\r
-                               break ;\r
-\r
-                       case 4 :                // After End            <target>contents</target>^\r
-                               oRange.setEndAfter( targetElement ) ;\r
-               }\r
-\r
-               if ( !noInfoUpdate )\r
-                       this._UpdateElementInfo() ;\r
-       },\r
-\r
-       Expand : function( unit )\r
-       {\r
-               var oNode, oSibling ;\r
-\r
-               switch ( unit )\r
-               {\r
-                       // Expand the range to include all inline parent elements if we are\r
-                       // are in their boundary limits.\r
-                       // For example (where [ ] are the range limits):\r
-                       //      Before =>               Some <b>[<i>Some sample text]</i></b>.\r
-                       //      After =>                Some [<b><i>Some sample text</i></b>].\r
-                       case 'inline_elements' :\r
-                               // Expand the start boundary.\r
-                               if ( this._Range.startOffset == 0 )\r
-                               {\r
-                                       oNode = this._Range.startContainer ;\r
-\r
-                                       if ( oNode.nodeType != 1 )\r
-                                               oNode = oNode.previousSibling ? null : oNode.parentNode ;\r
-\r
-                                       if ( oNode )\r
-                                       {\r
-                                               while ( FCKListsLib.InlineNonEmptyElements[ oNode.nodeName.toLowerCase() ] )\r
-                                               {\r
-                                                       this._Range.setStartBefore( oNode ) ;\r
-\r
-                                                       if ( oNode != oNode.parentNode.firstChild )\r
-                                                               break ;\r
-\r
-                                                       oNode = oNode.parentNode ;\r
-                                               }\r
-                                       }\r
-                               }\r
-\r
-                               // Expand the end boundary.\r
-                               oNode = this._Range.endContainer ;\r
-                               var offset = this._Range.endOffset ;\r
-\r
-                               if ( ( oNode.nodeType == 3 && offset >= oNode.nodeValue.length ) || ( oNode.nodeType == 1 && offset >= oNode.childNodes.length ) || ( oNode.nodeType != 1 && oNode.nodeType != 3 ) )\r
-                               {\r
-                                       if ( oNode.nodeType != 1 )\r
-                                               oNode = oNode.nextSibling ? null : oNode.parentNode ;\r
-\r
-                                       if ( oNode )\r
-                                       {\r
-                                               while ( FCKListsLib.InlineNonEmptyElements[ oNode.nodeName.toLowerCase() ] )\r
-                                               {\r
-                                                       this._Range.setEndAfter( oNode ) ;\r
-\r
-                                                       if ( oNode != oNode.parentNode.lastChild )\r
-                                                               break ;\r
-\r
-                                                       oNode = oNode.parentNode ;\r
-                                               }\r
-                                       }\r
-                               }\r
-\r
-                               break ;\r
-\r
-                       case 'block_contents' :\r
-                       case 'list_contents' :\r
-                               var boundarySet = FCKListsLib.BlockBoundaries ;\r
-                               if ( unit == 'list_contents' || FCKConfig.EnterMode == 'br' )\r
-                                       boundarySet = FCKListsLib.ListBoundaries ;\r
-\r
-                               if ( this.StartBlock && FCKConfig.EnterMode != 'br' && unit == 'block_contents' )\r
-                                       this.SetStart( this.StartBlock, 1 ) ;\r
-                               else\r
-                               {\r
-                                       // Get the start node for the current range.\r
-                                       oNode = this._Range.startContainer ;\r
-\r
-                                       // If it is an element, get the node right before of it (in source order).\r
-                                       if ( oNode.nodeType == 1 )\r
-                                       {\r
-                                               var lastNode = oNode.childNodes[ this._Range.startOffset ] ;\r
-                                               if ( lastNode )\r
-                                                       oNode = FCKDomTools.GetPreviousSourceNode( lastNode, true ) ;\r
-                                               else\r
-                                                       oNode = oNode.lastChild || oNode ;\r
-                                       }\r
-\r
-                                       // We must look for the left boundary, relative to the range\r
-                                       // start, which is limited by a block element.\r
-                                       while ( oNode\r
-                                                       && ( oNode.nodeType != 1\r
-                                                               || ( oNode != this.StartBlockLimit\r
-                                                                       && !boundarySet[ oNode.nodeName.toLowerCase() ] ) ) )\r
-                                       {\r
-                                               this._Range.setStartBefore( oNode ) ;\r
-                                               oNode = oNode.previousSibling || oNode.parentNode ;\r
-                                       }\r
-                               }\r
-\r
-                               if ( this.EndBlock && FCKConfig.EnterMode != 'br' && unit == 'block_contents' && this.EndBlock.nodeName.toLowerCase() != 'li' )\r
-                                       this.SetEnd( this.EndBlock, 2 ) ;\r
-                               else\r
-                               {\r
-                                       oNode = this._Range.endContainer ;\r
-                                       if ( oNode.nodeType == 1 )\r
-                                               oNode = oNode.childNodes[ this._Range.endOffset ] || oNode.lastChild ;\r
-\r
-                                       // We must look for the right boundary, relative to the range\r
-                                       // end, which is limited by a block element.\r
-                                       while ( oNode\r
-                                                       && ( oNode.nodeType != 1\r
-                                                               || ( oNode != this.StartBlockLimit\r
-                                                                       && !boundarySet[ oNode.nodeName.toLowerCase() ] ) ) )\r
-                                       {\r
-                                               this._Range.setEndAfter( oNode ) ;\r
-                                               oNode = oNode.nextSibling || oNode.parentNode ;\r
-                                       }\r
-\r
-                                       // In EnterMode='br', the end <br> boundary element must\r
-                                       // be included in the expanded range.\r
-                                       if ( oNode && oNode.nodeName.toLowerCase() == 'br' )\r
-                                               this._Range.setEndAfter( oNode ) ;\r
-                               }\r
-\r
-                               this._UpdateElementInfo() ;\r
-               }\r
-       },\r
-\r
-       /**\r
-        * Split the block element for the current range. It deletes the contents\r
-        * of the range and splits the block in the collapsed position, resulting\r
-        * in two sucessive blocks. The range is then positioned in the middle of\r
-        * them.\r
-        *\r
-        * It returns and object with the following properties:\r
-        *              - PreviousBlock : a reference to the block element that preceeds\r
-        *                the range after the split.\r
-        *              - NextBlock : a reference to the block element that follows the\r
-        *                range after the split.\r
-        *              - WasStartOfBlock : a boolean indicating that the range was\r
-        *                originaly at the start of the block.\r
-        *              - WasEndOfBlock : a boolean indicating that the range was originaly\r
-        *                at the end of the block.\r
-        *\r
-        * If the range was originaly at the start of the block, no split will happen\r
-        * and the PreviousBlock value will be null. The same is valid for the\r
-        * NextBlock value if the range was at the end of the block.\r
-        */\r
-       SplitBlock : function( forceBlockTag )\r
-       {\r
-               var blockTag = forceBlockTag || FCKConfig.EnterMode ;\r
-\r
-               if ( !this._Range )\r
-                       this.MoveToSelection() ;\r
-\r
-               // The range boundaries must be in the same "block limit" element.\r
-               if ( this.StartBlockLimit == this.EndBlockLimit )\r
-               {\r
-                       // Get the current blocks.\r
-                       var eStartBlock         = this.StartBlock ;\r
-                       var eEndBlock           = this.EndBlock ;\r
-                       var oElementPath        = null ;\r
-\r
-                       if ( blockTag != 'br' )\r
-                       {\r
-                               if ( !eStartBlock )\r
-                               {\r
-                                       eStartBlock = this.FixBlock( true, blockTag ) ;\r
-                                       eEndBlock       = this.EndBlock ;       // FixBlock may have fixed the EndBlock too.\r
-                               }\r
-\r
-                               if ( !eEndBlock )\r
-                                       eEndBlock = this.FixBlock( false, blockTag ) ;\r
-                       }\r
-\r
-                       // Get the range position.\r
-                       var bIsStartOfBlock     = ( eStartBlock != null && this.CheckStartOfBlock() ) ;\r
-                       var bIsEndOfBlock       = ( eEndBlock != null && this.CheckEndOfBlock() ) ;\r
-\r
-                       // Delete the current contents.\r
-                       if ( !this.CheckIsEmpty() )\r
-                               this.DeleteContents() ;\r
-\r
-                       if ( eStartBlock && eEndBlock && eStartBlock == eEndBlock )\r
-                       {\r
-                               if ( bIsEndOfBlock )\r
-                               {\r
-                                       oElementPath = new FCKElementPath( this.StartContainer ) ;\r
-                                       this.MoveToPosition( eEndBlock, 4 ) ;\r
-                                       eEndBlock = null ;\r
-                               }\r
-                               else if ( bIsStartOfBlock )\r
-                               {\r
-                                       oElementPath = new FCKElementPath( this.StartContainer ) ;\r
-                                       this.MoveToPosition( eStartBlock, 3 ) ;\r
-                                       eStartBlock = null ;\r
-                               }\r
-                               else\r
-                               {\r
-                                       // Extract the contents of the block from the selection point to the end of its contents.\r
-                                       this.SetEnd( eStartBlock, 2 ) ;\r
-                                       var eDocFrag = this.ExtractContents() ;\r
-\r
-                                       // Duplicate the block element after it.\r
-                                       eEndBlock = eStartBlock.cloneNode( false ) ;\r
-                                       eEndBlock.removeAttribute( 'id', false ) ;\r
-\r
-                                       // Place the extracted contents in the duplicated block.\r
-                                       eDocFrag.AppendTo( eEndBlock ) ;\r
-\r
-                                       FCKDomTools.InsertAfterNode( eStartBlock, eEndBlock ) ;\r
-\r
-                                       this.MoveToPosition( eStartBlock, 4 ) ;\r
-\r
-                                       // In Gecko, the last child node must be a bogus <br>.\r
-                                       // Note: bogus <br> added under <ul> or <ol> would cause lists to be incorrectly rendered.\r
-                                       if ( FCKBrowserInfo.IsGecko &&\r
-                                                       ! eStartBlock.nodeName.IEquals( ['ul', 'ol'] ) )\r
-                                               FCKTools.AppendBogusBr( eStartBlock ) ;\r
-                               }\r
-                       }\r
-\r
-                       return {\r
-                               PreviousBlock   : eStartBlock,\r
-                               NextBlock               : eEndBlock,\r
-                               WasStartOfBlock : bIsStartOfBlock,\r
-                               WasEndOfBlock   : bIsEndOfBlock,\r
-                               ElementPath             : oElementPath\r
-                       } ;\r
-               }\r
-\r
-               return null ;\r
-       },\r
-\r
-       // Transform a block without a block tag in a valid block (orphan text in the body or td, usually).\r
-       FixBlock : function( isStart, blockTag )\r
-       {\r
-               // Bookmark the range so we can restore it later.\r
-               var oBookmark = this.CreateBookmark() ;\r
-\r
-               // Collapse the range to the requested ending boundary.\r
-               this.Collapse( isStart ) ;\r
-\r
-               // Expands it to the block contents.\r
-               this.Expand( 'block_contents' ) ;\r
-\r
-               // Create the fixed block.\r
-               var oFixedBlock = this.Window.document.createElement( blockTag ) ;\r
-\r
-               // Move the contents of the temporary range to the fixed block.\r
-               this.ExtractContents().AppendTo( oFixedBlock ) ;\r
-               FCKDomTools.TrimNode( oFixedBlock ) ;\r
-\r
-               // If the fixed block is empty (not counting bookmark nodes)\r
-               // Add a <br /> inside to expand it.\r
-               if ( FCKDomTools.CheckIsEmptyElement(oFixedBlock, function( element ) { return element.getAttribute('_fck_bookmark') != 'true' ; } )\r
-                               && FCKBrowserInfo.IsGeckoLike )\r
-                               FCKTools.AppendBogusBr( oFixedBlock ) ;\r
-\r
-               // Insert the fixed block into the DOM.\r
-               this.InsertNode( oFixedBlock ) ;\r
-\r
-               // Move the range back to the bookmarked place.\r
-               this.MoveToBookmark( oBookmark ) ;\r
-\r
-               return oFixedBlock ;\r
-       },\r
-\r
-       Release : function( preserveWindow )\r
-       {\r
-               if ( !preserveWindow )\r
-                       this.Window = null ;\r
-\r
-               this.StartNode = null ;\r
-               this.StartContainer = null ;\r
-               this.StartBlock = null ;\r
-               this.StartBlockLimit = null ;\r
-               this.EndNode = null ;\r
-               this.EndContainer = null ;\r
-               this.EndBlock = null ;\r
-               this.EndBlockLimit = null ;\r
-               this._Range = null ;\r
-               this._Cache = null ;\r
-       },\r
-\r
-       CheckHasRange : function()\r
-       {\r
-               return !!this._Range ;\r
-       },\r
-\r
-       GetTouchedStartNode : function()\r
-       {\r
-               var range = this._Range ;\r
-               var container = range.startContainer ;\r
-\r
-               if ( range.collapsed || container.nodeType != 1 )\r
-                       return container ;\r
-\r
-               return container.childNodes[ range.startOffset ] || container ;\r
-       },\r
-\r
-       GetTouchedEndNode : function()\r
-       {\r
-               var range = this._Range ;\r
-               var container = range.endContainer ;\r
-\r
-               if ( range.collapsed || container.nodeType != 1 )\r
-                       return container ;\r
-\r
-               return container.childNodes[ range.endOffset - 1 ] || container ;\r
-       }\r
-} ;\r