import rt 3.8.7
[freeside.git] / rt / share / html / NoAuth / RichText / FCKeditor / editor / _source / classes / fckdomrange_ie.js
diff --git a/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/classes/fckdomrange_ie.js b/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/classes/fckdomrange_ie.js
new file mode 100644 (file)
index 0000000..0773afd
--- /dev/null
@@ -0,0 +1,199 @@
+/*\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
+ * (IE Implementation)\r
+ */\r
+\r
+FCKDomRange.prototype.MoveToSelection = function()\r
+{\r
+       this.Release( true ) ;\r
+\r
+       this._Range = new FCKW3CRange( this.Window.document ) ;\r
+\r
+       var oSel = this.Window.document.selection ;\r
+\r
+       if ( oSel.type != 'Control' )\r
+       {\r
+               var eMarkerStart        = this._GetSelectionMarkerTag( true ) ;\r
+               var eMarkerEnd          = this._GetSelectionMarkerTag( false ) ;\r
+\r
+               if ( !eMarkerStart && !eMarkerEnd )\r
+               {\r
+                       this._Range.setStart( this.Window.document.body, 0 ) ;\r
+                       this._UpdateElementInfo() ;\r
+                       return ;\r
+               }\r
+\r
+               // Set the start boundary.\r
+               this._Range.setStart( eMarkerStart.parentNode, FCKDomTools.GetIndexOf( eMarkerStart ) ) ;\r
+               eMarkerStart.parentNode.removeChild( eMarkerStart ) ;\r
+\r
+               // Set the end boundary.\r
+               this._Range.setEnd( eMarkerEnd.parentNode, FCKDomTools.GetIndexOf( eMarkerEnd ) ) ;\r
+               eMarkerEnd.parentNode.removeChild( eMarkerEnd ) ;\r
+\r
+               this._UpdateElementInfo() ;\r
+       }\r
+       else\r
+       {\r
+               var oControl = oSel.createRange().item(0) ;\r
+\r
+               if ( oControl )\r
+               {\r
+                       this._Range.setStartBefore( oControl ) ;\r
+                       this._Range.setEndAfter( oControl ) ;\r
+                       this._UpdateElementInfo() ;\r
+               }\r
+       }\r
+}\r
+\r
+FCKDomRange.prototype.Select = function( forceExpand )\r
+{\r
+       if ( this._Range )\r
+               this.SelectBookmark( this.CreateBookmark( true ), forceExpand ) ;\r
+}\r
+\r
+// Not compatible with bookmark created with CreateBookmark2.\r
+// The bookmark nodes will be deleted from the document.\r
+FCKDomRange.prototype.SelectBookmark = function( bookmark, forceExpand )\r
+{\r
+       var bIsCollapsed = this.CheckIsCollapsed() ;\r
+       var bIsStartMakerAlone ;\r
+       var dummySpan ;\r
+\r
+       // Create marker tags for the start and end boundaries.\r
+       var eStartMarker = this.GetBookmarkNode( bookmark, true ) ;\r
+\r
+       if ( !eStartMarker )\r
+               return ;\r
+\r
+       var eEndMarker ;\r
+       if ( !bIsCollapsed )\r
+               eEndMarker = this.GetBookmarkNode( bookmark, false ) ;\r
+\r
+       // Create the main range which will be used for the selection.\r
+       var oIERange = this.Window.document.body.createTextRange() ;\r
+\r
+       // Position the range at the start boundary.\r
+       oIERange.moveToElementText( eStartMarker ) ;\r
+       oIERange.moveStart( 'character', 1 ) ;\r
+\r
+       if ( eEndMarker )\r
+       {\r
+               // Create a tool range for the end.\r
+               var oIERangeEnd = this.Window.document.body.createTextRange() ;\r
+\r
+               // Position the tool range at the end.\r
+               oIERangeEnd.moveToElementText( eEndMarker ) ;\r
+\r
+               // Move the end boundary of the main range to match the tool range.\r
+               oIERange.setEndPoint( 'EndToEnd', oIERangeEnd ) ;\r
+               oIERange.moveEnd( 'character', -1 ) ;\r
+       }\r
+       else\r
+       {\r
+               bIsStartMakerAlone = ( forceExpand || !eStartMarker.previousSibling || eStartMarker.previousSibling.nodeName.toLowerCase() == 'br' ) && !eStartMarker.nextSibing ;\r
+\r
+               // Append a temporary <span>&#65279;</span> before the selection.\r
+               // This is needed to avoid IE destroying selections inside empty\r
+               // inline elements, like <b></b> (#253).\r
+               // It is also needed when placing the selection right after an inline\r
+               // element to avoid the selection moving inside of it.\r
+               dummySpan = this.Window.document.createElement( 'span' ) ;\r
+               dummySpan.innerHTML = '&#65279;' ;      // Zero Width No-Break Space (U+FEFF). See #1359.\r
+               eStartMarker.parentNode.insertBefore( dummySpan, eStartMarker ) ;\r
+\r
+               if ( bIsStartMakerAlone )\r
+               {\r
+                       // To expand empty blocks or line spaces after <br>, we need\r
+                       // instead to have any char, which will be later deleted using the\r
+                       // selection.\r
+                       // \ufeff = Zero Width No-Break Space (U+FEFF). See #1359.\r
+                       eStartMarker.parentNode.insertBefore( this.Window.document.createTextNode( '\ufeff' ), eStartMarker ) ;\r
+               }\r
+       }\r
+\r
+       if ( !this._Range )\r
+               this._Range = this.CreateRange() ;\r
+\r
+       // Remove the markers (reset the position, because of the changes in the DOM tree).\r
+       this._Range.setStartBefore( eStartMarker ) ;\r
+       eStartMarker.parentNode.removeChild( eStartMarker ) ;\r
+\r
+       if ( bIsCollapsed )\r
+       {\r
+               if ( bIsStartMakerAlone )\r
+               {\r
+                       // Move the selection start to include the temporary &#65279;.\r
+                       oIERange.moveStart( 'character', -1 ) ;\r
+\r
+                       oIERange.select() ;\r
+\r
+                       // Remove our temporary stuff.\r
+                       this.Window.document.selection.clear() ;\r
+               }\r
+               else\r
+                       oIERange.select() ;\r
+\r
+               FCKDomTools.RemoveNode( dummySpan ) ;\r
+       }\r
+       else\r
+       {\r
+               this._Range.setEndBefore( eEndMarker ) ;\r
+               eEndMarker.parentNode.removeChild( eEndMarker ) ;\r
+               oIERange.select() ;\r
+       }\r
+}\r
+\r
+FCKDomRange.prototype._GetSelectionMarkerTag = function( toStart )\r
+{\r
+       var doc = this.Window.document ;\r
+       var selection = doc.selection ;\r
+\r
+       // Get a range for the start boundary.\r
+       var oRange ;\r
+\r
+       // IE may throw an "unspecified error" on some cases (it happened when\r
+       // loading _samples/default.html), so try/catch.\r
+       try\r
+       {\r
+               oRange = selection.createRange() ;\r
+       }\r
+       catch (e)\r
+       {\r
+               return null ;\r
+       }\r
+\r
+       // IE might take the range object to the main window instead of inside the editor iframe window.\r
+       // This is known to happen when the editor window has not been selected before (See #933).\r
+       // We need to avoid that.\r
+       if ( oRange.parentElement().document != doc )\r
+               return null ;\r
+\r
+       oRange.collapse( toStart === true ) ;\r
+\r
+       // Paste a marker element at the collapsed range and get it from the DOM.\r
+       var sMarkerId = 'fck_dom_range_temp_' + (new Date()).valueOf() + '_' + Math.floor(Math.random()*1000) ;\r
+       oRange.pasteHTML( '<span id="' + sMarkerId + '"></span>' ) ;\r
+\r
+       return doc.getElementById( sMarkerId ) ;\r
+}\r