+++ /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
- * Creation and initialization of the "FCK" object. This is the main object\r
- * that represents an editor instance.\r
- */\r
-\r
-// FCK represents the active editor instance.\r
-var FCK =\r
-{\r
- Name : FCKURLParams[ 'InstanceName' ],\r
- Status : FCK_STATUS_NOTLOADED,\r
- EditMode : FCK_EDITMODE_WYSIWYG,\r
- Toolbar : null,\r
- HasFocus : false,\r
- DataProcessor : new FCKDataProcessor(),\r
-\r
- GetInstanceObject : (function()\r
- {\r
- var w = window ;\r
- return function( name )\r
- {\r
- return w[name] ;\r
- }\r
- })(),\r
-\r
- AttachToOnSelectionChange : function( functionPointer )\r
- {\r
- this.Events.AttachEvent( 'OnSelectionChange', functionPointer ) ;\r
- },\r
-\r
- GetLinkedFieldValue : function()\r
- {\r
- return this.LinkedField.value ;\r
- },\r
-\r
- GetParentForm : function()\r
- {\r
- return this.LinkedField.form ;\r
- } ,\r
-\r
- // # START : IsDirty implementation\r
-\r
- StartupValue : '',\r
-\r
- IsDirty : function()\r
- {\r
- if ( this.EditMode == FCK_EDITMODE_SOURCE )\r
- return ( this.StartupValue != this.EditingArea.Textarea.value ) ;\r
- else\r
- {\r
- // It can happen switching between design and source mode in Gecko\r
- if ( ! this.EditorDocument )\r
- return false ;\r
-\r
- return ( this.StartupValue != this.EditorDocument.body.innerHTML ) ;\r
- }\r
- },\r
-\r
- ResetIsDirty : function()\r
- {\r
- if ( this.EditMode == FCK_EDITMODE_SOURCE )\r
- this.StartupValue = this.EditingArea.Textarea.value ;\r
- else if ( this.EditorDocument.body )\r
- this.StartupValue = this.EditorDocument.body.innerHTML ;\r
- },\r
-\r
- // # END : IsDirty implementation\r
-\r
- StartEditor : function()\r
- {\r
- this.TempBaseTag = FCKConfig.BaseHref.length > 0 ? '<base href="' + FCKConfig.BaseHref + '" _fcktemp="true"></base>' : '' ;\r
-\r
- // Setup the keystroke handler.\r
- var oKeystrokeHandler = FCK.KeystrokeHandler = new FCKKeystrokeHandler() ;\r
- oKeystrokeHandler.OnKeystroke = _FCK_KeystrokeHandler_OnKeystroke ;\r
-\r
- // Set the config keystrokes.\r
- oKeystrokeHandler.SetKeystrokes( FCKConfig.Keystrokes ) ;\r
-\r
- // In IE7, if the editor tries to access the clipboard by code, a dialog is\r
- // shown to the user asking if the application is allowed to access or not.\r
- // Due to the IE implementation of it, the KeystrokeHandler will not work\r
- //well in this case, so we must leave the pasting keys to have their default behavior.\r
- if ( FCKBrowserInfo.IsIE7 )\r
- {\r
- if ( ( CTRL + 86 /*V*/ ) in oKeystrokeHandler.Keystrokes )\r
- oKeystrokeHandler.SetKeystrokes( [ CTRL + 86, true ] ) ;\r
-\r
- if ( ( SHIFT + 45 /*INS*/ ) in oKeystrokeHandler.Keystrokes )\r
- oKeystrokeHandler.SetKeystrokes( [ SHIFT + 45, true ] ) ;\r
- }\r
-\r
- // Retain default behavior for Ctrl-Backspace. (Bug #362)\r
- oKeystrokeHandler.SetKeystrokes( [ CTRL + 8, true ] ) ;\r
-\r
- this.EditingArea = new FCKEditingArea( document.getElementById( 'xEditingArea' ) ) ;\r
- this.EditingArea.FFSpellChecker = FCKConfig.FirefoxSpellChecker ;\r
-\r
- // Set the editor's startup contents.\r
- this.SetData( this.GetLinkedFieldValue(), true ) ;\r
-\r
- // Tab key handling for source mode.\r
- FCKTools.AddEventListener( document, "keydown", this._TabKeyHandler ) ;\r
-\r
- // Add selection change listeners. They must be attached only once.\r
- this.AttachToOnSelectionChange( _FCK_PaddingNodeListener ) ;\r
- if ( FCKBrowserInfo.IsGecko )\r
- this.AttachToOnSelectionChange( this._ExecCheckEmptyBlock ) ;\r
-\r
- },\r
-\r
- Focus : function()\r
- {\r
- FCK.EditingArea.Focus() ;\r
- },\r
-\r
- SetStatus : function( newStatus )\r
- {\r
- this.Status = newStatus ;\r
-\r
- if ( newStatus == FCK_STATUS_ACTIVE )\r
- {\r
- FCKFocusManager.AddWindow( window, true ) ;\r
-\r
- if ( FCKBrowserInfo.IsIE )\r
- FCKFocusManager.AddWindow( window.frameElement, true ) ;\r
-\r
- // Force the focus in the editor.\r
- if ( FCKConfig.StartupFocus )\r
- FCK.Focus() ;\r
- }\r
-\r
- this.Events.FireEvent( 'OnStatusChange', newStatus ) ;\r
-\r
- },\r
-\r
- // Fixes the body by moving all inline and text nodes to appropriate block\r
- // elements.\r
- FixBody : function()\r
- {\r
- var sBlockTag = FCKConfig.EnterMode ;\r
-\r
- // In 'br' mode, no fix must be done.\r
- if ( sBlockTag != 'p' && sBlockTag != 'div' )\r
- return ;\r
-\r
- var oDocument = this.EditorDocument ;\r
-\r
- if ( !oDocument )\r
- return ;\r
-\r
- var oBody = oDocument.body ;\r
-\r
- if ( !oBody )\r
- return ;\r
-\r
- FCKDomTools.TrimNode( oBody ) ;\r
-\r
- var oNode = oBody.firstChild ;\r
- var oNewBlock ;\r
-\r
- while ( oNode )\r
- {\r
- var bMoveNode = false ;\r
-\r
- switch ( oNode.nodeType )\r
- {\r
- // Element Node.\r
- case 1 :\r
- var nodeName = oNode.nodeName.toLowerCase() ;\r
- if ( !FCKListsLib.BlockElements[ nodeName ] &&\r
- nodeName != 'li' &&\r
- !oNode.getAttribute('_fckfakelement') &&\r
- oNode.getAttribute('_moz_dirty') == null )\r
- bMoveNode = true ;\r
- break ;\r
-\r
- // Text Node.\r
- case 3 :\r
- // Ignore space only or empty text.\r
- if ( oNewBlock || oNode.nodeValue.Trim().length > 0 )\r
- bMoveNode = true ;\r
- break;\r
-\r
- // Comment Node\r
- case 8 :\r
- if ( oNewBlock )\r
- bMoveNode = true ;\r
- break;\r
- }\r
-\r
- if ( bMoveNode )\r
- {\r
- var oParent = oNode.parentNode ;\r
-\r
- if ( !oNewBlock )\r
- oNewBlock = oParent.insertBefore( oDocument.createElement( sBlockTag ), oNode ) ;\r
-\r
- oNewBlock.appendChild( oParent.removeChild( oNode ) ) ;\r
-\r
- oNode = oNewBlock.nextSibling ;\r
- }\r
- else\r
- {\r
- if ( oNewBlock )\r
- {\r
- FCKDomTools.TrimNode( oNewBlock ) ;\r
- oNewBlock = null ;\r
- }\r
- oNode = oNode.nextSibling ;\r
- }\r
- }\r
-\r
- if ( oNewBlock )\r
- FCKDomTools.TrimNode( oNewBlock ) ;\r
- },\r
-\r
- GetData : function( format )\r
- {\r
- // We assume that if the user is in source editing, the editor value must\r
- // represent the exact contents of the source, as the user wanted it to be.\r
- if ( FCK.EditMode == FCK_EDITMODE_SOURCE )\r
- return FCK.EditingArea.Textarea.value ;\r
-\r
- this.FixBody() ;\r
-\r
- var oDoc = FCK.EditorDocument ;\r
- if ( !oDoc )\r
- return null ;\r
-\r
- var isFullPage = FCKConfig.FullPage ;\r
-\r
- // Call the Data Processor to generate the output data.\r
- var data = FCK.DataProcessor.ConvertToDataFormat(\r
- isFullPage ? oDoc.documentElement : oDoc.body,\r
- !isFullPage,\r
- FCKConfig.IgnoreEmptyParagraphValue,\r
- format ) ;\r
-\r
- // Restore protected attributes.\r
- data = FCK.ProtectEventsRestore( data ) ;\r
-\r
- if ( FCKBrowserInfo.IsIE )\r
- data = data.replace( FCKRegexLib.ToReplace, '$1' ) ;\r
-\r
- if ( isFullPage )\r
- {\r
- if ( FCK.DocTypeDeclaration && FCK.DocTypeDeclaration.length > 0 )\r
- data = FCK.DocTypeDeclaration + '\n' + data ;\r
-\r
- if ( FCK.XmlDeclaration && FCK.XmlDeclaration.length > 0 )\r
- data = FCK.XmlDeclaration + '\n' + data ;\r
- }\r
-\r
- return FCKConfig.ProtectedSource.Revert( data ) ;\r
- },\r
-\r
- UpdateLinkedField : function()\r
- {\r
- var value = FCK.GetXHTML( FCKConfig.FormatOutput ) ;\r
-\r
- if ( FCKConfig.HtmlEncodeOutput )\r
- value = FCKTools.HTMLEncode( value ) ;\r
-\r
- FCK.LinkedField.value = value ;\r
- FCK.Events.FireEvent( 'OnAfterLinkedFieldUpdate' ) ;\r
- },\r
-\r
- RegisteredDoubleClickHandlers : new Object(),\r
-\r
- OnDoubleClick : function( element )\r
- {\r
- var oCalls = FCK.RegisteredDoubleClickHandlers[ element.tagName.toUpperCase() ] ;\r
-\r
- if ( oCalls )\r
- {\r
- for ( var i = 0 ; i < oCalls.length ; i++ )\r
- oCalls[ i ]( element ) ;\r
- }\r
-\r
- // Generic handler for any element\r
- oCalls = FCK.RegisteredDoubleClickHandlers[ '*' ] ;\r
-\r
- if ( oCalls )\r
- {\r
- for ( var i = 0 ; i < oCalls.length ; i++ )\r
- oCalls[ i ]( element ) ;\r
- }\r
-\r
- },\r
-\r
- // Register objects that can handle double click operations.\r
- RegisterDoubleClickHandler : function( handlerFunction, tag )\r
- {\r
- var nodeName = tag || '*' ;\r
- nodeName = nodeName.toUpperCase() ;\r
-\r
- var aTargets ;\r
-\r
- if ( !( aTargets = FCK.RegisteredDoubleClickHandlers[ nodeName ] ) )\r
- FCK.RegisteredDoubleClickHandlers[ nodeName ] = [ handlerFunction ] ;\r
- else\r
- {\r
- // Check that the event handler isn't already registered with the same listener\r
- // It doesn't detect function pointers belonging to an object (at least in Gecko)\r
- if ( aTargets.IndexOf( handlerFunction ) == -1 )\r
- aTargets.push( handlerFunction ) ;\r
- }\r
-\r
- },\r
-\r
- OnAfterSetHTML : function()\r
- {\r
- FCKDocumentProcessor.Process( FCK.EditorDocument ) ;\r
- FCKUndo.SaveUndoStep() ;\r
-\r
- FCK.Events.FireEvent( 'OnSelectionChange' ) ;\r
- FCK.Events.FireEvent( 'OnAfterSetHTML' ) ;\r
- },\r
-\r
- // Saves URLs on links and images on special attributes, so they don't change when\r
- // moving around.\r
- ProtectUrls : function( html )\r
- {\r
- // <A> href\r
- html = html.replace( FCKRegexLib.ProtectUrlsA , '$& _fcksavedurl=$1' ) ;\r
-\r
- // <IMG> src\r
- html = html.replace( FCKRegexLib.ProtectUrlsImg , '$& _fcksavedurl=$1' ) ;\r
-\r
- // <AREA> href\r
- html = html.replace( FCKRegexLib.ProtectUrlsArea , '$& _fcksavedurl=$1' ) ;\r
-\r
- return html ;\r
- },\r
-\r
- // Saves event attributes (like onclick) so they don't get executed while\r
- // editing.\r
- ProtectEvents : function( html )\r
- {\r
- return html.replace( FCKRegexLib.TagsWithEvent, _FCK_ProtectEvents_ReplaceTags ) ;\r
- },\r
-\r
- ProtectEventsRestore : function( html )\r
- {\r
- return html.replace( FCKRegexLib.ProtectedEvents, _FCK_ProtectEvents_RestoreEvents ) ;\r
- },\r
-\r
- ProtectTags : function( html )\r
- {\r
- var sTags = FCKConfig.ProtectedTags ;\r
-\r
- // IE doesn't support <abbr> and it breaks it. Let's protect it.\r
- if ( FCKBrowserInfo.IsIE )\r
- sTags += sTags.length > 0 ? '|ABBR|XML|EMBED|OBJECT' : 'ABBR|XML|EMBED|OBJECT' ;\r
-\r
- var oRegex ;\r
- if ( sTags.length > 0 )\r
- {\r
- oRegex = new RegExp( '<(' + sTags + ')(?!\w|:)', 'gi' ) ;\r
- html = html.replace( oRegex, '<FCK:$1' ) ;\r
-\r
- oRegex = new RegExp( '<\/(' + sTags + ')>', 'gi' ) ;\r
- html = html.replace( oRegex, '<\/FCK:$1>' ) ;\r
- }\r
-\r
- // Protect some empty elements. We must do it separately because the\r
- // original tag may not contain the closing slash, like <hr>:\r
- // - <meta> tags get executed, so if you have a redirect meta, the\r
- // content will move to the target page.\r
- // - <hr> may destroy the document structure if not well\r
- // positioned. The trick is protect it here and restore them in\r
- // the FCKDocumentProcessor.\r
- sTags = 'META' ;\r
- if ( FCKBrowserInfo.IsIE )\r
- sTags += '|HR' ;\r
-\r
- oRegex = new RegExp( '<((' + sTags + ')(?=\\s|>|/)[\\s\\S]*?)/?>', 'gi' ) ;\r
- html = html.replace( oRegex, '<FCK:$1 />' ) ;\r
-\r
- return html ;\r
- },\r
-\r
- SetData : function( data, resetIsDirty )\r
- {\r
- this.EditingArea.Mode = FCK.EditMode ;\r
-\r
- // If there was an onSelectionChange listener in IE we must remove it to avoid crashes #1498\r
- if ( FCKBrowserInfo.IsIE && FCK.EditorDocument )\r
- {\r
- FCK.EditorDocument.detachEvent("onselectionchange", Doc_OnSelectionChange ) ;\r
- }\r
-\r
- FCKTempBin.Reset() ;\r
-\r
- // Bug #2469: SelectionData.createRange becomes undefined after the editor\r
- // iframe is changed by FCK.SetData().\r
- FCK.Selection.Release() ;\r
-\r
- if ( FCK.EditMode == FCK_EDITMODE_WYSIWYG )\r
- {\r
- // Save the resetIsDirty for later use (async)\r
- this._ForceResetIsDirty = ( resetIsDirty === true ) ;\r
-\r
- // Protect parts of the code that must remain untouched (and invisible)\r
- // during editing.\r
- data = FCKConfig.ProtectedSource.Protect( data ) ;\r
-\r
- // Call the Data Processor to transform the data.\r
- data = FCK.DataProcessor.ConvertToHtml( data ) ;\r
-\r
- // Fix for invalid self-closing tags (see #152).\r
- data = data.replace( FCKRegexLib.InvalidSelfCloseTags, '$1></$2>' ) ;\r
-\r
- // Protect event attributes (they could get fired in the editing area).\r
- data = FCK.ProtectEvents( data ) ;\r
-\r
- // Protect some things from the browser itself.\r
- data = FCK.ProtectUrls( data ) ;\r
- data = FCK.ProtectTags( data ) ;\r
-\r
- // Insert the base tag (FCKConfig.BaseHref), if not exists in the source.\r
- // The base must be the first tag in the HEAD, to get relative\r
- // links on styles, for example.\r
- if ( FCK.TempBaseTag.length > 0 && !FCKRegexLib.HasBaseTag.test( data ) )\r
- data = data.replace( FCKRegexLib.HeadOpener, '$&' + FCK.TempBaseTag ) ;\r
-\r
- // Build the HTML for the additional things we need on <head>.\r
- var sHeadExtra = '' ;\r
-\r
- if ( !FCKConfig.FullPage )\r
- sHeadExtra += _FCK_GetEditorAreaStyleTags() ;\r
-\r
- if ( FCKBrowserInfo.IsIE )\r
- sHeadExtra += FCK._GetBehaviorsStyle() ;\r
- else if ( FCKConfig.ShowBorders )\r
- sHeadExtra += FCKTools.GetStyleHtml( FCK_ShowTableBordersCSS, true ) ;\r
-\r
- sHeadExtra += FCKTools.GetStyleHtml( FCK_InternalCSS, true ) ;\r
-\r
- // Attention: do not change it before testing it well (sample07)!\r
- // This is tricky... if the head ends with <meta ... content type>,\r
- // Firefox will break. But, it works if we place our extra stuff as\r
- // the last elements in the HEAD.\r
- data = data.replace( FCKRegexLib.HeadCloser, sHeadExtra + '$&' ) ;\r
-\r
- // Load the HTML in the editing area.\r
- this.EditingArea.OnLoad = _FCK_EditingArea_OnLoad ;\r
- this.EditingArea.Start( data ) ;\r
- }\r
- else\r
- {\r
- // Remove the references to the following elements, as the editing area\r
- // IFRAME will be removed.\r
- FCK.EditorWindow = null ;\r
- FCK.EditorDocument = null ;\r
- FCKDomTools.PaddingNode = null ;\r
-\r
- this.EditingArea.OnLoad = null ;\r
- this.EditingArea.Start( data ) ;\r
-\r
- // Enables the context menu in the textarea.\r
- this.EditingArea.Textarea._FCKShowContextMenu = true ;\r
-\r
- // Removes the enter key handler.\r
- FCK.EnterKeyHandler = null ;\r
-\r
- if ( resetIsDirty )\r
- this.ResetIsDirty() ;\r
-\r
- // Listen for keystroke events.\r
- FCK.KeystrokeHandler.AttachToElement( this.EditingArea.Textarea ) ;\r
-\r
- this.EditingArea.Textarea.focus() ;\r
-\r
- FCK.Events.FireEvent( 'OnAfterSetHTML' ) ;\r
- }\r
-\r
- if ( FCKBrowserInfo.IsGecko )\r
- window.onresize() ;\r
- },\r
-\r
- // This collection is used by the browser specific implementations to tell\r
- // which named commands must be handled separately.\r
- RedirectNamedCommands : new Object(),\r
-\r
- ExecuteNamedCommand : function( commandName, commandParameter, noRedirect, noSaveUndo )\r
- {\r
- if ( !noSaveUndo )\r
- FCKUndo.SaveUndoStep() ;\r
-\r
- if ( !noRedirect && FCK.RedirectNamedCommands[ commandName ] != null )\r
- FCK.ExecuteRedirectedNamedCommand( commandName, commandParameter ) ;\r
- else\r
- {\r
- FCK.Focus() ;\r
- FCK.EditorDocument.execCommand( commandName, false, commandParameter ) ;\r
- FCK.Events.FireEvent( 'OnSelectionChange' ) ;\r
- }\r
-\r
- if ( !noSaveUndo )\r
- FCKUndo.SaveUndoStep() ;\r
- },\r
-\r
- GetNamedCommandState : function( commandName )\r
- {\r
- try\r
- {\r
-\r
- // Bug #50 : Safari never returns positive state for the Paste command, override that.\r
- if ( FCKBrowserInfo.IsSafari && FCK.EditorWindow && commandName.IEquals( 'Paste' ) )\r
- return FCK_TRISTATE_OFF ;\r
-\r
- if ( !FCK.EditorDocument.queryCommandEnabled( commandName ) )\r
- return FCK_TRISTATE_DISABLED ;\r
- else\r
- {\r
- return FCK.EditorDocument.queryCommandState( commandName ) ? FCK_TRISTATE_ON : FCK_TRISTATE_OFF ;\r
- }\r
- }\r
- catch ( e )\r
- {\r
- return FCK_TRISTATE_OFF ;\r
- }\r
- },\r
-\r
- GetNamedCommandValue : function( commandName )\r
- {\r
- var sValue = '' ;\r
- var eState = FCK.GetNamedCommandState( commandName ) ;\r
-\r
- if ( eState == FCK_TRISTATE_DISABLED )\r
- return null ;\r
-\r
- try\r
- {\r
- sValue = this.EditorDocument.queryCommandValue( commandName ) ;\r
- }\r
- catch(e) {}\r
-\r
- return sValue ? sValue : '' ;\r
- },\r
-\r
- Paste : function( _callListenersOnly )\r
- {\r
- // First call 'OnPaste' listeners.\r
- if ( FCK.Status != FCK_STATUS_COMPLETE || !FCK.Events.FireEvent( 'OnPaste' ) )\r
- return false ;\r
-\r
- // Then call the default implementation.\r
- return _callListenersOnly || FCK._ExecPaste() ;\r
- },\r
-\r
- PasteFromWord : function()\r
- {\r
- FCKDialog.OpenDialog( 'FCKDialog_Paste', FCKLang.PasteFromWord, 'dialog/fck_paste.html', 400, 330, 'Word' ) ;\r
- },\r
-\r
- Preview : function()\r
- {\r
- var sHTML ;\r
-\r
- if ( FCKConfig.FullPage )\r
- {\r
- if ( FCK.TempBaseTag.length > 0 )\r
- sHTML = FCK.TempBaseTag + FCK.GetXHTML() ;\r
- else\r
- sHTML = FCK.GetXHTML() ;\r
- }\r
- else\r
- {\r
- sHTML =\r
- FCKConfig.DocType +\r
- '<html dir="' + FCKConfig.ContentLangDirection + '">' +\r
- '<head>' +\r
- FCK.TempBaseTag +\r
- '<title>' + FCKLang.Preview + '</title>' +\r
- _FCK_GetEditorAreaStyleTags() +\r
- '</head><body' + FCKConfig.GetBodyAttributes() + '>' +\r
- FCK.GetXHTML() +\r
- '</body></html>' ;\r
- }\r
-\r
- var iWidth = FCKConfig.ScreenWidth * 0.8 ;\r
- var iHeight = FCKConfig.ScreenHeight * 0.7 ;\r
- var iLeft = ( FCKConfig.ScreenWidth - iWidth ) / 2 ;\r
-\r
- var sOpenUrl = '' ;\r
- if ( FCK_IS_CUSTOM_DOMAIN && FCKBrowserInfo.IsIE)\r
- {\r
- window._FCKHtmlToLoad = sHTML ;\r
- sOpenUrl = 'javascript:void( (function(){' +\r
- 'document.open() ;' +\r
- 'document.domain="' + document.domain + '" ;' +\r
- 'document.write( window.opener._FCKHtmlToLoad );' +\r
- 'document.close() ;' +\r
- 'window.opener._FCKHtmlToLoad = null ;' +\r
- '})() )' ;\r
- }\r
-\r
- var oWindow = window.open( sOpenUrl, null, 'toolbar=yes,location=no,status=yes,menubar=yes,scrollbars=yes,resizable=yes,width=' + iWidth + ',height=' + iHeight + ',left=' + iLeft ) ;\r
-\r
- if ( !FCK_IS_CUSTOM_DOMAIN || !FCKBrowserInfo.IsIE)\r
- {\r
- oWindow.document.write( sHTML );\r
- oWindow.document.close();\r
- }\r
-\r
- },\r
-\r
- SwitchEditMode : function( noUndo )\r
- {\r
- var bIsWysiwyg = ( FCK.EditMode == FCK_EDITMODE_WYSIWYG ) ;\r
-\r
- // Save the current IsDirty state, so we may restore it after the switch.\r
- var bIsDirty = FCK.IsDirty() ;\r
-\r
- var sHtml ;\r
-\r
- // Update the HTML in the view output to show, also update\r
- // FCKTempBin for IE to avoid #2263.\r
- if ( bIsWysiwyg )\r
- {\r
- FCKCommands.GetCommand( 'ShowBlocks' ).SaveState() ;\r
- if ( !noUndo && FCKBrowserInfo.IsIE )\r
- FCKUndo.SaveUndoStep() ;\r
-\r
- sHtml = FCK.GetXHTML( FCKConfig.FormatSource ) ;\r
-\r
- if ( FCKBrowserInfo.IsIE )\r
- FCKTempBin.ToHtml() ;\r
-\r
- if ( sHtml == null )\r
- return false ;\r
- }\r
- else\r
- sHtml = this.EditingArea.Textarea.value ;\r
-\r
- FCK.EditMode = bIsWysiwyg ? FCK_EDITMODE_SOURCE : FCK_EDITMODE_WYSIWYG ;\r
-\r
- FCK.SetData( sHtml, !bIsDirty ) ;\r
-\r
- // Set the Focus.\r
- FCK.Focus() ;\r
-\r
- // Update the toolbar (Running it directly causes IE to fail).\r
- FCKTools.RunFunction( FCK.ToolbarSet.RefreshModeState, FCK.ToolbarSet ) ;\r
-\r
- return true ;\r
- },\r
-\r
- InsertElement : function( element )\r
- {\r
- // The parameter may be a string (element name), so transform it in an element.\r
- if ( typeof element == 'string' )\r
- element = this.EditorDocument.createElement( element ) ;\r
-\r
- var elementName = element.nodeName.toLowerCase() ;\r
-\r
- FCKSelection.Restore() ;\r
-\r
- // Create a range for the selection. V3 will have a new selection\r
- // object that may internally supply this feature.\r
- var range = new FCKDomRange( this.EditorWindow ) ;\r
-\r
- // Move to the selection and delete it.\r
- range.MoveToSelection() ;\r
- range.DeleteContents() ;\r
-\r
- if ( FCKListsLib.BlockElements[ elementName ] != null )\r
- {\r
- if ( range.StartBlock )\r
- {\r
- if ( range.CheckStartOfBlock() )\r
- range.MoveToPosition( range.StartBlock, 3 ) ;\r
- else if ( range.CheckEndOfBlock() )\r
- range.MoveToPosition( range.StartBlock, 4 ) ;\r
- else\r
- range.SplitBlock() ;\r
- }\r
-\r
- range.InsertNode( element ) ;\r
-\r
- var next = FCKDomTools.GetNextSourceElement( element, false, null, [ 'hr','br','param','img','area','input' ], true ) ;\r
-\r
- // Be sure that we have something after the new element, so we can move the cursor there.\r
- if ( !next && FCKConfig.EnterMode != 'br')\r
- {\r
- next = this.EditorDocument.body.appendChild( this.EditorDocument.createElement( FCKConfig.EnterMode ) ) ;\r
-\r
- if ( FCKBrowserInfo.IsGeckoLike )\r
- FCKTools.AppendBogusBr( next ) ;\r
- }\r
-\r
- if ( FCKListsLib.EmptyElements[ elementName ] == null )\r
- range.MoveToElementEditStart( element ) ;\r
- else if ( next )\r
- range.MoveToElementEditStart( next ) ;\r
- else\r
- range.MoveToPosition( element, 4 ) ;\r
-\r
- if ( FCKBrowserInfo.IsGeckoLike )\r
- {\r
- if ( next )\r
- FCKDomTools.ScrollIntoView( next, false );\r
- FCKDomTools.ScrollIntoView( element, false );\r
- }\r
- }\r
- else\r
- {\r
- // Insert the node.\r
- range.InsertNode( element ) ;\r
-\r
- // Move the selection right after the new element.\r
- // DISCUSSION: Should we select the element instead?\r
- range.SetStart( element, 4 ) ;\r
- range.SetEnd( element, 4 ) ;\r
- }\r
-\r
- range.Select() ;\r
- range.Release() ;\r
-\r
- // REMOVE IT: The focus should not really be set here. It is up to the\r
- // calling code to reset the focus if needed.\r
- this.Focus() ;\r
-\r
- return element ;\r
- },\r
-\r
- _InsertBlockElement : function( blockElement )\r
- {\r
- },\r
-\r
- _IsFunctionKey : function( keyCode )\r
- {\r
- // keys that are captured but do not change editor contents\r
- if ( keyCode >= 16 && keyCode <= 20 )\r
- // shift, ctrl, alt, pause, capslock\r
- return true ;\r
- if ( keyCode == 27 || ( keyCode >= 33 && keyCode <= 40 ) )\r
- // esc, page up, page down, end, home, left, up, right, down\r
- return true ;\r
- if ( keyCode == 45 )\r
- // insert, no effect on FCKeditor, yet\r
- return true ;\r
- return false ;\r
- },\r
-\r
- _KeyDownListener : function( evt )\r
- {\r
- if (! evt)\r
- evt = FCK.EditorWindow.event ;\r
- if ( FCK.EditorWindow )\r
- {\r
- if ( !FCK._IsFunctionKey(evt.keyCode) // do not capture function key presses, like arrow keys or shift/alt/ctrl\r
- && !(evt.ctrlKey || evt.metaKey) // do not capture Ctrl hotkeys, as they have their snapshot capture logic\r
- && !(evt.keyCode == 46) ) // do not capture Del, it has its own capture logic in fckenterkey.js\r
- FCK._KeyDownUndo() ;\r
- }\r
- return true ;\r
- },\r
-\r
- _KeyDownUndo : function()\r
- {\r
- if ( !FCKUndo.Typing )\r
- {\r
- FCKUndo.SaveUndoStep() ;\r
- FCKUndo.Typing = true ;\r
- FCK.Events.FireEvent( "OnSelectionChange" ) ;\r
- }\r
-\r
- FCKUndo.TypesCount++ ;\r
- FCKUndo.Changed = 1 ;\r
-\r
- if ( FCKUndo.TypesCount > FCKUndo.MaxTypes )\r
- {\r
- FCKUndo.TypesCount = 0 ;\r
- FCKUndo.SaveUndoStep() ;\r
- }\r
- },\r
-\r
- _TabKeyHandler : function( evt )\r
- {\r
- if ( ! evt )\r
- evt = window.event ;\r
-\r
- var keystrokeValue = evt.keyCode ;\r
-\r
- // Pressing <Tab> in source mode should produce a tab space in the text area, not\r
- // changing the focus to something else.\r
- if ( keystrokeValue == 9 && FCK.EditMode != FCK_EDITMODE_WYSIWYG )\r
- {\r
- if ( FCKBrowserInfo.IsIE )\r
- {\r
- var range = document.selection.createRange() ;\r
- if ( range.parentElement() != FCK.EditingArea.Textarea )\r
- return true ;\r
- range.text = '\t' ;\r
- range.select() ;\r
- }\r
- else\r
- {\r
- var a = [] ;\r
- var el = FCK.EditingArea.Textarea ;\r
- var selStart = el.selectionStart ;\r
- var selEnd = el.selectionEnd ;\r
- a.push( el.value.substr(0, selStart ) ) ;\r
- a.push( '\t' ) ;\r
- a.push( el.value.substr( selEnd ) ) ;\r
- el.value = a.join( '' ) ;\r
- el.setSelectionRange( selStart + 1, selStart + 1 ) ;\r
- }\r
-\r
- if ( evt.preventDefault )\r
- return evt.preventDefault() ;\r
-\r
- return evt.returnValue = false ;\r
- }\r
-\r
- return true ;\r
- }\r
-} ;\r
-\r
-FCK.Events = new FCKEvents( FCK ) ;\r
-\r
-// DEPRECATED in favor or "GetData".\r
-FCK.GetHTML = FCK.GetXHTML = FCK.GetData ;\r
-\r
-// DEPRECATED in favor of "SetData".\r
-FCK.SetHTML = FCK.SetData ;\r
-\r
-// InsertElementAndGetIt and CreateElement are Deprecated : returns the same value as InsertElement.\r
-FCK.InsertElementAndGetIt = FCK.CreateElement = FCK.InsertElement ;\r
-\r
-// Replace all events attributes (like onclick).\r
-function _FCK_ProtectEvents_ReplaceTags( tagMatch )\r
-{\r
- return tagMatch.replace( FCKRegexLib.EventAttributes, _FCK_ProtectEvents_ReplaceEvents ) ;\r
-}\r
-\r
-// Replace an event attribute with its respective __fckprotectedatt attribute.\r
-// The original event markup will be encoded and saved as the value of the new\r
-// attribute.\r
-function _FCK_ProtectEvents_ReplaceEvents( eventMatch, attName )\r
-{\r
- return ' ' + attName + '_fckprotectedatt="' + encodeURIComponent( eventMatch ) + '"' ;\r
-}\r
-\r
-function _FCK_ProtectEvents_RestoreEvents( match, encodedOriginal )\r
-{\r
- return decodeURIComponent( encodedOriginal ) ;\r
-}\r
-\r
-function _FCK_MouseEventsListener( evt )\r
-{\r
- if ( ! evt )\r
- evt = window.event ;\r
- if ( evt.type == 'mousedown' )\r
- FCK.MouseDownFlag = true ;\r
- else if ( evt.type == 'mouseup' )\r
- FCK.MouseDownFlag = false ;\r
- else if ( evt.type == 'mousemove' )\r
- FCK.Events.FireEvent( 'OnMouseMove', evt ) ;\r
-}\r
-\r
-function _FCK_PaddingNodeListener()\r
-{\r
- if ( FCKConfig.EnterMode.IEquals( 'br' ) )\r
- return ;\r
- FCKDomTools.EnforcePaddingNode( FCK.EditorDocument, FCKConfig.EnterMode ) ;\r
-\r
- if ( ! FCKBrowserInfo.IsIE && FCKDomTools.PaddingNode )\r
- {\r
- // Prevent the caret from going between the body and the padding node in Firefox.\r
- // i.e. <body>|<p></p></body>\r
- var sel = FCKSelection.GetSelection() ;\r
- if ( sel && sel.rangeCount == 1 )\r
- {\r
- var range = sel.getRangeAt( 0 ) ;\r
- if ( range.collapsed && range.startContainer == FCK.EditorDocument.body && range.startOffset == 0 )\r
- {\r
- range.selectNodeContents( FCKDomTools.PaddingNode ) ;\r
- range.collapse( true ) ;\r
- sel.removeAllRanges() ;\r
- sel.addRange( range ) ;\r
- }\r
- }\r
- }\r
- else if ( FCKDomTools.PaddingNode )\r
- {\r
- // Prevent the caret from going into an empty body but not into the padding node in IE.\r
- // i.e. <body><p></p>|</body>\r
- var parentElement = FCKSelection.GetParentElement() ;\r
- var paddingNode = FCKDomTools.PaddingNode ;\r
- if ( parentElement && parentElement.nodeName.IEquals( 'body' ) )\r
- {\r
- if ( FCK.EditorDocument.body.childNodes.length == 1\r
- && FCK.EditorDocument.body.firstChild == paddingNode )\r
- {\r
- /*\r
- * Bug #1764: Don't move the selection if the\r
- * current selection isn't in the editor\r
- * document.\r
- */\r
- if ( FCKSelection._GetSelectionDocument( FCK.EditorDocument.selection ) != FCK.EditorDocument )\r
- return ;\r
-\r
- var range = FCK.EditorDocument.body.createTextRange() ;\r
- var clearContents = false ;\r
- if ( !paddingNode.childNodes.firstChild )\r
- {\r
- paddingNode.appendChild( FCKTools.GetElementDocument( paddingNode ).createTextNode( '\ufeff' ) ) ;\r
- clearContents = true ;\r
- }\r
- range.moveToElementText( paddingNode ) ;\r
- range.select() ;\r
- if ( clearContents )\r
- range.pasteHTML( '' ) ;\r
- }\r
- }\r
- }\r
-}\r
-\r
-function _FCK_EditingArea_OnLoad()\r
-{\r
- // Get the editor's window and document (DOM)\r
- FCK.EditorWindow = FCK.EditingArea.Window ;\r
- FCK.EditorDocument = FCK.EditingArea.Document ;\r
-\r
- if ( FCKBrowserInfo.IsIE )\r
- FCKTempBin.ToElements() ;\r
-\r
- FCK.InitializeBehaviors() ;\r
-\r
- // Listen for mousedown and mouseup events for tracking drag and drops.\r
- FCK.MouseDownFlag = false ;\r
- FCKTools.AddEventListener( FCK.EditorDocument, 'mousemove', _FCK_MouseEventsListener ) ;\r
- FCKTools.AddEventListener( FCK.EditorDocument, 'mousedown', _FCK_MouseEventsListener ) ;\r
- FCKTools.AddEventListener( FCK.EditorDocument, 'mouseup', _FCK_MouseEventsListener ) ;\r
-\r
- // Most of the CTRL key combos do not work under Safari for onkeydown and onkeypress (See #1119)\r
- // But we can use the keyup event to override some of these...\r
- if ( FCKBrowserInfo.IsSafari )\r
- {\r
- var undoFunc = function( evt )\r
- {\r
- if ( ! ( evt.ctrlKey || evt.metaKey ) )\r
- return ;\r
- if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG )\r
- return ;\r
- switch ( evt.keyCode )\r
- {\r
- case 89:\r
- FCKUndo.Redo() ;\r
- break ;\r
- case 90:\r
- FCKUndo.Undo() ;\r
- break ;\r
- }\r
- }\r
-\r
- FCKTools.AddEventListener( FCK.EditorDocument, 'keyup', undoFunc ) ;\r
- }\r
-\r
- // Create the enter key handler\r
- FCK.EnterKeyHandler = new FCKEnterKey( FCK.EditorWindow, FCKConfig.EnterMode, FCKConfig.ShiftEnterMode, FCKConfig.TabSpaces ) ;\r
-\r
- // Listen for keystroke events.\r
- FCK.KeystrokeHandler.AttachToElement( FCK.EditorDocument ) ;\r
-\r
- if ( FCK._ForceResetIsDirty )\r
- FCK.ResetIsDirty() ;\r
-\r
- // This is a tricky thing for IE. In some cases, even if the cursor is\r
- // blinking in the editing, the keystroke handler doesn't catch keyboard\r
- // events. We must activate the editing area to make it work. (#142).\r
- if ( FCKBrowserInfo.IsIE && FCK.HasFocus )\r
- FCK.EditorDocument.body.setActive() ;\r
-\r
- FCK.OnAfterSetHTML() ;\r
-\r
- // Restore show blocks status.\r
- FCKCommands.GetCommand( 'ShowBlocks' ).RestoreState() ;\r
-\r
- // Check if it is not a startup call, otherwise complete the startup.\r
- if ( FCK.Status != FCK_STATUS_NOTLOADED )\r
- return ;\r
-\r
- FCK.SetStatus( FCK_STATUS_ACTIVE ) ;\r
-}\r
-\r
-function _FCK_GetEditorAreaStyleTags()\r
-{\r
- return FCKTools.GetStyleHtml( FCKConfig.EditorAreaCSS ) +\r
- FCKTools.GetStyleHtml( FCKConfig.EditorAreaStyles ) ;\r
-}\r
-\r
-function _FCK_KeystrokeHandler_OnKeystroke( keystroke, keystrokeValue )\r
-{\r
- if ( FCK.Status != FCK_STATUS_COMPLETE )\r
- return false ;\r
-\r
- if ( FCK.EditMode == FCK_EDITMODE_WYSIWYG )\r
- {\r
- switch ( keystrokeValue )\r
- {\r
- case 'Paste' :\r
- return !FCK.Paste() ;\r
-\r
- case 'Cut' :\r
- FCKUndo.SaveUndoStep() ;\r
- return false ;\r
- }\r
- }\r
- else\r
- {\r
- // In source mode, some actions must have their default behavior.\r
- if ( keystrokeValue.Equals( 'Paste', 'Undo', 'Redo', 'SelectAll', 'Cut' ) )\r
- return false ;\r
- }\r
-\r
- // The return value indicates if the default behavior of the keystroke must\r
- // be cancelled. Let's do that only if the Execute() call explicitly returns "false".\r
- var oCommand = FCK.Commands.GetCommand( keystrokeValue ) ;\r
-\r
- // If the command is disabled then ignore the keystroke\r
- if ( oCommand.GetState() == FCK_TRISTATE_DISABLED )\r
- return false ;\r
-\r
- return ( oCommand.Execute.apply( oCommand, FCKTools.ArgumentsToArray( arguments, 2 ) ) !== false ) ;\r
-}\r
-\r
-// Set the FCK.LinkedField reference to the field that will be used to post the\r
-// editor data.\r
-(function()\r
-{\r
- // There is a bug on IE... getElementById returns any META tag that has the\r
- // name set to the ID you are looking for. So the best way in to get the array\r
- // by names and look for the correct one.\r
- // As ASP.Net generates a ID that is different from the Name, we must also\r
- // look for the field based on the ID (the first one is the ID).\r
-\r
- var oDocument = window.parent.document ;\r
-\r
- // Try to get the field using the ID.\r
- var eLinkedField = oDocument.getElementById( FCK.Name ) ;\r
-\r
- var i = 0;\r
- while ( eLinkedField || i == 0 )\r
- {\r
- if ( eLinkedField && eLinkedField.tagName.toLowerCase().Equals( 'input', 'textarea' ) )\r
- {\r
- FCK.LinkedField = eLinkedField ;\r
- break ;\r
- }\r
-\r
- eLinkedField = oDocument.getElementsByName( FCK.Name )[i++] ;\r
- }\r
-})() ;\r
-\r
-var FCKTempBin =\r
-{\r
- Elements : new Array(),\r
-\r
- AddElement : function( element )\r
- {\r
- var iIndex = this.Elements.length ;\r
- this.Elements[ iIndex ] = element ;\r
- return iIndex ;\r
- },\r
-\r
- RemoveElement : function( index )\r
- {\r
- var e = this.Elements[ index ] ;\r
- this.Elements[ index ] = null ;\r
- return e ;\r
- },\r
-\r
- Reset : function()\r
- {\r
- var i = 0 ;\r
- while ( i < this.Elements.length )\r
- this.Elements[ i++ ] = null ;\r
- this.Elements.length = 0 ;\r
- },\r
-\r
- ToHtml : function()\r
- {\r
- for ( var i = 0 ; i < this.Elements.length ; i++ )\r
- {\r
- this.Elements[i] = '<div> ' + this.Elements[i].outerHTML + '</div>' ;\r
- this.Elements[i].isHtml = true ;\r
- }\r
- },\r
-\r
- ToElements : function()\r
- {\r
- var node = FCK.EditorDocument.createElement( 'div' ) ;\r
- for ( var i = 0 ; i < this.Elements.length ; i++ )\r
- {\r
- if ( this.Elements[i].isHtml )\r
- {\r
- node.innerHTML = this.Elements[i] ;\r
- this.Elements[i] = node.firstChild.removeChild( node.firstChild.lastChild ) ;\r
- }\r
- }\r
- }\r
-} ;\r
-\r
-\r
-\r
-// # Focus Manager: Manages the focus in the editor.\r
-var FCKFocusManager = FCK.FocusManager =\r
-{\r
- IsLocked : false,\r
-\r
- AddWindow : function( win, sendToEditingArea )\r
- {\r
- var oTarget ;\r
-\r
- if ( FCKBrowserInfo.IsIE )\r
- oTarget = win.nodeType == 1 ? win : win.frameElement ? win.frameElement : win.document ;\r
- else if ( FCKBrowserInfo.IsSafari )\r
- oTarget = win ;\r
- else\r
- oTarget = win.document ;\r
-\r
- FCKTools.AddEventListener( oTarget, 'blur', FCKFocusManager_Win_OnBlur ) ;\r
- FCKTools.AddEventListener( oTarget, 'focus', sendToEditingArea ? FCKFocusManager_Win_OnFocus_Area : FCKFocusManager_Win_OnFocus ) ;\r
- },\r
-\r
- RemoveWindow : function( win )\r
- {\r
- if ( FCKBrowserInfo.IsIE )\r
- oTarget = win.nodeType == 1 ? win : win.frameElement ? win.frameElement : win.document ;\r
- else\r
- oTarget = win.document ;\r
-\r
- FCKTools.RemoveEventListener( oTarget, 'blur', FCKFocusManager_Win_OnBlur ) ;\r
- FCKTools.RemoveEventListener( oTarget, 'focus', FCKFocusManager_Win_OnFocus_Area ) ;\r
- FCKTools.RemoveEventListener( oTarget, 'focus', FCKFocusManager_Win_OnFocus ) ;\r
- },\r
-\r
- Lock : function()\r
- {\r
- this.IsLocked = true ;\r
- },\r
-\r
- Unlock : function()\r
- {\r
- if ( this._HasPendingBlur )\r
- FCKFocusManager._Timer = window.setTimeout( FCKFocusManager_FireOnBlur, 100 ) ;\r
-\r
- this.IsLocked = false ;\r
- },\r
-\r
- _ResetTimer : function()\r
- {\r
- this._HasPendingBlur = false ;\r
-\r
- if ( this._Timer )\r
- {\r
- window.clearTimeout( this._Timer ) ;\r
- delete this._Timer ;\r
- }\r
- }\r
-} ;\r
-\r
-function FCKFocusManager_Win_OnBlur()\r
-{\r
- if ( typeof(FCK) != 'undefined' && FCK.HasFocus )\r
- {\r
- FCKFocusManager._ResetTimer() ;\r
- FCKFocusManager._Timer = window.setTimeout( FCKFocusManager_FireOnBlur, 100 ) ;\r
- }\r
-}\r
-\r
-function FCKFocusManager_FireOnBlur()\r
-{\r
- if ( FCKFocusManager.IsLocked )\r
- FCKFocusManager._HasPendingBlur = true ;\r
- else\r
- {\r
- FCK.HasFocus = false ;\r
- FCK.Events.FireEvent( "OnBlur" ) ;\r
- }\r
-}\r
-\r
-function FCKFocusManager_Win_OnFocus_Area()\r
-{\r
- // Check if we are already focusing the editor (to avoid loops).\r
- if ( FCKFocusManager._IsFocusing )\r
- return ;\r
-\r
- FCKFocusManager._IsFocusing = true ;\r
-\r
- FCK.Focus() ;\r
- FCKFocusManager_Win_OnFocus() ;\r
-\r
- // The above FCK.Focus() call may trigger other focus related functions.\r
- // So, to avoid a loop, we delay the focusing mark removal, so it get\r
- // executed after all othre functions have been run.\r
- FCKTools.RunFunction( function()\r
- {\r
- delete FCKFocusManager._IsFocusing ;\r
- } ) ;\r
-}\r
-\r
-function FCKFocusManager_Win_OnFocus()\r
-{\r
- FCKFocusManager._ResetTimer() ;\r
-\r
- if ( !FCK.HasFocus && !FCKFocusManager.IsLocked )\r
- {\r
- FCK.HasFocus = true ;\r
- FCK.Events.FireEvent( "OnFocus" ) ;\r
- }\r
-}\r
-\r
-/*\r
- * #1633 : Protect the editor iframe from external styles.\r
- * Notice that we can't use FCKTools.ResetStyles here since FCKTools isn't\r
- * loaded yet.\r
- */\r
-(function()\r
-{\r
- var el = window.frameElement ;\r
- var width = el.width ;\r
- var height = el.height ;\r
- if ( /^\d+$/.test( width ) ) width += 'px' ;\r
- if ( /^\d+$/.test( height ) ) height += 'px' ;\r
- var style = el.style ;\r
- style.border = style.padding = style.margin = 0 ;\r
- style.backgroundColor = 'transparent';\r
- style.backgroundImage = 'none';\r
- style.width = width ;\r
- style.height = height ;\r
-})() ;\r