summaryrefslogtreecommitdiff
path: root/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses
diff options
context:
space:
mode:
Diffstat (limited to 'rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses')
-rw-r--r--rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fck_othercommands.js634
-rw-r--r--rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckblockquotecommand.js281
-rw-r--r--rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckcorestylecommand.js61
-rw-r--r--rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckfitwindow.js213
-rw-r--r--rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckindentcommands.js282
-rw-r--r--rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckjustifycommands.js173
-rw-r--r--rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fcklistcommands.js382
-rw-r--r--rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fcknamedcommand.js39
-rw-r--r--rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckpasteplaintextcommand.js40
-rw-r--r--rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckpastewordcommand.js40
-rw-r--r--rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckremoveformatcommand.js45
-rw-r--r--rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckshowblocks.js94
-rw-r--r--rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckspellcheckcommand_gecko.js49
-rw-r--r--rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckspellcheckcommand_ie.js72
-rw-r--r--rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckstylecommand.js60
-rw-r--r--rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fcktablecommand.js106
-rw-r--r--rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fcktextcolorcommand.js201
17 files changed, 2772 insertions, 0 deletions
diff --git a/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fck_othercommands.js b/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fck_othercommands.js
new file mode 100644
index 0000000..ac26085
--- /dev/null
+++ b/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fck_othercommands.js
@@ -0,0 +1,634 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2009 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ * - GNU General Public License Version 2 or later (the "GPL")
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ * - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * - Mozilla Public License Version 1.1 or later (the "MPL")
+ * http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Definition of other commands that are not available internaly in the
+ * browser (see FCKNamedCommand).
+ */
+
+// ### General Dialog Box Commands.
+var FCKDialogCommand = function( name, title, url, width, height, getStateFunction, getStateParam, customValue )
+{
+ this.Name = name ;
+ this.Title = title ;
+ this.Url = url ;
+ this.Width = width ;
+ this.Height = height ;
+ this.CustomValue = customValue ;
+
+ this.GetStateFunction = getStateFunction ;
+ this.GetStateParam = getStateParam ;
+
+ this.Resizable = false ;
+}
+
+FCKDialogCommand.prototype.Execute = function()
+{
+ FCKDialog.OpenDialog( 'FCKDialog_' + this.Name , this.Title, this.Url, this.Width, this.Height, this.CustomValue, null, this.Resizable ) ;
+}
+
+FCKDialogCommand.prototype.GetState = function()
+{
+ if ( this.GetStateFunction )
+ return this.GetStateFunction( this.GetStateParam ) ;
+ else
+ return FCK.EditMode == FCK_EDITMODE_WYSIWYG ? FCK_TRISTATE_OFF : FCK_TRISTATE_DISABLED ;
+}
+
+// Generic Undefined command (usually used when a command is under development).
+var FCKUndefinedCommand = function()
+{
+ this.Name = 'Undefined' ;
+}
+
+FCKUndefinedCommand.prototype.Execute = function()
+{
+ alert( FCKLang.NotImplemented ) ;
+}
+
+FCKUndefinedCommand.prototype.GetState = function()
+{
+ return FCK_TRISTATE_OFF ;
+}
+
+
+// ### FormatBlock
+var FCKFormatBlockCommand = function()
+{}
+
+FCKFormatBlockCommand.prototype =
+{
+ Name : 'FormatBlock',
+
+ Execute : FCKStyleCommand.prototype.Execute,
+
+ GetState : function()
+ {
+ return FCK.EditorDocument ? FCK_TRISTATE_OFF : FCK_TRISTATE_DISABLED ;
+ }
+};
+
+// ### FontName
+
+var FCKFontNameCommand = function()
+{}
+
+FCKFontNameCommand.prototype =
+{
+ Name : 'FontName',
+ Execute : FCKStyleCommand.prototype.Execute,
+ GetState : FCKFormatBlockCommand.prototype.GetState
+};
+
+// ### FontSize
+var FCKFontSizeCommand = function()
+{}
+
+FCKFontSizeCommand.prototype =
+{
+ Name : 'FontSize',
+ Execute : FCKStyleCommand.prototype.Execute,
+ GetState : FCKFormatBlockCommand.prototype.GetState
+};
+
+// ### Preview
+var FCKPreviewCommand = function()
+{
+ this.Name = 'Preview' ;
+}
+
+FCKPreviewCommand.prototype.Execute = function()
+{
+ FCK.Preview() ;
+}
+
+FCKPreviewCommand.prototype.GetState = function()
+{
+ return FCK_TRISTATE_OFF ;
+}
+
+// ### Save
+var FCKSaveCommand = function()
+{
+ this.Name = 'Save' ;
+}
+
+FCKSaveCommand.prototype.Execute = function()
+{
+ // Get the linked field form.
+ var oForm = FCK.GetParentForm() ;
+
+ if ( typeof( oForm.onsubmit ) == 'function' )
+ {
+ var bRet = oForm.onsubmit() ;
+ if ( bRet != null && bRet === false )
+ return ;
+ }
+
+ // Submit the form.
+ // If there's a button named "submit" then the form.submit() function is masked and
+ // can't be called in Mozilla, so we call the click() method of that button.
+ if ( typeof( oForm.submit ) == 'function' )
+ oForm.submit() ;
+ else
+ oForm.submit.click() ;
+}
+
+FCKSaveCommand.prototype.GetState = function()
+{
+ return FCK_TRISTATE_OFF ;
+}
+
+// ### NewPage
+var FCKNewPageCommand = function()
+{
+ this.Name = 'NewPage' ;
+}
+
+FCKNewPageCommand.prototype.Execute = function()
+{
+ FCKUndo.SaveUndoStep() ;
+ FCK.SetData( '' ) ;
+ FCKUndo.Typing = true ;
+ FCK.Focus() ;
+}
+
+FCKNewPageCommand.prototype.GetState = function()
+{
+ return FCK_TRISTATE_OFF ;
+}
+
+// ### Source button
+var FCKSourceCommand = function()
+{
+ this.Name = 'Source' ;
+}
+
+FCKSourceCommand.prototype.Execute = function()
+{
+ if ( FCKConfig.SourcePopup ) // Until v2.2, it was mandatory for FCKBrowserInfo.IsGecko.
+ {
+ var iWidth = FCKConfig.ScreenWidth * 0.65 ;
+ var iHeight = FCKConfig.ScreenHeight * 0.65 ;
+ FCKDialog.OpenDialog( 'FCKDialog_Source', FCKLang.Source, 'dialog/fck_source.html', iWidth, iHeight, null, null, true ) ;
+ }
+ else
+ FCK.SwitchEditMode() ;
+}
+
+FCKSourceCommand.prototype.GetState = function()
+{
+ return ( FCK.EditMode == FCK_EDITMODE_WYSIWYG ? FCK_TRISTATE_OFF : FCK_TRISTATE_ON ) ;
+}
+
+// ### Undo
+var FCKUndoCommand = function()
+{
+ this.Name = 'Undo' ;
+}
+
+FCKUndoCommand.prototype.Execute = function()
+{
+ FCKUndo.Undo() ;
+}
+
+FCKUndoCommand.prototype.GetState = function()
+{
+ if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
+ return FCK_TRISTATE_DISABLED ;
+ return ( FCKUndo.CheckUndoState() ? FCK_TRISTATE_OFF : FCK_TRISTATE_DISABLED ) ;
+}
+
+// ### Redo
+var FCKRedoCommand = function()
+{
+ this.Name = 'Redo' ;
+}
+
+FCKRedoCommand.prototype.Execute = function()
+{
+ FCKUndo.Redo() ;
+}
+
+FCKRedoCommand.prototype.GetState = function()
+{
+ if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
+ return FCK_TRISTATE_DISABLED ;
+ return ( FCKUndo.CheckRedoState() ? FCK_TRISTATE_OFF : FCK_TRISTATE_DISABLED ) ;
+}
+
+// ### Page Break
+var FCKPageBreakCommand = function()
+{
+ this.Name = 'PageBreak' ;
+}
+
+FCKPageBreakCommand.prototype.Execute = function()
+{
+ // Take an undo snapshot before changing the document
+ FCKUndo.SaveUndoStep() ;
+
+// var e = FCK.EditorDocument.createElement( 'CENTER' ) ;
+// e.style.pageBreakAfter = 'always' ;
+
+ // Tidy was removing the empty CENTER tags, so the following solution has
+ // been found. It also validates correctly as XHTML 1.0 Strict.
+ var e = FCK.EditorDocument.createElement( 'DIV' ) ;
+ e.style.pageBreakAfter = 'always' ;
+ e.innerHTML = '<span style="DISPLAY:none">&nbsp;</span>' ;
+
+ var oFakeImage = FCKDocumentProcessor_CreateFakeImage( 'FCK__PageBreak', e ) ;
+ var oRange = new FCKDomRange( FCK.EditorWindow ) ;
+ oRange.MoveToSelection() ;
+ var oSplitInfo = oRange.SplitBlock() ;
+ oRange.InsertNode( oFakeImage ) ;
+
+ FCK.Events.FireEvent( 'OnSelectionChange' ) ;
+}
+
+FCKPageBreakCommand.prototype.GetState = function()
+{
+ if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
+ return FCK_TRISTATE_DISABLED ;
+ return 0 ; // FCK_TRISTATE_OFF
+}
+
+// FCKUnlinkCommand - by Johnny Egeland (johnny@coretrek.com)
+var FCKUnlinkCommand = function()
+{
+ this.Name = 'Unlink' ;
+}
+
+FCKUnlinkCommand.prototype.Execute = function()
+{
+ // Take an undo snapshot before changing the document
+ FCKUndo.SaveUndoStep() ;
+
+ if ( FCKBrowserInfo.IsGeckoLike )
+ {
+ var oLink = FCK.Selection.MoveToAncestorNode( 'A' ) ;
+ // The unlink command can generate a span in Firefox, so let's do it our way. See #430
+ if ( oLink )
+ FCKTools.RemoveOuterTags( oLink ) ;
+
+ return ;
+ }
+
+ FCK.ExecuteNamedCommand( this.Name ) ;
+}
+
+FCKUnlinkCommand.prototype.GetState = function()
+{
+ if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
+ return FCK_TRISTATE_DISABLED ;
+ var state = FCK.GetNamedCommandState( this.Name ) ;
+
+ // Check that it isn't an anchor
+ if ( state == FCK_TRISTATE_OFF && FCK.EditMode == FCK_EDITMODE_WYSIWYG )
+ {
+ var oLink = FCKSelection.MoveToAncestorNode( 'A' ) ;
+ var bIsAnchor = ( oLink && oLink.name.length > 0 && oLink.href.length == 0 ) ;
+ if ( bIsAnchor )
+ state = FCK_TRISTATE_DISABLED ;
+ }
+
+ return state ;
+}
+
+var FCKVisitLinkCommand = function()
+{
+ this.Name = 'VisitLink';
+}
+FCKVisitLinkCommand.prototype =
+{
+ GetState : function()
+ {
+ if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
+ return FCK_TRISTATE_DISABLED ;
+ var state = FCK.GetNamedCommandState( 'Unlink' ) ;
+
+ if ( state == FCK_TRISTATE_OFF )
+ {
+ var el = FCKSelection.MoveToAncestorNode( 'A' ) ;
+ if ( !el.href )
+ state = FCK_TRISTATE_DISABLED ;
+ }
+
+ return state ;
+ },
+
+ Execute : function()
+ {
+ var el = FCKSelection.MoveToAncestorNode( 'A' ) ;
+ var url = el.getAttribute( '_fcksavedurl' ) || el.getAttribute( 'href', 2 ) ;
+
+ // Check if it's a full URL.
+ // If not full URL, we'll need to apply the BaseHref setting.
+ if ( ! /:\/\//.test( url ) )
+ {
+ var baseHref = FCKConfig.BaseHref ;
+ var parentWindow = FCK.GetInstanceObject( 'parent' ) ;
+ if ( !baseHref )
+ {
+ baseHref = parentWindow.document.location.href ;
+ baseHref = baseHref.substring( 0, baseHref.lastIndexOf( '/' ) + 1 ) ;
+ }
+
+ if ( /^\//.test( url ) )
+ {
+ try
+ {
+ baseHref = baseHref.match( /^.*:\/\/+[^\/]+/ )[0] ;
+ }
+ catch ( e )
+ {
+ baseHref = parentWindow.document.location.protocol + '://' + parentWindow.parent.document.location.host ;
+ }
+ }
+
+ url = baseHref + url ;
+ }
+
+ if ( !window.open( url, '_blank' ) )
+ alert( FCKLang.VisitLinkBlocked ) ;
+ }
+} ;
+
+// FCKSelectAllCommand
+var FCKSelectAllCommand = function()
+{
+ this.Name = 'SelectAll' ;
+}
+
+FCKSelectAllCommand.prototype.Execute = function()
+{
+ if ( FCK.EditMode == FCK_EDITMODE_WYSIWYG )
+ {
+ FCK.ExecuteNamedCommand( 'SelectAll' ) ;
+ }
+ else
+ {
+ // Select the contents of the textarea
+ var textarea = FCK.EditingArea.Textarea ;
+ if ( FCKBrowserInfo.IsIE )
+ {
+ textarea.createTextRange().execCommand( 'SelectAll' ) ;
+ }
+ else
+ {
+ textarea.selectionStart = 0 ;
+ textarea.selectionEnd = textarea.value.length ;
+ }
+ textarea.focus() ;
+ }
+}
+
+FCKSelectAllCommand.prototype.GetState = function()
+{
+ if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
+ return FCK_TRISTATE_DISABLED ;
+ return FCK_TRISTATE_OFF ;
+}
+
+// FCKPasteCommand
+var FCKPasteCommand = function()
+{
+ this.Name = 'Paste' ;
+}
+
+FCKPasteCommand.prototype =
+{
+ Execute : function()
+ {
+ if ( FCKBrowserInfo.IsIE )
+ FCK.Paste() ;
+ else
+ FCK.ExecuteNamedCommand( 'Paste' ) ;
+ },
+
+ GetState : function()
+ {
+ if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
+ return FCK_TRISTATE_DISABLED ;
+ return FCK.GetNamedCommandState( 'Paste' ) ;
+ }
+} ;
+
+// FCKRuleCommand
+var FCKRuleCommand = function()
+{
+ this.Name = 'Rule' ;
+}
+
+FCKRuleCommand.prototype =
+{
+ Execute : function()
+ {
+ FCKUndo.SaveUndoStep() ;
+ FCK.InsertElement( 'hr' ) ;
+ },
+
+ GetState : function()
+ {
+ if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
+ return FCK_TRISTATE_DISABLED ;
+ return FCK.GetNamedCommandState( 'InsertHorizontalRule' ) ;
+ }
+} ;
+
+// FCKCutCopyCommand
+var FCKCutCopyCommand = function( isCut )
+{
+ this.Name = isCut ? 'Cut' : 'Copy' ;
+}
+
+FCKCutCopyCommand.prototype =
+{
+ Execute : function()
+ {
+ var enabled = false ;
+
+ if ( FCKBrowserInfo.IsIE )
+ {
+ // The following seems to be the only reliable way to detect that
+ // cut/copy is enabled in IE. It will fire the oncut/oncopy event
+ // only if the security settings enabled the command to execute.
+
+ var onEvent = function()
+ {
+ enabled = true ;
+ } ;
+
+ var eventName = 'on' + this.Name.toLowerCase() ;
+
+ FCK.EditorDocument.body.attachEvent( eventName, onEvent ) ;
+ FCK.ExecuteNamedCommand( this.Name ) ;
+ FCK.EditorDocument.body.detachEvent( eventName, onEvent ) ;
+ }
+ else
+ {
+ try
+ {
+ // Other browsers throw an error if the command is disabled.
+ FCK.ExecuteNamedCommand( this.Name ) ;
+ enabled = true ;
+ }
+ catch(e){}
+ }
+
+ if ( !enabled )
+ alert( FCKLang[ 'PasteError' + this.Name ] ) ;
+ },
+
+ GetState : function()
+ {
+ // Strangely, the Cut command happens to have the correct states for
+ // both Copy and Cut in all browsers.
+ return FCK.EditMode != FCK_EDITMODE_WYSIWYG ?
+ FCK_TRISTATE_DISABLED :
+ FCK.GetNamedCommandState( 'Cut' ) ;
+ }
+};
+
+var FCKAnchorDeleteCommand = function()
+{
+ this.Name = 'AnchorDelete' ;
+}
+
+FCKAnchorDeleteCommand.prototype =
+{
+ Execute : function()
+ {
+ if (FCK.Selection.GetType() == 'Control')
+ {
+ FCK.Selection.Delete();
+ }
+ else
+ {
+ var oFakeImage = FCK.Selection.GetSelectedElement() ;
+ if ( oFakeImage )
+ {
+ if ( oFakeImage.tagName == 'IMG' && oFakeImage.getAttribute('_fckanchor') )
+ oAnchor = FCK.GetRealElement( oFakeImage ) ;
+ else
+ oFakeImage = null ;
+ }
+
+ //Search for a real anchor
+ if ( !oFakeImage )
+ {
+ oAnchor = FCK.Selection.MoveToAncestorNode( 'A' ) ;
+ if ( oAnchor )
+ FCK.Selection.SelectNode( oAnchor ) ;
+ }
+
+ // If it's also a link, then just remove the name and exit
+ if ( oAnchor.href.length != 0 )
+ {
+ oAnchor.removeAttribute( 'name' ) ;
+ // Remove temporary class for IE
+ if ( FCKBrowserInfo.IsIE )
+ oAnchor.className = oAnchor.className.replace( FCKRegexLib.FCK_Class, '' ) ;
+ return ;
+ }
+
+ // We need to remove the anchor
+ // If we got a fake image, then just remove it and we're done
+ if ( oFakeImage )
+ {
+ oFakeImage.parentNode.removeChild( oFakeImage ) ;
+ return ;
+ }
+ // Empty anchor, so just remove it
+ if ( oAnchor.innerHTML.length == 0 )
+ {
+ oAnchor.parentNode.removeChild( oAnchor ) ;
+ return ;
+ }
+ // Anchor with content, leave the content
+ FCKTools.RemoveOuterTags( oAnchor ) ;
+ }
+ if ( FCKBrowserInfo.IsGecko )
+ FCK.Selection.Collapse( true ) ;
+ },
+
+ GetState : function()
+ {
+ if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
+ return FCK_TRISTATE_DISABLED ;
+ return FCK.GetNamedCommandState( 'Unlink') ;
+ }
+};
+
+var FCKDeleteDivCommand = function()
+{
+}
+FCKDeleteDivCommand.prototype =
+{
+ GetState : function()
+ {
+ if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
+ return FCK_TRISTATE_DISABLED ;
+
+ var node = FCKSelection.GetParentElement() ;
+ var path = new FCKElementPath( node ) ;
+ return path.BlockLimit && path.BlockLimit.nodeName.IEquals( 'div' ) ? FCK_TRISTATE_OFF : FCK_TRISTATE_DISABLED ;
+ },
+
+ Execute : function()
+ {
+ // Create an undo snapshot before doing anything.
+ FCKUndo.SaveUndoStep() ;
+
+ // Find out the nodes to delete.
+ var nodes = FCKDomTools.GetSelectedDivContainers() ;
+
+ // Remember the current selection position.
+ var range = new FCKDomRange( FCK.EditorWindow ) ;
+ range.MoveToSelection() ;
+ var bookmark = range.CreateBookmark() ;
+
+ // Delete the container DIV node.
+ for ( var i = 0 ; i < nodes.length ; i++)
+ FCKDomTools.RemoveNode( nodes[i], true ) ;
+
+ // Restore selection.
+ range.MoveToBookmark( bookmark ) ;
+ range.Select() ;
+ }
+} ;
+
+// FCKRuleCommand
+var FCKNbsp = function()
+{
+ this.Name = 'Non Breaking Space' ;
+}
+
+FCKNbsp.prototype =
+{
+ Execute : function()
+ {
+ FCK.InsertHtml( '&nbsp;' ) ;
+ },
+
+ GetState : function()
+ {
+ return ( FCK.EditMode != FCK_EDITMODE_WYSIWYG ? FCK_TRISTATE_DISABLED : FCK_TRISTATE_OFF ) ;
+ }
+} ;
diff --git a/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckblockquotecommand.js b/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckblockquotecommand.js
new file mode 100644
index 0000000..2caff1b
--- /dev/null
+++ b/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckblockquotecommand.js
@@ -0,0 +1,281 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2009 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ * - GNU General Public License Version 2 or later (the "GPL")
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ * - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * - Mozilla Public License Version 1.1 or later (the "MPL")
+ * http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKBlockQuoteCommand Class: adds or removes blockquote tags.
+ */
+
+var FCKBlockQuoteCommand = function()
+{
+}
+
+FCKBlockQuoteCommand.prototype =
+{
+ Execute : function()
+ {
+ FCKUndo.SaveUndoStep() ;
+
+ var state = this.GetState() ;
+
+ var range = new FCKDomRange( FCK.EditorWindow ) ;
+ range.MoveToSelection() ;
+
+ var bookmark = range.CreateBookmark() ;
+
+ // Kludge for #1592: if the bookmark nodes are in the beginning of
+ // blockquote, then move them to the nearest block element in the
+ // blockquote.
+ if ( FCKBrowserInfo.IsIE )
+ {
+ var bStart = range.GetBookmarkNode( bookmark, true ) ;
+ var bEnd = range.GetBookmarkNode( bookmark, false ) ;
+
+ var cursor ;
+
+ if ( bStart
+ && bStart.parentNode.nodeName.IEquals( 'blockquote' )
+ && !bStart.previousSibling )
+ {
+ cursor = bStart ;
+ while ( ( cursor = cursor.nextSibling ) )
+ {
+ if ( FCKListsLib.BlockElements[ cursor.nodeName.toLowerCase() ] )
+ FCKDomTools.MoveNode( bStart, cursor, true ) ;
+ }
+ }
+
+ if ( bEnd
+ && bEnd.parentNode.nodeName.IEquals( 'blockquote' )
+ && !bEnd.previousSibling )
+ {
+ cursor = bEnd ;
+ while ( ( cursor = cursor.nextSibling ) )
+ {
+ if ( FCKListsLib.BlockElements[ cursor.nodeName.toLowerCase() ] )
+ {
+ if ( cursor.firstChild == bStart )
+ FCKDomTools.InsertAfterNode( bStart, bEnd ) ;
+ else
+ FCKDomTools.MoveNode( bEnd, cursor, true ) ;
+ }
+ }
+ }
+ }
+
+ var iterator = new FCKDomRangeIterator( range ) ;
+ var block ;
+
+ if ( state == FCK_TRISTATE_OFF )
+ {
+ var paragraphs = [] ;
+ while ( ( block = iterator.GetNextParagraph() ) )
+ paragraphs.push( block ) ;
+
+ // If no paragraphs, create one from the current selection position.
+ if ( paragraphs.length < 1 )
+ {
+ para = range.Window.document.createElement( FCKConfig.EnterMode.IEquals( 'p' ) ? 'p' : 'div' ) ;
+ range.InsertNode( para ) ;
+ para.appendChild( range.Window.document.createTextNode( '\ufeff' ) ) ;
+ range.MoveToBookmark( bookmark ) ;
+ range.MoveToNodeContents( para ) ;
+ range.Collapse( true ) ;
+ bookmark = range.CreateBookmark() ;
+ paragraphs.push( para ) ;
+ }
+
+ // Make sure all paragraphs have the same parent.
+ var commonParent = paragraphs[0].parentNode ;
+ var tmp = [] ;
+ for ( var i = 0 ; i < paragraphs.length ; i++ )
+ {
+ block = paragraphs[i] ;
+ commonParent = FCKDomTools.GetCommonParents( block.parentNode, commonParent ).pop() ;
+ }
+
+ // The common parent must not be the following tags: table, tbody, tr, ol, ul.
+ while ( commonParent.nodeName.IEquals( 'table', 'tbody', 'tr', 'ol', 'ul' ) )
+ commonParent = commonParent.parentNode ;
+
+ // Reconstruct the block list to be processed such that all resulting blocks
+ // satisfy parentNode == commonParent.
+ var lastBlock = null ;
+ while ( paragraphs.length > 0 )
+ {
+ block = paragraphs.shift() ;
+ while ( block.parentNode != commonParent )
+ block = block.parentNode ;
+ if ( block != lastBlock )
+ tmp.push( block ) ;
+ lastBlock = block ;
+ }
+
+ // If any of the selected blocks is a blockquote, remove it to prevent nested blockquotes.
+ while ( tmp.length > 0 )
+ {
+ block = tmp.shift() ;
+ if ( block.nodeName.IEquals( 'blockquote' ) )
+ {
+ var docFrag = FCKTools.GetElementDocument( block ).createDocumentFragment() ;
+ while ( block.firstChild )
+ {
+ docFrag.appendChild( block.removeChild( block.firstChild ) ) ;
+ paragraphs.push( docFrag.lastChild ) ;
+ }
+ block.parentNode.replaceChild( docFrag, block ) ;
+ }
+ else
+ paragraphs.push( block ) ;
+ }
+
+ // Now we have all the blocks to be included in a new blockquote node.
+ var bqBlock = range.Window.document.createElement( 'blockquote' ) ;
+ commonParent.insertBefore( bqBlock, paragraphs[0] ) ;
+ while ( paragraphs.length > 0 )
+ {
+ block = paragraphs.shift() ;
+ bqBlock.appendChild( block ) ;
+ }
+ }
+ else if ( state == FCK_TRISTATE_ON )
+ {
+ var moveOutNodes = [] ;
+ var elementMarkers = {} ;
+ while ( ( block = iterator.GetNextParagraph() ) )
+ {
+ var bqParent = null ;
+ var bqChild = null ;
+ while ( block.parentNode )
+ {
+ if ( block.parentNode.nodeName.IEquals( 'blockquote' ) )
+ {
+ bqParent = block.parentNode ;
+ bqChild = block ;
+ break ;
+ }
+ block = block.parentNode ;
+ }
+
+ // Remember the blocks that were recorded down in the moveOutNodes array
+ // to prevent duplicates.
+ if ( bqParent && bqChild && !bqChild._fckblockquotemoveout )
+ {
+ moveOutNodes.push( bqChild ) ;
+ FCKDomTools.SetElementMarker( elementMarkers, bqChild, '_fckblockquotemoveout', true ) ;
+ }
+ }
+ FCKDomTools.ClearAllMarkers( elementMarkers ) ;
+
+ var movedNodes = [] ;
+ var processedBlockquoteBlocks = [], elementMarkers = {} ;
+ var noBlockLeft = function( bqBlock )
+ {
+ for ( var i = 0 ; i < bqBlock.childNodes.length ; i++ )
+ {
+ if ( FCKListsLib.BlockElements[ bqBlock.childNodes[i].nodeName.toLowerCase() ] )
+ return false ;
+ }
+ return true ;
+ } ;
+ while ( moveOutNodes.length > 0 )
+ {
+ var node = moveOutNodes.shift() ;
+ var bqBlock = node.parentNode ;
+
+ // If the node is located at the beginning or the end, just take it out without splitting.
+ // Otherwise, split the blockquote node and move the paragraph in between the two blockquote nodes.
+ if ( node == node.parentNode.firstChild )
+ bqBlock.parentNode.insertBefore( bqBlock.removeChild( node ), bqBlock ) ;
+ else if ( node == node.parentNode.lastChild )
+ bqBlock.parentNode.insertBefore( bqBlock.removeChild( node ), bqBlock.nextSibling ) ;
+ else
+ FCKDomTools.BreakParent( node, node.parentNode, range ) ;
+
+ // Remember the blockquote node so we can clear it later (if it becomes empty).
+ if ( !bqBlock._fckbqprocessed )
+ {
+ processedBlockquoteBlocks.push( bqBlock ) ;
+ FCKDomTools.SetElementMarker( elementMarkers, bqBlock, '_fckbqprocessed', true );
+ }
+
+ movedNodes.push( node ) ;
+ }
+
+ // Clear blockquote nodes that have become empty.
+ for ( var i = processedBlockquoteBlocks.length - 1 ; i >= 0 ; i-- )
+ {
+ var bqBlock = processedBlockquoteBlocks[i] ;
+ if ( noBlockLeft( bqBlock ) )
+ FCKDomTools.RemoveNode( bqBlock ) ;
+ }
+ FCKDomTools.ClearAllMarkers( elementMarkers ) ;
+
+ if ( FCKConfig.EnterMode.IEquals( 'br' ) )
+ {
+ while ( movedNodes.length )
+ {
+ var node = movedNodes.shift() ;
+ var firstTime = true ;
+ if ( node.nodeName.IEquals( 'div' ) )
+ {
+ var docFrag = FCKTools.GetElementDocument( node ).createDocumentFragment() ;
+ var needBeginBr = firstTime && node.previousSibling &&
+ !FCKListsLib.BlockBoundaries[node.previousSibling.nodeName.toLowerCase()] ;
+ if ( firstTime && needBeginBr )
+ docFrag.appendChild( FCKTools.GetElementDocument( node ).createElement( 'br' ) ) ;
+ var needEndBr = node.nextSibling &&
+ !FCKListsLib.BlockBoundaries[node.nextSibling.nodeName.toLowerCase()] ;
+ while ( node.firstChild )
+ docFrag.appendChild( node.removeChild( node.firstChild ) ) ;
+ if ( needEndBr )
+ docFrag.appendChild( FCKTools.GetElementDocument( node ).createElement( 'br' ) ) ;
+ node.parentNode.replaceChild( docFrag, node ) ;
+ firstTime = false ;
+ }
+ }
+ }
+ }
+ range.MoveToBookmark( bookmark ) ;
+ range.Select() ;
+
+ FCK.Focus() ;
+ FCK.Events.FireEvent( 'OnSelectionChange' ) ;
+ },
+
+ GetState : function()
+ {
+ // Disabled if not WYSIWYG.
+ if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG || ! FCK.EditorWindow )
+ return FCK_TRISTATE_DISABLED ;
+
+ var path = new FCKElementPath( FCKSelection.GetBoundaryParentElement( true ) ) ;
+ var firstBlock = path.Block || path.BlockLimit ;
+
+ if ( !firstBlock || firstBlock.nodeName.toLowerCase() == 'body' )
+ return FCK_TRISTATE_OFF ;
+
+ // See if the first block has a blockquote parent.
+ for ( var i = 0 ; i < path.Elements.length ; i++ )
+ {
+ if ( path.Elements[i].nodeName.IEquals( 'blockquote' ) )
+ return FCK_TRISTATE_ON ;
+ }
+ return FCK_TRISTATE_OFF ;
+ }
+} ;
diff --git a/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckcorestylecommand.js b/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckcorestylecommand.js
new file mode 100644
index 0000000..b99ba5b
--- /dev/null
+++ b/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckcorestylecommand.js
@@ -0,0 +1,61 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2009 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ * - GNU General Public License Version 2 or later (the "GPL")
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ * - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * - Mozilla Public License Version 1.1 or later (the "MPL")
+ * http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKCoreStyleCommand Class: controls the execution of a core style. Core
+ * styles are usually represented as buttons in the toolbar., like Bold and
+ * Italic.
+ */
+
+ var FCKCoreStyleCommand = function( coreStyleName )
+ {
+ this.Name = 'CoreStyle' ;
+ this.StyleName = '_FCK_' + coreStyleName ;
+ this.IsActive = false ;
+
+ FCKStyles.AttachStyleStateChange( this.StyleName, this._OnStyleStateChange, this ) ;
+ }
+
+ FCKCoreStyleCommand.prototype =
+ {
+ Execute : function()
+ {
+ FCKUndo.SaveUndoStep() ;
+
+ if ( this.IsActive )
+ FCKStyles.RemoveStyle( this.StyleName ) ;
+ else
+ FCKStyles.ApplyStyle( this.StyleName ) ;
+
+ FCK.Focus() ;
+ FCK.Events.FireEvent( 'OnSelectionChange' ) ;
+ },
+
+ GetState : function()
+ {
+ if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
+ return FCK_TRISTATE_DISABLED ;
+ return this.IsActive ? FCK_TRISTATE_ON : FCK_TRISTATE_OFF ;
+ },
+
+ _OnStyleStateChange : function( styleName, isActive )
+ {
+ this.IsActive = isActive ;
+ }
+ };
diff --git a/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckfitwindow.js b/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckfitwindow.js
new file mode 100644
index 0000000..c1b8f9a
--- /dev/null
+++ b/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckfitwindow.js
@@ -0,0 +1,213 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2009 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ * - GNU General Public License Version 2 or later (the "GPL")
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ * - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * - Mozilla Public License Version 1.1 or later (the "MPL")
+ * http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Stretch the editor to full window size and back.
+ */
+
+var FCKFitWindow = function()
+{
+ this.Name = 'FitWindow' ;
+}
+
+FCKFitWindow.prototype.Execute = function()
+{
+ var eEditorFrame = window.frameElement ;
+ var eEditorFrameStyle = eEditorFrame.style ;
+
+ var eMainWindow = parent ;
+ var eDocEl = eMainWindow.document.documentElement ;
+ var eBody = eMainWindow.document.body ;
+ var eBodyStyle = eBody.style ;
+ var eParent ;
+
+ // Save the current selection and scroll position.
+ var oRange, oEditorScrollPos ;
+ if ( FCK.EditMode == FCK_EDITMODE_WYSIWYG )
+ {
+ oRange = new FCKDomRange( FCK.EditorWindow ) ;
+ oRange.MoveToSelection() ;
+ oEditorScrollPos = FCKTools.GetScrollPosition( FCK.EditorWindow ) ;
+ }
+ else
+ {
+ var eTextarea = FCK.EditingArea.Textarea ;
+ oRange = !FCKBrowserInfo.IsIE && [ eTextarea.selectionStart, eTextarea.selectionEnd ] ;
+ oEditorScrollPos = [ eTextarea.scrollLeft, eTextarea.scrollTop ] ;
+ }
+
+ // No original style properties known? Go fullscreen.
+ if ( !this.IsMaximized )
+ {
+ // Registering an event handler when the window gets resized.
+ if( FCKBrowserInfo.IsIE )
+ eMainWindow.attachEvent( 'onresize', FCKFitWindow_Resize ) ;
+ else
+ eMainWindow.addEventListener( 'resize', FCKFitWindow_Resize, true ) ;
+
+ // Save the scrollbars position.
+ this._ScrollPos = FCKTools.GetScrollPosition( eMainWindow ) ;
+
+ // Save and reset the styles for the entire node tree. They could interfere in the result.
+ eParent = eEditorFrame ;
+ // The extra () is to avoid a warning with strict error checking. This is ok.
+ while( (eParent = eParent.parentNode) )
+ {
+ if ( eParent.nodeType == 1 )
+ {
+ eParent._fckSavedStyles = FCKTools.SaveStyles( eParent ) ;
+ eParent.style.zIndex = FCKConfig.FloatingPanelsZIndex - 1 ;
+ }
+ }
+
+ // Hide IE scrollbars (in strict mode).
+ if ( FCKBrowserInfo.IsIE )
+ {
+ this.documentElementOverflow = eDocEl.style.overflow ;
+ eDocEl.style.overflow = 'hidden' ;
+ eBodyStyle.overflow = 'hidden' ;
+ }
+ else
+ {
+ // Hide the scroolbars in Firefox.
+ eBodyStyle.overflow = 'hidden' ;
+ eBodyStyle.width = '0px' ;
+ eBodyStyle.height = '0px' ;
+ }
+
+ // Save the IFRAME styles.
+ this._EditorFrameStyles = FCKTools.SaveStyles( eEditorFrame ) ;
+
+ // Resize.
+ var oViewPaneSize = FCKTools.GetViewPaneSize( eMainWindow ) ;
+
+ eEditorFrameStyle.position = "absolute";
+ eEditorFrame.offsetLeft ; // Kludge for Safari 3.1 browser bug, do not remove. See #2066.
+ eEditorFrameStyle.zIndex = FCKConfig.FloatingPanelsZIndex - 1;
+ eEditorFrameStyle.left = "0px";
+ eEditorFrameStyle.top = "0px";
+ eEditorFrameStyle.width = oViewPaneSize.Width + "px";
+ eEditorFrameStyle.height = oViewPaneSize.Height + "px";
+
+ // Giving the frame some (huge) borders on his right and bottom
+ // side to hide the background that would otherwise show when the
+ // editor is in fullsize mode and the window is increased in size
+ // not for IE, because IE immediately adapts the editor on resize,
+ // without showing any of the background oddly in firefox, the
+ // editor seems not to fill the whole frame, so just setting the
+ // background of it to white to cover the page laying behind it anyway.
+ if ( !FCKBrowserInfo.IsIE )
+ {
+ eEditorFrameStyle.borderRight = eEditorFrameStyle.borderBottom = "9999px solid white" ;
+ eEditorFrameStyle.backgroundColor = "white";
+ }
+
+ // Scroll to top left.
+ eMainWindow.scrollTo(0, 0);
+
+ // Is the editor still not on the top left? Let's find out and fix that as well. (Bug #174)
+ var editorPos = FCKTools.GetWindowPosition( eMainWindow, eEditorFrame ) ;
+ if ( editorPos.x != 0 )
+ eEditorFrameStyle.left = ( -1 * editorPos.x ) + "px" ;
+ if ( editorPos.y != 0 )
+ eEditorFrameStyle.top = ( -1 * editorPos.y ) + "px" ;
+
+ this.IsMaximized = true ;
+ }
+ else // Resize to original size.
+ {
+ // Remove the event handler of window resizing.
+ if( FCKBrowserInfo.IsIE )
+ eMainWindow.detachEvent( "onresize", FCKFitWindow_Resize ) ;
+ else
+ eMainWindow.removeEventListener( "resize", FCKFitWindow_Resize, true ) ;
+
+ // Restore the CSS position for the entire node tree.
+ eParent = eEditorFrame ;
+ // The extra () is to avoid a warning with strict error checking. This is ok.
+ while( (eParent = eParent.parentNode) )
+ {
+ if ( eParent._fckSavedStyles )
+ {
+ FCKTools.RestoreStyles( eParent, eParent._fckSavedStyles ) ;
+ eParent._fckSavedStyles = null ;
+ }
+ }
+
+ // Restore IE scrollbars
+ if ( FCKBrowserInfo.IsIE )
+ eDocEl.style.overflow = this.documentElementOverflow ;
+
+ // Restore original size
+ FCKTools.RestoreStyles( eEditorFrame, this._EditorFrameStyles ) ;
+
+ // Restore the window scroll position.
+ eMainWindow.scrollTo( this._ScrollPos.X, this._ScrollPos.Y ) ;
+
+ this.IsMaximized = false ;
+ }
+
+ FCKToolbarItems.GetItem('FitWindow').RefreshState() ;
+
+ // It seams that Firefox restarts the editing area when making this changes.
+ // On FF 1.0.x, the area is not anymore editable. On FF 1.5+, the special
+ //configuration, like DisableFFTableHandles and DisableObjectResizing get
+ //lost, so we must reset it. Also, the cursor position and selection are
+ //also lost, even if you comment the following line (MakeEditable).
+ // if ( FCKBrowserInfo.IsGecko10 ) // Initially I thought it was a FF 1.0 only problem.
+ if ( FCK.EditMode == FCK_EDITMODE_WYSIWYG )
+ FCK.EditingArea.MakeEditable() ;
+
+ FCK.Focus() ;
+
+ // Restore the selection and scroll position of inside the document.
+ if ( FCK.EditMode == FCK_EDITMODE_WYSIWYG )
+ {
+ oRange.Select() ;
+ FCK.EditorWindow.scrollTo( oEditorScrollPos.X, oEditorScrollPos.Y ) ;
+ }
+ else
+ {
+ if ( !FCKBrowserInfo.IsIE )
+ {
+ eTextarea.selectionStart = oRange[0] ;
+ eTextarea.selectionEnd = oRange[1] ;
+ }
+ eTextarea.scrollLeft = oEditorScrollPos[0] ;
+ eTextarea.scrollTop = oEditorScrollPos[1] ;
+ }
+}
+
+FCKFitWindow.prototype.GetState = function()
+{
+ if ( FCKConfig.ToolbarLocation != 'In' )
+ return FCK_TRISTATE_DISABLED ;
+ else
+ return ( this.IsMaximized ? FCK_TRISTATE_ON : FCK_TRISTATE_OFF );
+}
+
+function FCKFitWindow_Resize()
+{
+ var oViewPaneSize = FCKTools.GetViewPaneSize( parent ) ;
+
+ var eEditorFrameStyle = window.frameElement.style ;
+
+ eEditorFrameStyle.width = oViewPaneSize.Width + 'px' ;
+ eEditorFrameStyle.height = oViewPaneSize.Height + 'px' ;
+}
diff --git a/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckindentcommands.js b/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckindentcommands.js
new file mode 100644
index 0000000..5ae8de9
--- /dev/null
+++ b/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckindentcommands.js
@@ -0,0 +1,282 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2009 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ * - GNU General Public License Version 2 or later (the "GPL")
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ * - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * - Mozilla Public License Version 1.1 or later (the "MPL")
+ * http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKIndentCommand Class: controls block indentation.
+ */
+
+var FCKIndentCommand = function( name, offset )
+{
+ this.Name = name ;
+ this.Offset = offset ;
+ this.IndentCSSProperty = FCKConfig.ContentLangDirection.IEquals( 'ltr' ) ? 'marginLeft' : 'marginRight' ;
+}
+
+FCKIndentCommand._InitIndentModeParameters = function()
+{
+ if ( FCKConfig.IndentClasses && FCKConfig.IndentClasses.length > 0 )
+ {
+ this._UseIndentClasses = true ;
+ this._IndentClassMap = {} ;
+ for ( var i = 0 ; i < FCKConfig.IndentClasses.length ;i++ )
+ this._IndentClassMap[FCKConfig.IndentClasses[i]] = i + 1 ;
+ this._ClassNameRegex = new RegExp( '(?:^|\\s+)(' + FCKConfig.IndentClasses.join( '|' ) + ')(?=$|\\s)' ) ;
+ }
+ else
+ this._UseIndentClasses = false ;
+}
+
+
+FCKIndentCommand.prototype =
+{
+ Execute : function()
+ {
+ // Save an undo snapshot before doing anything.
+ FCKUndo.SaveUndoStep() ;
+
+ var range = new FCKDomRange( FCK.EditorWindow ) ;
+ range.MoveToSelection() ;
+ var bookmark = range.CreateBookmark() ;
+
+ // Two cases to handle here: either we're in a list, or not.
+ // If we're in a list, then the indent/outdent operations would be done on the list nodes.
+ // Otherwise, apply the operation on the nearest block nodes.
+ var nearestListBlock = FCKDomTools.GetCommonParentNode( range.StartNode || range.StartContainer ,
+ range.EndNode || range.EndContainer,
+ ['ul', 'ol'] ) ;
+ if ( nearestListBlock )
+ this._IndentList( range, nearestListBlock ) ;
+ else
+ this._IndentBlock( range ) ;
+
+ range.MoveToBookmark( bookmark ) ;
+ range.Select() ;
+
+ FCK.Focus() ;
+ FCK.Events.FireEvent( 'OnSelectionChange' ) ;
+ },
+
+ GetState : function()
+ {
+ // Disabled if not WYSIWYG.
+ if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG || ! FCK.EditorWindow )
+ return FCK_TRISTATE_DISABLED ;
+
+ // Initialize parameters if not already initialzed.
+ if ( FCKIndentCommand._UseIndentClasses == undefined )
+ FCKIndentCommand._InitIndentModeParameters() ;
+
+ // If we're not in a list, and the starting block's indentation is zero, and the current
+ // command is the outdent command, then we should return FCK_TRISTATE_DISABLED.
+ var startContainer = FCKSelection.GetBoundaryParentElement( true ) ;
+ var endContainer = FCKSelection.GetBoundaryParentElement( false ) ;
+ var listNode = FCKDomTools.GetCommonParentNode( startContainer, endContainer, ['ul','ol'] ) ;
+
+ if ( listNode )
+ {
+ if ( this.Name.IEquals( 'outdent' ) )
+ return FCK_TRISTATE_OFF ;
+ var firstItem = FCKTools.GetElementAscensor( startContainer, 'li' ) ;
+ if ( !firstItem || !firstItem.previousSibling )
+ return FCK_TRISTATE_DISABLED ;
+ return FCK_TRISTATE_OFF ;
+ }
+ if ( ! FCKIndentCommand._UseIndentClasses && this.Name.IEquals( 'indent' ) )
+ return FCK_TRISTATE_OFF;
+
+ var path = new FCKElementPath( startContainer ) ;
+ var firstBlock = path.Block || path.BlockLimit ;
+ if ( !firstBlock )
+ return FCK_TRISTATE_DISABLED ;
+
+ if ( FCKIndentCommand._UseIndentClasses )
+ {
+ var indentClass = firstBlock.className.match( FCKIndentCommand._ClassNameRegex ) ;
+ var indentStep = 0 ;
+ if ( indentClass != null )
+ {
+ indentClass = indentClass[1] ;
+ indentStep = FCKIndentCommand._IndentClassMap[indentClass] ;
+ }
+ if ( ( this.Name == 'outdent' && indentStep == 0 ) ||
+ ( this.Name == 'indent' && indentStep == FCKConfig.IndentClasses.length ) )
+ return FCK_TRISTATE_DISABLED ;
+ return FCK_TRISTATE_OFF ;
+ }
+ else
+ {
+ var indent = parseInt( firstBlock.style[this.IndentCSSProperty], 10 ) ;
+ if ( isNaN( indent ) )
+ indent = 0 ;
+ if ( indent <= 0 )
+ return FCK_TRISTATE_DISABLED ;
+ return FCK_TRISTATE_OFF ;
+ }
+ },
+
+ _IndentBlock : function( range )
+ {
+ var iterator = new FCKDomRangeIterator( range ) ;
+ iterator.EnforceRealBlocks = true ;
+
+ range.Expand( 'block_contents' ) ;
+ var commonParents = FCKDomTools.GetCommonParents( range.StartContainer, range.EndContainer ) ;
+ var nearestParent = commonParents[commonParents.length - 1] ;
+ var block ;
+
+ while ( ( block = iterator.GetNextParagraph() ) )
+ {
+ // We don't want to indent subtrees recursively, so only perform the indent operation
+ // if the block itself is the nearestParent, or the block's parent is the nearestParent.
+ if ( ! ( block == nearestParent || block.parentNode == nearestParent ) )
+ continue ;
+
+ if ( FCKIndentCommand._UseIndentClasses )
+ {
+ // Transform current class name to indent step index.
+ var indentClass = block.className.match( FCKIndentCommand._ClassNameRegex ) ;
+ var indentStep = 0 ;
+ if ( indentClass != null )
+ {
+ indentClass = indentClass[1] ;
+ indentStep = FCKIndentCommand._IndentClassMap[indentClass] ;
+ }
+
+ // Operate on indent step index, transform indent step index back to class name.
+ if ( this.Name.IEquals( 'outdent' ) )
+ indentStep-- ;
+ else if ( this.Name.IEquals( 'indent' ) )
+ indentStep++ ;
+ indentStep = Math.min( indentStep, FCKConfig.IndentClasses.length ) ;
+ indentStep = Math.max( indentStep, 0 ) ;
+ var className = block.className.replace( FCKIndentCommand._ClassNameRegex, '' ) ;
+ if ( indentStep < 1 )
+ block.className = className ;
+ else
+ block.className = ( className.length > 0 ? className + ' ' : '' ) +
+ FCKConfig.IndentClasses[indentStep - 1] ;
+ }
+ else
+ {
+ // Offset distance is assumed to be in pixels for now.
+ var currentOffset = parseInt( block.style[this.IndentCSSProperty], 10 ) ;
+ if ( isNaN( currentOffset ) )
+ currentOffset = 0 ;
+ currentOffset += this.Offset ;
+ currentOffset = Math.max( currentOffset, 0 ) ;
+ currentOffset = Math.ceil( currentOffset / this.Offset ) * this.Offset ;
+ block.style[this.IndentCSSProperty] = currentOffset ? currentOffset + FCKConfig.IndentUnit : '' ;
+ if ( block.getAttribute( 'style' ) == '' )
+ block.removeAttribute( 'style' ) ;
+ }
+ }
+ },
+
+ _IndentList : function( range, listNode )
+ {
+ // Our starting and ending points of the range might be inside some blocks under a list item...
+ // So before playing with the iterator, we need to expand the block to include the list items.
+ var startContainer = range.StartContainer ;
+ var endContainer = range.EndContainer ;
+ while ( startContainer && startContainer.parentNode != listNode )
+ startContainer = startContainer.parentNode ;
+ while ( endContainer && endContainer.parentNode != listNode )
+ endContainer = endContainer.parentNode ;
+
+ if ( ! startContainer || ! endContainer )
+ return ;
+
+ // Now we can iterate over the individual items on the same tree depth.
+ var block = startContainer ;
+ var itemsToMove = [] ;
+ var stopFlag = false ;
+ while ( stopFlag == false )
+ {
+ if ( block == endContainer )
+ stopFlag = true ;
+ itemsToMove.push( block ) ;
+ block = block.nextSibling ;
+ }
+ if ( itemsToMove.length < 1 )
+ return ;
+
+ // Do indent or outdent operations on the array model of the list, not the list's DOM tree itself.
+ // The array model demands that it knows as much as possible about the surrounding lists, we need
+ // to feed it the further ancestor node that is still a list.
+ var listParents = FCKDomTools.GetParents( listNode ) ;
+ for ( var i = 0 ; i < listParents.length ; i++ )
+ {
+ if ( listParents[i].nodeName.IEquals( ['ul', 'ol'] ) )
+ {
+ listNode = listParents[i] ;
+ break ;
+ }
+ }
+ var indentOffset = this.Name.IEquals( 'indent' ) ? 1 : -1 ;
+ var startItem = itemsToMove[0] ;
+ var lastItem = itemsToMove[ itemsToMove.length - 1 ] ;
+ var markerObj = {} ;
+
+ // Convert the list DOM tree into a one dimensional array.
+ var listArray = FCKDomTools.ListToArray( listNode, markerObj ) ;
+
+ // Apply indenting or outdenting on the array.
+ var baseIndent = listArray[lastItem._FCK_ListArray_Index].indent ;
+ for ( var i = startItem._FCK_ListArray_Index ; i <= lastItem._FCK_ListArray_Index ; i++ )
+ listArray[i].indent += indentOffset ;
+ for ( var i = lastItem._FCK_ListArray_Index + 1 ; i < listArray.length && listArray[i].indent > baseIndent ; i++ )
+ listArray[i].indent += indentOffset ;
+
+ /* For debug use only
+ var PrintArray = function( listArray, doc )
+ {
+ var s = [] ;
+ for ( var i = 0 ; i < listArray.length ; i++ )
+ {
+ for ( var j in listArray[i] )
+ {
+ if ( j != 'contents' )
+ s.push( j + ":" + listArray[i][j] + "; " ) ;
+ else
+ {
+ var docFrag = doc.createDocumentFragment() ;
+ var tmpNode = doc.createElement( 'span' ) ;
+ for ( var k = 0 ; k < listArray[i][j].length ; k++ )
+ docFrag.appendChild( listArray[i][j][k].cloneNode( true ) ) ;
+ tmpNode.appendChild( docFrag ) ;
+ s.push( j + ":" + tmpNode.innerHTML + "; ") ;
+ }
+ }
+ s.push( '\n' ) ;
+ }
+ alert( s.join('') ) ;
+ }
+ PrintArray( listArray, FCK.EditorDocument ) ;
+ */
+
+ // Convert the array back to a DOM forest (yes we might have a few subtrees now).
+ // And replace the old list with the new forest.
+ var newList = FCKDomTools.ArrayToList( listArray ) ;
+ if ( newList )
+ listNode.parentNode.replaceChild( newList.listNode, listNode ) ;
+
+ // Clean up the markers.
+ FCKDomTools.ClearAllMarkers( markerObj ) ;
+ }
+} ;
diff --git a/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckjustifycommands.js b/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckjustifycommands.js
new file mode 100644
index 0000000..f72c2cb
--- /dev/null
+++ b/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckjustifycommands.js
@@ -0,0 +1,173 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2009 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ * - GNU General Public License Version 2 or later (the "GPL")
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ * - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * - Mozilla Public License Version 1.1 or later (the "MPL")
+ * http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKJustifyCommand Class: controls block justification.
+ */
+
+var FCKJustifyCommand = function( alignValue )
+{
+ this.AlignValue = alignValue ;
+
+ // Detect whether this is the instance for the default alignment.
+ var contentDir = FCKConfig.ContentLangDirection.toLowerCase() ;
+ this.IsDefaultAlign = ( alignValue == 'left' && contentDir == 'ltr' ) ||
+ ( alignValue == 'right' && contentDir == 'rtl' ) ;
+
+ // Get the class name to be used by this instance.
+ var cssClassName = this._CssClassName = ( function()
+ {
+ var classes = FCKConfig.JustifyClasses ;
+ if ( classes )
+ {
+ switch ( alignValue )
+ {
+ case 'left' :
+ return classes[0] || null ;
+ case 'center' :
+ return classes[1] || null ;
+ case 'right' :
+ return classes[2] || null ;
+ case 'justify' :
+ return classes[3] || null ;
+ }
+ }
+ return null ;
+ } )() ;
+
+ if ( cssClassName && cssClassName.length > 0 )
+ this._CssClassRegex = new RegExp( '(?:^|\\s+)' + cssClassName + '(?=$|\\s)' ) ;
+}
+
+FCKJustifyCommand._GetClassNameRegex = function()
+{
+ var regex = FCKJustifyCommand._ClassRegex ;
+ if ( regex != undefined )
+ return regex ;
+
+ var names = [] ;
+
+ var classes = FCKConfig.JustifyClasses ;
+ if ( classes )
+ {
+ for ( var i = 0 ; i < 4 ; i++ )
+ {
+ var className = classes[i] ;
+ if ( className && className.length > 0 )
+ names.push( className ) ;
+ }
+ }
+
+ if ( names.length > 0 )
+ regex = new RegExp( '(?:^|\\s+)(?:' + names.join( '|' ) + ')(?=$|\\s)' ) ;
+ else
+ regex = null ;
+
+ return FCKJustifyCommand._ClassRegex = regex ;
+}
+
+FCKJustifyCommand.prototype =
+{
+ Execute : function()
+ {
+ // Save an undo snapshot before doing anything.
+ FCKUndo.SaveUndoStep() ;
+
+ var range = new FCKDomRange( FCK.EditorWindow ) ;
+ range.MoveToSelection() ;
+
+ var currentState = this.GetState() ;
+ if ( currentState == FCK_TRISTATE_DISABLED )
+ return ;
+
+ // Store a bookmark of the selection since the paragraph iterator might
+ // change the DOM tree and break selections.
+ var bookmark = range.CreateBookmark() ;
+
+ var cssClassName = this._CssClassName ;
+
+ // Apply alignment setting for each paragraph.
+ var iterator = new FCKDomRangeIterator( range ) ;
+ var block ;
+ while ( ( block = iterator.GetNextParagraph() ) )
+ {
+ block.removeAttribute( 'align' ) ;
+
+ if ( cssClassName )
+ {
+ // Remove the any of the alignment classes from the className.
+ var className = block.className.replace( FCKJustifyCommand._GetClassNameRegex(), '' ) ;
+
+ // Append the desired class name.
+ if ( currentState == FCK_TRISTATE_OFF )
+ {
+ if ( className.length > 0 )
+ className += ' ' ;
+ block.className = className + cssClassName ;
+ }
+ else if ( className.length == 0 )
+ FCKDomTools.RemoveAttribute( block, 'class' ) ;
+ }
+ else
+ {
+ var style = block.style ;
+ if ( currentState == FCK_TRISTATE_OFF )
+ style.textAlign = this.AlignValue ;
+ else
+ {
+ style.textAlign = '' ;
+ if ( style.cssText.length == 0 )
+ block.removeAttribute( 'style' ) ;
+ }
+ }
+ }
+
+ // Restore previous selection.
+ range.MoveToBookmark( bookmark ) ;
+ range.Select() ;
+
+ FCK.Focus() ;
+ FCK.Events.FireEvent( 'OnSelectionChange' ) ;
+ },
+
+ GetState : function()
+ {
+ // Disabled if not WYSIWYG.
+ if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG || ! FCK.EditorWindow )
+ return FCK_TRISTATE_DISABLED ;
+
+ // Retrieve the first selected block.
+ var path = new FCKElementPath( FCKSelection.GetBoundaryParentElement( true ) ) ;
+ var firstBlock = path.Block || path.BlockLimit ;
+
+ if ( !firstBlock || firstBlock.nodeName.toLowerCase() == 'body' )
+ return FCK_TRISTATE_OFF ;
+
+ // Check if the desired style is already applied to the block.
+ var currentAlign ;
+ if ( FCKBrowserInfo.IsIE )
+ currentAlign = firstBlock.currentStyle.textAlign ;
+ else
+ currentAlign = FCK.EditorWindow.getComputedStyle( firstBlock, '' ).getPropertyValue( 'text-align' );
+ currentAlign = currentAlign.replace( /(-moz-|-webkit-|start|auto)/i, '' );
+ if ( ( !currentAlign && this.IsDefaultAlign ) || currentAlign == this.AlignValue )
+ return FCK_TRISTATE_ON ;
+ return FCK_TRISTATE_OFF ;
+ }
+} ;
diff --git a/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fcklistcommands.js b/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fcklistcommands.js
new file mode 100644
index 0000000..16f71ea
--- /dev/null
+++ b/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fcklistcommands.js
@@ -0,0 +1,382 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2009 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ * - GNU General Public License Version 2 or later (the "GPL")
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ * - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * - Mozilla Public License Version 1.1 or later (the "MPL")
+ * http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Implementation for the "Insert/Remove Ordered/Unordered List" commands.
+ */
+
+var FCKListCommand = function( name, tagName )
+{
+ this.Name = name ;
+ this.TagName = tagName ;
+}
+
+FCKListCommand.prototype =
+{
+ GetState : function()
+ {
+ // Disabled if not WYSIWYG.
+ if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG || ! FCK.EditorWindow )
+ return FCK_TRISTATE_DISABLED ;
+
+ // We'll use the style system's convention to determine list state here...
+ // If the starting block is a descendant of an <ol> or <ul> node, then we're in a list.
+ var startContainer = FCKSelection.GetBoundaryParentElement( true ) ;
+ var listNode = startContainer ;
+ while ( listNode )
+ {
+ if ( listNode.nodeName.IEquals( [ 'ul', 'ol' ] ) )
+ break ;
+ listNode = listNode.parentNode ;
+ }
+ if ( listNode && listNode.nodeName.IEquals( this.TagName ) )
+ return FCK_TRISTATE_ON ;
+ else
+ return FCK_TRISTATE_OFF ;
+ },
+
+ Execute : function()
+ {
+ FCKUndo.SaveUndoStep() ;
+
+ var doc = FCK.EditorDocument ;
+ var range = new FCKDomRange( FCK.EditorWindow ) ;
+ range.MoveToSelection() ;
+ var state = this.GetState() ;
+
+ // Midas lists rule #1 says we can create a list even in an empty document.
+ // But FCKDomRangeIterator wouldn't run if the document is really empty.
+ // So create a paragraph if the document is empty and we're going to create a list.
+ if ( state == FCK_TRISTATE_OFF )
+ {
+ FCKDomTools.TrimNode( doc.body ) ;
+ if ( ! doc.body.firstChild )
+ {
+ var paragraph = doc.createElement( 'p' ) ;
+ doc.body.appendChild( paragraph ) ;
+ range.MoveToNodeContents( paragraph ) ;
+ }
+ }
+
+ var bookmark = range.CreateBookmark() ;
+
+ // Group the blocks up because there are many cases where multiple lists have to be created,
+ // or multiple lists have to be cancelled.
+ var listGroups = [] ;
+ var markerObj = {} ;
+ var iterator = new FCKDomRangeIterator( range ) ;
+ var block ;
+
+ iterator.ForceBrBreak = ( state == FCK_TRISTATE_OFF ) ;
+ var nextRangeExists = true ;
+ var rangeQueue = null ;
+ while ( nextRangeExists )
+ {
+ while ( ( block = iterator.GetNextParagraph() ) )
+ {
+ var path = new FCKElementPath( block ) ;
+ var listNode = null ;
+ var processedFlag = false ;
+ var blockLimit = path.BlockLimit ;
+
+ // First, try to group by a list ancestor.
+ for ( var i = path.Elements.length - 1 ; i >= 0 ; i-- )
+ {
+ var el = path.Elements[i] ;
+ if ( el.nodeName.IEquals( ['ol', 'ul'] ) )
+ {
+ // If we've encountered a list inside a block limit
+ // The last group object of the block limit element should
+ // no longer be valid. Since paragraphs after the list
+ // should belong to a different group of paragraphs before
+ // the list. (Bug #1309)
+ if ( blockLimit._FCK_ListGroupObject )
+ blockLimit._FCK_ListGroupObject = null ;
+
+ var groupObj = el._FCK_ListGroupObject ;
+ if ( groupObj )
+ groupObj.contents.push( block ) ;
+ else
+ {
+ groupObj = { 'root' : el, 'contents' : [ block ] } ;
+ listGroups.push( groupObj ) ;
+ FCKDomTools.SetElementMarker( markerObj, el, '_FCK_ListGroupObject', groupObj ) ;
+ }
+ processedFlag = true ;
+ break ;
+ }
+ }
+
+ if ( processedFlag )
+ continue ;
+
+ // No list ancestor? Group by block limit.
+ var root = blockLimit ;
+ if ( root._FCK_ListGroupObject )
+ root._FCK_ListGroupObject.contents.push( block ) ;
+ else
+ {
+ var groupObj = { 'root' : root, 'contents' : [ block ] } ;
+ FCKDomTools.SetElementMarker( markerObj, root, '_FCK_ListGroupObject', groupObj ) ;
+ listGroups.push( groupObj ) ;
+ }
+ }
+
+ if ( FCKBrowserInfo.IsIE )
+ nextRangeExists = false ;
+ else
+ {
+ if ( rangeQueue == null )
+ {
+ rangeQueue = [] ;
+ var selectionObject = FCKSelection.GetSelection() ;
+ if ( selectionObject && listGroups.length == 0 )
+ rangeQueue.push( selectionObject.getRangeAt( 0 ) ) ;
+ for ( var i = 1 ; selectionObject && i < selectionObject.rangeCount ; i++ )
+ rangeQueue.push( selectionObject.getRangeAt( i ) ) ;
+ }
+ if ( rangeQueue.length < 1 )
+ nextRangeExists = false ;
+ else
+ {
+ var internalRange = FCKW3CRange.CreateFromRange( doc, rangeQueue.shift() ) ;
+ range._Range = internalRange ;
+ range._UpdateElementInfo() ;
+ if ( range.StartNode.nodeName.IEquals( 'td' ) )
+ range.SetStart( range.StartNode, 1 ) ;
+ if ( range.EndNode.nodeName.IEquals( 'td' ) )
+ range.SetEnd( range.EndNode, 2 ) ;
+ iterator = new FCKDomRangeIterator( range ) ;
+ iterator.ForceBrBreak = ( state == FCK_TRISTATE_OFF ) ;
+ }
+ }
+ }
+
+ // Now we have two kinds of list groups, groups rooted at a list, and groups rooted at a block limit element.
+ // We either have to build lists or remove lists, for removing a list does not makes sense when we are looking
+ // at the group that's not rooted at lists. So we have three cases to handle.
+ var listsCreated = [] ;
+ while ( listGroups.length > 0 )
+ {
+ var groupObj = listGroups.shift() ;
+ if ( state == FCK_TRISTATE_OFF )
+ {
+ if ( groupObj.root.nodeName.IEquals( ['ul', 'ol'] ) )
+ this._ChangeListType( groupObj, markerObj, listsCreated ) ;
+ else
+ this._CreateList( groupObj, listsCreated ) ;
+ }
+ else if ( state == FCK_TRISTATE_ON && groupObj.root.nodeName.IEquals( ['ul', 'ol'] ) )
+ this._RemoveList( groupObj, markerObj ) ;
+ }
+
+ // For all new lists created, merge adjacent, same type lists.
+ for ( var i = 0 ; i < listsCreated.length ; i++ )
+ {
+ var listNode = listsCreated[i] ;
+ var stopFlag = false ;
+ var currentNode = listNode ;
+ while ( ! stopFlag )
+ {
+ currentNode = currentNode.nextSibling ;
+ if ( currentNode && currentNode.nodeType == 3 && currentNode.nodeValue.search( /^[\n\r\t ]*$/ ) == 0 )
+ continue ;
+ stopFlag = true ;
+ }
+
+ if ( currentNode && currentNode.nodeName.IEquals( this.TagName ) )
+ {
+ currentNode.parentNode.removeChild( currentNode ) ;
+ while ( currentNode.firstChild )
+ listNode.appendChild( currentNode.removeChild( currentNode.firstChild ) ) ;
+ }
+
+ stopFlag = false ;
+ currentNode = listNode ;
+ while ( ! stopFlag )
+ {
+ currentNode = currentNode.previousSibling ;
+ if ( currentNode && currentNode.nodeType == 3 && currentNode.nodeValue.search( /^[\n\r\t ]*$/ ) == 0 )
+ continue ;
+ stopFlag = true ;
+ }
+ if ( currentNode && currentNode.nodeName.IEquals( this.TagName ) )
+ {
+ currentNode.parentNode.removeChild( currentNode ) ;
+ while ( currentNode.lastChild )
+ listNode.insertBefore( currentNode.removeChild( currentNode.lastChild ),
+ listNode.firstChild ) ;
+ }
+ }
+
+ // Clean up, restore selection and update toolbar button states.
+ FCKDomTools.ClearAllMarkers( markerObj ) ;
+ range.MoveToBookmark( bookmark ) ;
+ range.Select() ;
+
+ FCK.Focus() ;
+ FCK.Events.FireEvent( 'OnSelectionChange' ) ;
+ },
+
+ _ChangeListType : function( groupObj, markerObj, listsCreated )
+ {
+ // This case is easy...
+ // 1. Convert the whole list into a one-dimensional array.
+ // 2. Change the list type by modifying the array.
+ // 3. Recreate the whole list by converting the array to a list.
+ // 4. Replace the original list with the recreated list.
+ var listArray = FCKDomTools.ListToArray( groupObj.root, markerObj ) ;
+ var selectedListItems = [] ;
+ for ( var i = 0 ; i < groupObj.contents.length ; i++ )
+ {
+ var itemNode = groupObj.contents[i] ;
+ itemNode = FCKTools.GetElementAscensor( itemNode, 'li' ) ;
+ if ( ! itemNode || itemNode._FCK_ListItem_Processed )
+ continue ;
+ selectedListItems.push( itemNode ) ;
+ FCKDomTools.SetElementMarker( markerObj, itemNode, '_FCK_ListItem_Processed', true ) ;
+ }
+ var fakeParent = FCKTools.GetElementDocument( groupObj.root ).createElement( this.TagName ) ;
+ for ( var i = 0 ; i < selectedListItems.length ; i++ )
+ {
+ var listIndex = selectedListItems[i]._FCK_ListArray_Index ;
+ listArray[listIndex].parent = fakeParent ;
+ }
+ var newList = FCKDomTools.ArrayToList( listArray, markerObj ) ;
+ for ( var i = 0 ; i < newList.listNode.childNodes.length ; i++ )
+ {
+ if ( newList.listNode.childNodes[i].nodeName.IEquals( this.TagName ) )
+ listsCreated.push( newList.listNode.childNodes[i] ) ;
+ }
+ groupObj.root.parentNode.replaceChild( newList.listNode, groupObj.root ) ;
+ },
+
+ _CreateList : function( groupObj, listsCreated )
+ {
+ var contents = groupObj.contents ;
+ var doc = FCKTools.GetElementDocument( groupObj.root ) ;
+ var listContents = [] ;
+
+ // It is possible to have the contents returned by DomRangeIterator to be the same as the root.
+ // e.g. when we're running into table cells.
+ // In such a case, enclose the childNodes of contents[0] into a <div>.
+ if ( contents.length == 1 && contents[0] == groupObj.root )
+ {
+ var divBlock = doc.createElement( 'div' );
+ while ( contents[0].firstChild )
+ divBlock.appendChild( contents[0].removeChild( contents[0].firstChild ) ) ;
+ contents[0].appendChild( divBlock ) ;
+ contents[0] = divBlock ;
+ }
+
+ // Calculate the common parent node of all content blocks.
+ var commonParent = groupObj.contents[0].parentNode ;
+ for ( var i = 0 ; i < contents.length ; i++ )
+ commonParent = FCKDomTools.GetCommonParents( commonParent, contents[i].parentNode ).pop() ;
+
+ // We want to insert things that are in the same tree level only, so calculate the contents again
+ // by expanding the selected blocks to the same tree level.
+ for ( var i = 0 ; i < contents.length ; i++ )
+ {
+ var contentNode = contents[i] ;
+ while ( contentNode.parentNode )
+ {
+ if ( contentNode.parentNode == commonParent )
+ {
+ listContents.push( contentNode ) ;
+ break ;
+ }
+ contentNode = contentNode.parentNode ;
+ }
+ }
+
+ if ( listContents.length < 1 )
+ return ;
+
+ // Insert the list to the DOM tree.
+ var insertAnchor = listContents[listContents.length - 1].nextSibling ;
+ var listNode = doc.createElement( this.TagName ) ;
+ listsCreated.push( listNode ) ;
+ while ( listContents.length )
+ {
+ var contentBlock = listContents.shift() ;
+ var docFrag = doc.createDocumentFragment() ;
+ while ( contentBlock.firstChild )
+ docFrag.appendChild( contentBlock.removeChild( contentBlock.firstChild ) ) ;
+ contentBlock.parentNode.removeChild( contentBlock ) ;
+ var listItem = doc.createElement( 'li' ) ;
+ listItem.appendChild( docFrag ) ;
+ listNode.appendChild( listItem ) ;
+ }
+ commonParent.insertBefore( listNode, insertAnchor ) ;
+ },
+
+ _RemoveList : function( groupObj, markerObj )
+ {
+ // This is very much like the change list type operation.
+ // Except that we're changing the selected items' indent to -1 in the list array.
+ var listArray = FCKDomTools.ListToArray( groupObj.root, markerObj ) ;
+ var selectedListItems = [] ;
+ for ( var i = 0 ; i < groupObj.contents.length ; i++ )
+ {
+ var itemNode = groupObj.contents[i] ;
+ itemNode = FCKTools.GetElementAscensor( itemNode, 'li' ) ;
+ if ( ! itemNode || itemNode._FCK_ListItem_Processed )
+ continue ;
+ selectedListItems.push( itemNode ) ;
+ FCKDomTools.SetElementMarker( markerObj, itemNode, '_FCK_ListItem_Processed', true ) ;
+ }
+
+ var lastListIndex = null ;
+ for ( var i = 0 ; i < selectedListItems.length ; i++ )
+ {
+ var listIndex = selectedListItems[i]._FCK_ListArray_Index ;
+ listArray[listIndex].indent = -1 ;
+ lastListIndex = listIndex ;
+ }
+
+ // After cutting parts of the list out with indent=-1, we still have to maintain the array list
+ // model's nextItem.indent <= currentItem.indent + 1 invariant. Otherwise the array model of the
+ // list cannot be converted back to a real DOM list.
+ for ( var i = lastListIndex + 1; i < listArray.length ; i++ )
+ {
+ if ( listArray[i].indent > listArray[i-1].indent + 1 )
+ {
+ var indentOffset = listArray[i-1].indent + 1 - listArray[i].indent ;
+ var oldIndent = listArray[i].indent ;
+ while ( listArray[i] && listArray[i].indent >= oldIndent)
+ {
+ listArray[i].indent += indentOffset ;
+ i++ ;
+ }
+ i-- ;
+ }
+ }
+
+ var newList = FCKDomTools.ArrayToList( listArray, markerObj ) ;
+ // If groupObj.root is the last element in its parent, or its nextSibling is a <br>, then we should
+ // not add a <br> after the final item. So, check for the cases and trim the <br>.
+ if ( groupObj.root.nextSibling == null || groupObj.root.nextSibling.nodeName.IEquals( 'br' ) )
+ {
+ if ( newList.listNode.lastChild.nodeName.IEquals( 'br' ) )
+ newList.listNode.removeChild( newList.listNode.lastChild ) ;
+ }
+ groupObj.root.parentNode.replaceChild( newList.listNode, groupObj.root ) ;
+ }
+};
diff --git a/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fcknamedcommand.js b/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fcknamedcommand.js
new file mode 100644
index 0000000..b0e3f8e
--- /dev/null
+++ b/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fcknamedcommand.js
@@ -0,0 +1,39 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2009 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ * - GNU General Public License Version 2 or later (the "GPL")
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ * - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * - Mozilla Public License Version 1.1 or later (the "MPL")
+ * http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKNamedCommand Class: represents an internal browser command.
+ */
+
+var FCKNamedCommand = function( commandName )
+{
+ this.Name = commandName ;
+}
+
+FCKNamedCommand.prototype.Execute = function()
+{
+ FCK.ExecuteNamedCommand( this.Name ) ;
+}
+
+FCKNamedCommand.prototype.GetState = function()
+{
+ if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
+ return FCK_TRISTATE_DISABLED ;
+ return FCK.GetNamedCommandState( this.Name ) ;
+}
diff --git a/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckpasteplaintextcommand.js b/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckpasteplaintextcommand.js
new file mode 100644
index 0000000..0963490
--- /dev/null
+++ b/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckpasteplaintextcommand.js
@@ -0,0 +1,40 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2009 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ * - GNU General Public License Version 2 or later (the "GPL")
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ * - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * - Mozilla Public License Version 1.1 or later (the "MPL")
+ * http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKPastePlainTextCommand Class: represents the
+ * "Paste as Plain Text" command.
+ */
+
+var FCKPastePlainTextCommand = function()
+{
+ this.Name = 'PasteText' ;
+}
+
+FCKPastePlainTextCommand.prototype.Execute = function()
+{
+ FCK.PasteAsPlainText() ;
+}
+
+FCKPastePlainTextCommand.prototype.GetState = function()
+{
+ if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
+ return FCK_TRISTATE_DISABLED ;
+ return FCK.GetNamedCommandState( 'Paste' ) ;
+}
diff --git a/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckpastewordcommand.js b/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckpastewordcommand.js
new file mode 100644
index 0000000..b800a8f
--- /dev/null
+++ b/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckpastewordcommand.js
@@ -0,0 +1,40 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2009 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ * - GNU General Public License Version 2 or later (the "GPL")
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ * - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * - Mozilla Public License Version 1.1 or later (the "MPL")
+ * http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKPasteWordCommand Class: represents the "Paste from Word" command.
+ */
+
+var FCKPasteWordCommand = function()
+{
+ this.Name = 'PasteWord' ;
+}
+
+FCKPasteWordCommand.prototype.Execute = function()
+{
+ FCK.PasteFromWord() ;
+}
+
+FCKPasteWordCommand.prototype.GetState = function()
+{
+ if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG || FCKConfig.ForcePasteAsPlainText )
+ return FCK_TRISTATE_DISABLED ;
+ else
+ return FCK.GetNamedCommandState( 'Paste' ) ;
+}
diff --git a/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckremoveformatcommand.js b/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckremoveformatcommand.js
new file mode 100644
index 0000000..af37fd2
--- /dev/null
+++ b/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckremoveformatcommand.js
@@ -0,0 +1,45 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2009 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ * - GNU General Public License Version 2 or later (the "GPL")
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ * - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * - Mozilla Public License Version 1.1 or later (the "MPL")
+ * http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKRemoveFormatCommand Class: controls the execution of a core style. Core
+ * styles are usually represented as buttons in the toolbar., like Bold and
+ * Italic.
+ */
+
+ var FCKRemoveFormatCommand = function()
+ {
+ this.Name = 'RemoveFormat' ;
+ }
+
+ FCKRemoveFormatCommand.prototype =
+ {
+ Execute : function()
+ {
+ FCKStyles.RemoveAll() ;
+
+ FCK.Focus() ;
+ FCK.Events.FireEvent( 'OnSelectionChange' ) ;
+ },
+
+ GetState : function()
+ {
+ return FCK.EditorWindow ? FCK_TRISTATE_OFF : FCK_TRISTATE_DISABLED ;
+ }
+ };
diff --git a/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckshowblocks.js b/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckshowblocks.js
new file mode 100644
index 0000000..9c9919b
--- /dev/null
+++ b/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckshowblocks.js
@@ -0,0 +1,94 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2009 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ * - GNU General Public License Version 2 or later (the "GPL")
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ * - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * - Mozilla Public License Version 1.1 or later (the "MPL")
+ * http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKShowBlockCommand Class: the "Show Blocks" command.
+ */
+
+var FCKShowBlockCommand = function( name, defaultState )
+{
+ this.Name = name ;
+ if ( defaultState != undefined )
+ this._SavedState = defaultState ;
+ else
+ this._SavedState = null ;
+}
+
+FCKShowBlockCommand.prototype.Execute = function()
+{
+ var state = this.GetState() ;
+
+ if ( state == FCK_TRISTATE_DISABLED )
+ return ;
+
+ var body = FCK.EditorDocument.body ;
+
+ if ( state == FCK_TRISTATE_ON )
+ body.className = body.className.replace( /(^| )FCK__ShowBlocks/g, '' ) ;
+ else
+ body.className += ' FCK__ShowBlocks' ;
+
+ if ( FCKBrowserInfo.IsIE )
+ {
+ try
+ {
+ FCK.EditorDocument.selection.createRange().select() ;
+ }
+ catch ( e )
+ {}
+ }
+ else
+ {
+ var focus = FCK.EditorWindow.getSelection().focusNode ;
+ if ( focus )
+ {
+ if ( focus.nodeType != 1 )
+ focus = focus.parentNode ;
+ FCKDomTools.ScrollIntoView( focus, false ) ;
+ }
+ }
+
+ FCK.Events.FireEvent( 'OnSelectionChange' ) ;
+}
+
+FCKShowBlockCommand.prototype.GetState = function()
+{
+ if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
+ return FCK_TRISTATE_DISABLED ;
+
+ // On some cases FCK.EditorDocument.body is not yet available
+ if ( !FCK.EditorDocument )
+ return FCK_TRISTATE_OFF ;
+
+ if ( /FCK__ShowBlocks(?:\s|$)/.test( FCK.EditorDocument.body.className ) )
+ return FCK_TRISTATE_ON ;
+
+ return FCK_TRISTATE_OFF ;
+}
+
+FCKShowBlockCommand.prototype.SaveState = function()
+{
+ this._SavedState = this.GetState() ;
+}
+
+FCKShowBlockCommand.prototype.RestoreState = function()
+{
+ if ( this._SavedState != null && this.GetState() != this._SavedState )
+ this.Execute() ;
+}
diff --git a/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckspellcheckcommand_gecko.js b/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckspellcheckcommand_gecko.js
new file mode 100644
index 0000000..4b3266b
--- /dev/null
+++ b/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckspellcheckcommand_gecko.js
@@ -0,0 +1,49 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2009 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ * - GNU General Public License Version 2 or later (the "GPL")
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ * - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * - Mozilla Public License Version 1.1 or later (the "MPL")
+ * http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKStyleCommand Class: represents the "Spell Check" command.
+ * (Gecko specific implementation)
+ */
+
+var FCKSpellCheckCommand = function()
+{
+ this.Name = 'SpellCheck' ;
+ this.IsEnabled = ( FCKConfig.SpellChecker != 'ieSpell' ) ;
+}
+
+FCKSpellCheckCommand.prototype.Execute = function()
+{
+ switch ( FCKConfig.SpellChecker )
+ {
+ case 'SpellerPages' :
+ FCKDialog.OpenDialog( 'FCKDialog_SpellCheck', 'Spell Check', 'dialog/fck_spellerpages.html', 440, 480 ) ;
+ break;
+
+ case 'WSC' :
+ FCKDialog.OpenDialog( 'FCKDialog_SpellCheck', 'Spell Check', 'wsc/w.html', 530, 480 ) ;
+ }
+}
+
+FCKSpellCheckCommand.prototype.GetState = function()
+{
+ if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
+ return FCK_TRISTATE_DISABLED ;
+ return this.IsEnabled ? FCK_TRISTATE_OFF : FCK_TRISTATE_DISABLED ;
+}
diff --git a/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckspellcheckcommand_ie.js b/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckspellcheckcommand_ie.js
new file mode 100644
index 0000000..e41bd2e
--- /dev/null
+++ b/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckspellcheckcommand_ie.js
@@ -0,0 +1,72 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2009 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ * - GNU General Public License Version 2 or later (the "GPL")
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ * - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * - Mozilla Public License Version 1.1 or later (the "MPL")
+ * http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKStyleCommand Class: represents the "Spell Check" command.
+ * (IE specific implementation)
+ */
+
+var FCKSpellCheckCommand = function()
+{
+ this.Name = 'SpellCheck' ;
+ this.IsEnabled = true ;
+}
+
+FCKSpellCheckCommand.prototype.Execute = function()
+{
+ switch ( FCKConfig.SpellChecker )
+ {
+ case 'ieSpell' :
+ this._RunIeSpell() ;
+ break ;
+
+ case 'SpellerPages' :
+ FCKDialog.OpenDialog( 'FCKDialog_SpellCheck', 'Spell Check', 'dialog/fck_spellerpages.html', 440, 480 ) ;
+ break ;
+
+ case 'WSC' :
+ FCKDialog.OpenDialog( 'FCKDialog_SpellCheck', 'Spell Check', 'wsc/w.html', 530, 480 ) ;
+ }
+}
+
+FCKSpellCheckCommand.prototype._RunIeSpell = function()
+{
+ try
+ {
+ var oIeSpell = new ActiveXObject( "ieSpell.ieSpellExtension" ) ;
+ oIeSpell.CheckAllLinkedDocuments( FCK.EditorDocument ) ;
+ }
+ catch( e )
+ {
+ if( e.number == -2146827859 )
+ {
+ if ( confirm( FCKLang.IeSpellDownload ) )
+ window.open( FCKConfig.IeSpellDownloadUrl , 'IeSpellDownload' ) ;
+ }
+ else
+ alert( 'Error Loading ieSpell: ' + e.message + ' (' + e.number + ')' ) ;
+ }
+}
+
+FCKSpellCheckCommand.prototype.GetState = function()
+{
+ if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
+ return FCK_TRISTATE_DISABLED ;
+ return this.IsEnabled ? FCK_TRISTATE_OFF : FCK_TRISTATE_DISABLED ;
+}
diff --git a/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckstylecommand.js b/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckstylecommand.js
new file mode 100644
index 0000000..dc220f4
--- /dev/null
+++ b/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fckstylecommand.js
@@ -0,0 +1,60 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2009 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ * - GNU General Public License Version 2 or later (the "GPL")
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ * - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * - Mozilla Public License Version 1.1 or later (the "MPL")
+ * http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKStyleCommand Class: represents the "Style" command.
+ */
+
+var FCKStyleCommand = function()
+{}
+
+FCKStyleCommand.prototype =
+{
+ Name : 'Style',
+
+ Execute : function( styleName, styleComboItem )
+ {
+ FCKUndo.SaveUndoStep() ;
+
+ if ( styleComboItem.Selected )
+ FCK.Styles.RemoveStyle( styleComboItem.Style ) ;
+ else
+ FCK.Styles.ApplyStyle( styleComboItem.Style ) ;
+
+ FCKUndo.SaveUndoStep() ;
+
+ FCK.Focus() ;
+ FCK.Events.FireEvent( 'OnSelectionChange' ) ;
+ },
+
+ GetState : function()
+ {
+ if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG || !FCK.EditorDocument )
+ return FCK_TRISTATE_DISABLED ;
+
+ if ( FCKSelection.GetType() == 'Control' )
+ {
+ var el = FCKSelection.GetSelectedElement() ;
+ if ( !el || !FCKStyles.CheckHasObjectStyle( el.nodeName.toLowerCase() ) )
+ return FCK_TRISTATE_DISABLED ;
+ }
+
+ return FCK_TRISTATE_OFF ;
+ }
+};
diff --git a/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fcktablecommand.js b/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fcktablecommand.js
new file mode 100644
index 0000000..dda446b
--- /dev/null
+++ b/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fcktablecommand.js
@@ -0,0 +1,106 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2009 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ * - GNU General Public License Version 2 or later (the "GPL")
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ * - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * - Mozilla Public License Version 1.1 or later (the "MPL")
+ * http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKPastePlainTextCommand Class: represents the
+ * "Paste as Plain Text" command.
+ */
+
+var FCKTableCommand = function( command )
+{
+ this.Name = command ;
+}
+
+FCKTableCommand.prototype.Execute = function()
+{
+ FCKUndo.SaveUndoStep() ;
+
+ if ( ! FCKBrowserInfo.IsGecko )
+ {
+ switch ( this.Name )
+ {
+ case 'TableMergeRight' :
+ return FCKTableHandler.MergeRight() ;
+ case 'TableMergeDown' :
+ return FCKTableHandler.MergeDown() ;
+ }
+ }
+
+ switch ( this.Name )
+ {
+ case 'TableInsertRowAfter' :
+ return FCKTableHandler.InsertRow( false ) ;
+ case 'TableInsertRowBefore' :
+ return FCKTableHandler.InsertRow( true ) ;
+ case 'TableDeleteRows' :
+ return FCKTableHandler.DeleteRows() ;
+ case 'TableInsertColumnAfter' :
+ return FCKTableHandler.InsertColumn( false ) ;
+ case 'TableInsertColumnBefore' :
+ return FCKTableHandler.InsertColumn( true ) ;
+ case 'TableDeleteColumns' :
+ return FCKTableHandler.DeleteColumns() ;
+ case 'TableInsertCellAfter' :
+ return FCKTableHandler.InsertCell( null, false ) ;
+ case 'TableInsertCellBefore' :
+ return FCKTableHandler.InsertCell( null, true ) ;
+ case 'TableDeleteCells' :
+ return FCKTableHandler.DeleteCells() ;
+ case 'TableMergeCells' :
+ return FCKTableHandler.MergeCells() ;
+ case 'TableHorizontalSplitCell' :
+ return FCKTableHandler.HorizontalSplitCell() ;
+ case 'TableVerticalSplitCell' :
+ return FCKTableHandler.VerticalSplitCell() ;
+ case 'TableDelete' :
+ return FCKTableHandler.DeleteTable() ;
+ default :
+ return alert( FCKLang.UnknownCommand.replace( /%1/g, this.Name ) ) ;
+ }
+}
+
+FCKTableCommand.prototype.GetState = function()
+{
+ if ( FCK.EditorDocument != null && FCKSelection.HasAncestorNode( 'TABLE' ) )
+ {
+ switch ( this.Name )
+ {
+ case 'TableHorizontalSplitCell' :
+ case 'TableVerticalSplitCell' :
+ if ( FCKTableHandler.GetSelectedCells().length == 1 )
+ return FCK_TRISTATE_OFF ;
+ else
+ return FCK_TRISTATE_DISABLED ;
+ case 'TableMergeCells' :
+ if ( FCKTableHandler.CheckIsSelectionRectangular()
+ && FCKTableHandler.GetSelectedCells().length > 1 )
+ return FCK_TRISTATE_OFF ;
+ else
+ return FCK_TRISTATE_DISABLED ;
+ case 'TableMergeRight' :
+ return FCKTableHandler.GetMergeRightTarget() ? FCK_TRISTATE_OFF : FCK_TRISTATE_DISABLED ;
+ case 'TableMergeDown' :
+ return FCKTableHandler.GetMergeDownTarget() ? FCK_TRISTATE_OFF : FCK_TRISTATE_DISABLED ;
+ default :
+ return FCK_TRISTATE_OFF ;
+ }
+ }
+ else
+ return FCK_TRISTATE_DISABLED;
+}
diff --git a/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fcktextcolorcommand.js b/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fcktextcolorcommand.js
new file mode 100644
index 0000000..dccd794
--- /dev/null
+++ b/rt/share/html/NoAuth/RichText/FCKeditor/editor/_source/commandclasses/fcktextcolorcommand.js
@@ -0,0 +1,201 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2009 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ * - GNU General Public License Version 2 or later (the "GPL")
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ * - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * - Mozilla Public License Version 1.1 or later (the "MPL")
+ * http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * FCKTextColorCommand Class: represents the text color comand. It shows the
+ * color selection panel.
+ */
+
+// FCKTextColorCommand Constructor
+// type: can be 'ForeColor' or 'BackColor'.
+var FCKTextColorCommand = function( type )
+{
+ this.Name = type == 'ForeColor' ? 'TextColor' : 'BGColor' ;
+ this.Type = type ;
+
+ var oWindow ;
+
+ if ( FCKBrowserInfo.IsIE )
+ oWindow = window ;
+ else if ( FCK.ToolbarSet._IFrame )
+ oWindow = FCKTools.GetElementWindow( FCK.ToolbarSet._IFrame ) ;
+ else
+ oWindow = window.parent ;
+
+ this._Panel = new FCKPanel( oWindow ) ;
+ this._Panel.AppendStyleSheet( FCKConfig.SkinEditorCSS ) ;
+ this._Panel.MainNode.className = 'FCK_Panel' ;
+ this._CreatePanelBody( this._Panel.Document, this._Panel.MainNode ) ;
+ FCK.ToolbarSet.ToolbarItems.GetItem( this.Name ).RegisterPanel( this._Panel ) ;
+
+ FCKTools.DisableSelection( this._Panel.Document.body ) ;
+}
+
+FCKTextColorCommand.prototype.Execute = function( panelX, panelY, relElement )
+{
+ // Show the Color Panel at the desired position.
+ this._Panel.Show( panelX, panelY, relElement ) ;
+}
+
+FCKTextColorCommand.prototype.SetColor = function( color )
+{
+ FCKUndo.SaveUndoStep() ;
+
+ var style = FCKStyles.GetStyle( '_FCK_' +
+ ( this.Type == 'ForeColor' ? 'Color' : 'BackColor' ) ) ;
+
+ if ( !color || color.length == 0 )
+ FCK.Styles.RemoveStyle( style ) ;
+ else
+ {
+ style.SetVariable( 'Color', color ) ;
+ FCKStyles.ApplyStyle( style ) ;
+ }
+
+ FCKUndo.SaveUndoStep() ;
+
+ FCK.Focus() ;
+ FCK.Events.FireEvent( 'OnSelectionChange' ) ;
+}
+
+FCKTextColorCommand.prototype.GetState = function()
+{
+ if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )
+ return FCK_TRISTATE_DISABLED ;
+ return FCK_TRISTATE_OFF ;
+}
+
+function FCKTextColorCommand_OnMouseOver()
+{
+ this.className = 'ColorSelected' ;
+}
+
+function FCKTextColorCommand_OnMouseOut()
+{
+ this.className = 'ColorDeselected' ;
+}
+
+function FCKTextColorCommand_OnClick( ev, command, color )
+{
+ this.className = 'ColorDeselected' ;
+ command.SetColor( color ) ;
+ command._Panel.Hide() ;
+}
+
+function FCKTextColorCommand_AutoOnClick( ev, command )
+{
+ this.className = 'ColorDeselected' ;
+ command.SetColor( '' ) ;
+ command._Panel.Hide() ;
+}
+
+function FCKTextColorCommand_MoreOnClick( ev, command )
+{
+ this.className = 'ColorDeselected' ;
+ command._Panel.Hide() ;
+ FCKDialog.OpenDialog( 'FCKDialog_Color', FCKLang.DlgColorTitle, 'dialog/fck_colorselector.html', 410, 320,
+ FCKTools.Bind( command, command.SetColor ) ) ;
+}
+
+FCKTextColorCommand.prototype._CreatePanelBody = function( targetDocument, targetDiv )
+{
+ function CreateSelectionDiv()
+ {
+ var oDiv = targetDocument.createElement( "DIV" ) ;
+ oDiv.className = 'ColorDeselected' ;
+ FCKTools.AddEventListenerEx( oDiv, 'mouseover', FCKTextColorCommand_OnMouseOver ) ;
+ FCKTools.AddEventListenerEx( oDiv, 'mouseout', FCKTextColorCommand_OnMouseOut ) ;
+
+ return oDiv ;
+ }
+
+ // Create the Table that will hold all colors.
+ var oTable = targetDiv.appendChild( targetDocument.createElement( "TABLE" ) ) ;
+ oTable.className = 'ForceBaseFont' ; // Firefox 1.5 Bug.
+ oTable.style.tableLayout = 'fixed' ;
+ oTable.cellPadding = 0 ;
+ oTable.cellSpacing = 0 ;
+ oTable.border = 0 ;
+ oTable.width = 150 ;
+
+ var oCell = oTable.insertRow(-1).insertCell(-1) ;
+ oCell.colSpan = 8 ;
+
+ // Create the Button for the "Automatic" color selection.
+ var oDiv = oCell.appendChild( CreateSelectionDiv() ) ;
+ oDiv.innerHTML =
+ '<table cellspacing="0" cellpadding="0" width="100%" border="0">\
+ <tr>\
+ <td><div class="ColorBoxBorder"><div class="ColorBox" style="background-color: #000000"></div></div></td>\
+ <td nowrap width="100%" align="center">' + FCKLang.ColorAutomatic + '</td>\
+ </tr>\
+ </table>' ;
+
+ FCKTools.AddEventListenerEx( oDiv, 'click', FCKTextColorCommand_AutoOnClick, this ) ;
+
+ // Dirty hack for Opera, Safari and Firefox 3.
+ if ( !FCKBrowserInfo.IsIE )
+ oDiv.style.width = '96%' ;
+
+ // Create an array of colors based on the configuration file.
+ var aColors = FCKConfig.FontColors.toString().split(',') ;
+
+ // Create the colors table based on the array.
+ var iCounter = 0 ;
+ while ( iCounter < aColors.length )
+ {
+ var oRow = oTable.insertRow(-1) ;
+
+ for ( var i = 0 ; i < 8 ; i++, iCounter++ )
+ {
+ // The div will be created even if no more colors are available.
+ // Extra divs will be hidden later in the code. (#1597)
+ if ( iCounter < aColors.length )
+ {
+ var colorParts = aColors[iCounter].split('/') ;
+ var colorValue = '#' + colorParts[0] ;
+ var colorName = colorParts[1] || colorValue ;
+ }
+
+ oDiv = oRow.insertCell(-1).appendChild( CreateSelectionDiv() ) ;
+ oDiv.innerHTML = '<div class="ColorBoxBorder"><div class="ColorBox" style="background-color: ' + colorValue + '"></div></div>' ;
+
+ if ( iCounter >= aColors.length )
+ oDiv.style.visibility = 'hidden' ;
+ else
+ FCKTools.AddEventListenerEx( oDiv, 'click', FCKTextColorCommand_OnClick, [ this, colorName ] ) ;
+ }
+ }
+
+ // Create the Row and the Cell for the "More Colors..." button.
+ if ( FCKConfig.EnableMoreFontColors )
+ {
+ oCell = oTable.insertRow(-1).insertCell(-1) ;
+ oCell.colSpan = 8 ;
+
+ oDiv = oCell.appendChild( CreateSelectionDiv() ) ;
+ oDiv.innerHTML = '<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td nowrap align="center">' + FCKLang.ColorMoreColors + '</td></tr></table>' ;
+
+ FCKTools.AddEventListenerEx( oDiv, 'click', FCKTextColorCommand_MoreOnClick, this ) ;
+ }
+
+ // Dirty hack for Opera, Safari and Firefox 3.
+ if ( !FCKBrowserInfo.IsIE )
+ oDiv.style.width = '96%' ;
+}