--- /dev/null
+/*\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
+ * Active selection functions. (Gecko specific implementation)\r
+ */\r
+\r
+// Get the selection type (like document.select.type in IE).\r
+FCKSelection.GetType = function()\r
+{\r
+ // By default set the type to "Text".\r
+ var type = 'Text' ;\r
+\r
+ // Check if the actual selection is a Control (IMG, TABLE, HR, etc...).\r
+\r
+ var sel ;\r
+ try { sel = this.GetSelection() ; } catch (e) {}\r
+\r
+ if ( sel && sel.rangeCount == 1 )\r
+ {\r
+ var range = sel.getRangeAt(0) ;\r
+ if ( range.startContainer == range.endContainer\r
+ && ( range.endOffset - range.startOffset ) == 1\r
+ && range.startContainer.nodeType == 1\r
+ && FCKListsLib.StyleObjectElements[ range.startContainer.childNodes[ range.startOffset ].nodeName.toLowerCase() ] )\r
+ {\r
+ type = 'Control' ;\r
+ }\r
+ }\r
+\r
+ return type ;\r
+}\r
+\r
+// Retrieves the selected element (if any), just in the case that a single\r
+// element (object like and image or a table) is selected.\r
+FCKSelection.GetSelectedElement = function()\r
+{\r
+ var selection = !!FCK.EditorWindow && this.GetSelection() ;\r
+ if ( !selection || selection.rangeCount < 1 )\r
+ return null ;\r
+\r
+ var range = selection.getRangeAt( 0 ) ;\r
+ if ( range.startContainer != range.endContainer || range.startContainer.nodeType != 1 || range.startOffset != range.endOffset - 1 )\r
+ return null ;\r
+\r
+ var node = range.startContainer.childNodes[ range.startOffset ] ;\r
+ if ( node.nodeType != 1 )\r
+ return null ;\r
+\r
+ return node ;\r
+}\r
+\r
+FCKSelection.GetParentElement = function()\r
+{\r
+ if ( this.GetType() == 'Control' )\r
+ return FCKSelection.GetSelectedElement().parentNode ;\r
+ else\r
+ {\r
+ var oSel = this.GetSelection() ;\r
+ if ( oSel )\r
+ {\r
+ // if anchorNode == focusNode, see if the selection is text only or including nodes.\r
+ // if text only, return the parent node.\r
+ // if the selection includes DOM nodes, then the anchorNode is the nearest container.\r
+ if ( oSel.anchorNode && oSel.anchorNode == oSel.focusNode )\r
+ {\r
+ var oRange = oSel.getRangeAt( 0 ) ;\r
+ if ( oRange.collapsed || oRange.startContainer.nodeType == 3 )\r
+ return oSel.anchorNode.parentNode ;\r
+ else\r
+ return oSel.anchorNode ;\r
+ }\r
+\r
+ // looks like we're having a large selection here. To make the behavior same as IE's TextRange.parentElement(),\r
+ // we need to find the nearest ancestor node which encapsulates both the beginning and the end of the selection.\r
+ // TODO: A simpler logic can be found.\r
+ var anchorPath = new FCKElementPath( oSel.anchorNode ) ;\r
+ var focusPath = new FCKElementPath( oSel.focusNode ) ;\r
+ var deepPath = null ;\r
+ var shallowPath = null ;\r
+ if ( anchorPath.Elements.length > focusPath.Elements.length )\r
+ {\r
+ deepPath = anchorPath.Elements ;\r
+ shallowPath = focusPath.Elements ;\r
+ }\r
+ else\r
+ {\r
+ deepPath = focusPath.Elements ;\r
+ shallowPath = anchorPath.Elements ;\r
+ }\r
+\r
+ var deepPathBase = deepPath.length - shallowPath.length ;\r
+ for( var i = 0 ; i < shallowPath.length ; i++)\r
+ {\r
+ if ( deepPath[deepPathBase + i] == shallowPath[i])\r
+ return shallowPath[i];\r
+ }\r
+ return null ;\r
+ }\r
+ }\r
+ return null ;\r
+}\r
+\r
+FCKSelection.GetBoundaryParentElement = function( startBoundary )\r
+{\r
+ if ( ! FCK.EditorWindow )\r
+ return null ;\r
+ if ( this.GetType() == 'Control' )\r
+ return FCKSelection.GetSelectedElement().parentNode ;\r
+ else\r
+ {\r
+ var oSel = this.GetSelection() ;\r
+ if ( oSel && oSel.rangeCount > 0 )\r
+ {\r
+ var range = oSel.getRangeAt( startBoundary ? 0 : ( oSel.rangeCount - 1 ) ) ;\r
+\r
+ var element = startBoundary ? range.startContainer : range.endContainer ;\r
+\r
+ return ( element.nodeType == 1 ? element : element.parentNode ) ;\r
+ }\r
+ }\r
+ return null ;\r
+}\r
+\r
+FCKSelection.SelectNode = function( element )\r
+{\r
+ var oRange = FCK.EditorDocument.createRange() ;\r
+ oRange.selectNode( element ) ;\r
+\r
+ var oSel = this.GetSelection() ;\r
+ oSel.removeAllRanges() ;\r
+ oSel.addRange( oRange ) ;\r
+}\r
+\r
+FCKSelection.Collapse = function( toStart )\r
+{\r
+ var oSel = this.GetSelection() ;\r
+\r
+ if ( toStart == null || toStart === true )\r
+ oSel.collapseToStart() ;\r
+ else\r
+ oSel.collapseToEnd() ;\r
+}\r
+\r
+// The "nodeTagName" parameter must be Upper Case.\r
+FCKSelection.HasAncestorNode = function( nodeTagName )\r
+{\r
+ var oContainer = this.GetSelectedElement() ;\r
+ if ( ! oContainer && FCK.EditorWindow )\r
+ {\r
+ try { oContainer = this.GetSelection().getRangeAt(0).startContainer ; }\r
+ catch(e){}\r
+ }\r
+\r
+ while ( oContainer )\r
+ {\r
+ if ( oContainer.nodeType == 1 && oContainer.nodeName.IEquals( nodeTagName ) ) return true ;\r
+ oContainer = oContainer.parentNode ;\r
+ }\r
+\r
+ return false ;\r
+}\r
+\r
+// The "nodeTagName" parameter must be Upper Case.\r
+FCKSelection.MoveToAncestorNode = function( nodeTagName )\r
+{\r
+ var oNode ;\r
+\r
+ var oContainer = this.GetSelectedElement() ;\r
+ if ( ! oContainer )\r
+ oContainer = this.GetSelection().getRangeAt(0).startContainer ;\r
+\r
+ while ( oContainer )\r
+ {\r
+ if ( oContainer.nodeName.IEquals( nodeTagName ) )\r
+ return oContainer ;\r
+\r
+ oContainer = oContainer.parentNode ;\r
+ }\r
+ return null ;\r
+}\r
+\r
+FCKSelection.Delete = function()\r
+{\r
+ // Gets the actual selection.\r
+ var oSel = this.GetSelection() ;\r
+\r
+ // Deletes the actual selection contents.\r
+ for ( var i = 0 ; i < oSel.rangeCount ; i++ )\r
+ {\r
+ oSel.getRangeAt(i).deleteContents() ;\r
+ }\r
+\r
+ return oSel ;\r
+}\r
+\r
+/**\r
+ * Returns the native selection object.\r
+ */\r
+FCKSelection.GetSelection = function()\r
+{\r
+ return FCK.EditorWindow.getSelection() ;\r
+}\r
+\r
+// The following are IE only features (we don't need then in other browsers\r
+// currently).\r
+FCKSelection.Save = function()\r
+{}\r
+FCKSelection.Restore = function()\r
+{}\r
+FCKSelection.Release = function()\r
+{}\r