fck.js
来自「国外很不错的一个开源OA系统Group-Office」· JavaScript 代码 · 共 860 行 · 第 1/2 页
JS
860 行
/* * FCKeditor - The text editor for Internet - http://www.fckeditor.net * Copyright (C) 2003-2007 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 == * * Creation and initialization of the "FCK" object. This is the main object * that represents an editor instance. */// FCK represents the active editor instance.var FCK ={ Name : FCKURLParams[ 'InstanceName' ], Status : FCK_STATUS_NOTLOADED, EditMode : FCK_EDITMODE_WYSIWYG, Toolbar : null, HasFocus : false, GetLinkedFieldValue : function() { return this.LinkedField.value ; }, GetParentForm : function() { return this.LinkedField.form ; } , // # START : IsDirty implementation StartupValue : '', IsDirty : function() { if ( this.EditMode == FCK_EDITMODE_SOURCE ) return ( this.StartupValue != this.EditingArea.Textarea.value ) ; else return ( this.StartupValue != this.EditorDocument.body.innerHTML ) ; }, ResetIsDirty : function() { if ( this.EditMode == FCK_EDITMODE_SOURCE ) this.StartupValue = this.EditingArea.Textarea.value ; else if ( this.EditorDocument.body ) this.StartupValue = this.EditorDocument.body.innerHTML ; }, // # END : IsDirty implementation StartEditor : function() { this.TempBaseTag = FCKConfig.BaseHref.length > 0 ? '<base href="' + FCKConfig.BaseHref + '" _fcktemp="true"></base>' : '' ; // Setup the keystroke handler. var oKeystrokeHandler = FCK.KeystrokeHandler = new FCKKeystrokeHandler() ; oKeystrokeHandler.OnKeystroke = _FCK_KeystrokeHandler_OnKeystroke ; oKeystrokeHandler.SetKeystrokes( FCKConfig.Keystrokes ) ; // In IE7, if the editor tries to access the clipboard by code, a dialog is // shown to the user asking if the application is allowed to access or not. // Due to the IE implementation of it, the KeystrokeHandler will not work //well in this case, so we must leave the pasting keys to have their default behavior. if ( FCKBrowserInfo.IsIE7 ) { if ( ( CTRL + 86 /*V*/ ) in oKeystrokeHandler.Keystrokes ) oKeystrokeHandler.SetKeystrokes( [ CTRL + 86, true ] ) ; if ( ( SHIFT + 45 /*INS*/ ) in oKeystrokeHandler.Keystrokes ) oKeystrokeHandler.SetKeystrokes( [ SHIFT + 45, true ] ) ; } this.EditingArea = new FCKEditingArea( document.getElementById( 'xEditingArea' ) ) ; this.EditingArea.FFSpellChecker = false ; // Final setup of the lists lib. FCKListsLib.Setup() ; // Set the editor's startup contents this.SetHTML( this.GetLinkedFieldValue(), true ) ; }, Focus : function() { FCK.EditingArea.Focus() ; }, SetStatus : function( newStatus ) { this.Status = newStatus ; if ( newStatus == FCK_STATUS_ACTIVE ) { FCKFocusManager.AddWindow( window, true ) ; if ( FCKBrowserInfo.IsIE ) FCKFocusManager.AddWindow( window.frameElement, true ) ; // Force the focus in the editor. if ( FCKConfig.StartupFocus ) FCK.Focus() ; } this.Events.FireEvent( 'OnStatusChange', newStatus ) ; }, // Fixes the body by moving all inline and text nodes to appropriate block // elements. FixBody : function() { var sBlockTag = FCKConfig.EnterMode ; // In 'br' mode, no fix must be done. if ( sBlockTag != 'p' && sBlockTag != 'div' ) return ; var oDocument = this.EditorDocument ; if ( !oDocument ) return ; var oBody = oDocument.body ; if ( !oBody ) return ; FCKDomTools.TrimNode( oBody ) ; var oNode = oBody.firstChild ; var oNewBlock ; while ( oNode ) { var bMoveNode = false ; switch ( oNode.nodeType ) { // Element Node. case 1 : if ( !FCKListsLib.BlockElements[ oNode.nodeName.toLowerCase() ] ) bMoveNode = true ; break ; // Text Node. case 3 : // Ignore space only or empty text. if ( oNewBlock || oNode.nodeValue.Trim().length > 0 ) bMoveNode = true ; } if ( bMoveNode ) { var oParent = oNode.parentNode ; if ( !oNewBlock ) oNewBlock = oParent.insertBefore( oDocument.createElement( sBlockTag ), oNode ) ; oNewBlock.appendChild( oParent.removeChild( oNode ) ) ; oNode = oNewBlock.nextSibling ; } else { if ( oNewBlock ) { FCKDomTools.TrimNode( oNewBlock ) ; oNewBlock = null ; } oNode = oNode.nextSibling ; } } if ( oNewBlock ) FCKDomTools.TrimNode( oNewBlock ) ; }, GetXHTML : function( format ) { // We assume that if the user is in source editing, the editor value must // represent the exact contents of the source, as the user wanted it to be. if ( FCK.EditMode == FCK_EDITMODE_SOURCE ) return FCK.EditingArea.Textarea.value ; this.FixBody() ; var sXHTML ; var oDoc = FCK.EditorDocument ; if ( !oDoc ) return null ; if ( FCKConfig.FullPage ) { sXHTML = FCKXHtml.GetXHTML( oDoc.getElementsByTagName( 'html' )[0], true, format ) ; if ( FCK.DocTypeDeclaration && FCK.DocTypeDeclaration.length > 0 ) sXHTML = FCK.DocTypeDeclaration + '\n' + sXHTML ; if ( FCK.XmlDeclaration && FCK.XmlDeclaration.length > 0 ) sXHTML = FCK.XmlDeclaration + '\n' + sXHTML ; } else { sXHTML = FCKXHtml.GetXHTML( oDoc.body, false, format ) ; if ( FCKConfig.IgnoreEmptyParagraphValue && FCKRegexLib.EmptyOutParagraph.test( sXHTML ) ) sXHTML = '' ; } // Restore protected attributes. sXHTML = FCK.ProtectEventsRestore( sXHTML ) ; if ( FCKBrowserInfo.IsIE ) sXHTML = sXHTML.replace( FCKRegexLib.ToReplace, '$1' ) ; return FCKConfig.ProtectedSource.Revert( sXHTML ) ; }, UpdateLinkedField : function() { FCK.LinkedField.value = FCK.GetXHTML( FCKConfig.FormatOutput ) ; FCK.Events.FireEvent( 'OnAfterLinkedFieldUpdate' ) ; }, RegisteredDoubleClickHandlers : new Object(), OnDoubleClick : function( element ) { var oHandler = FCK.RegisteredDoubleClickHandlers[ element.tagName ] ; if ( oHandler ) oHandler( element ) ; }, // Register objects that can handle double click operations. RegisterDoubleClickHandler : function( handlerFunction, tag ) { FCK.RegisteredDoubleClickHandlers[ tag.toUpperCase() ] = handlerFunction ; }, OnAfterSetHTML : function() { FCKDocumentProcessor.Process( FCK.EditorDocument ) ; FCKUndo.SaveUndoStep() ; FCK.Events.FireEvent( 'OnSelectionChange' ) ; FCK.Events.FireEvent( 'OnAfterSetHTML' ) ; }, // Saves URLs on links and images on special attributes, so they don't change when // moving around. ProtectUrls : function( html ) { // <A> href html = html.replace( FCKRegexLib.ProtectUrlsA , '$& _fcksavedurl=$1' ) ; // <IMG> src html = html.replace( FCKRegexLib.ProtectUrlsImg , '$& _fcksavedurl=$1' ) ; return html ; }, // Saves event attributes (like onclick) so they don't get executed while // editing. ProtectEvents : function( html ) { return html.replace( FCKRegexLib.TagsWithEvent, _FCK_ProtectEvents_ReplaceTags ) ; }, ProtectEventsRestore : function( html ) { return html.replace( FCKRegexLib.ProtectedEvents, _FCK_ProtectEvents_RestoreEvents ) ; }, ProtectTags : function( html ) { var sTags = FCKConfig.ProtectedTags ; // IE doesn't support <abbr> and it breaks it. Let's protect it. if ( FCKBrowserInfo.IsIE ) sTags += sTags.length > 0 ? '|ABBR' : 'ABBR' ; var oRegex ; if ( sTags.length > 0 ) { oRegex = new RegExp( '<(' + sTags + ')(?!\w|:)', 'gi' ) ; html = html.replace( oRegex, '<FCK:$1' ) ; oRegex = new RegExp( '<\/(' + sTags + ')>', 'gi' ) ; html = html.replace( oRegex, '<\/FCK:$1>' ) ; } // Protect some empty elements. We must do it separately becase the // original tag may not contain the closing slash, like <hr>: // - <meta> tags get executed, so if you have a redirect meta, the // content will move to the target page. // - <hr> may destroy the document structure if not well // positioned. The trick is protect it here and restore them in // the FCKDocumentProcessor. sTags = 'META' ; if ( FCKBrowserInfo.IsIE ) sTags += '|HR' ; oRegex = new RegExp( '<((' + sTags + ')(?=\s|>)[\s\S]*?)/?>', 'gi' ) ; html = html.replace( oRegex, '<FCK:$1 />' ) ; return html ; }, SetHTML : function( html, resetIsDirty ) { this.EditingArea.Mode = FCK.EditMode ; if ( FCK.EditMode == FCK_EDITMODE_WYSIWYG ) { html = FCKConfig.ProtectedSource.Protect( html ) ; // Fix for invalid self-closing tags (see #152). html = html.replace( FCKRegexLib.InvalidSelfCloseTags, '$1></$2>' ) ; html = FCK.ProtectEvents( html ) ; html = FCK.ProtectUrls( html ) ; html = FCK.ProtectTags( html ) ; // Firefox can't handle correctly the editing of the STRONG and EM tags. // We must replace them with B and I. if ( FCKBrowserInfo.IsGecko ) { html = html.replace( FCKRegexLib.StrongOpener, '<b$1' ) ; html = html.replace( FCKRegexLib.StrongCloser, '<\/b>' ) ; html = html.replace( FCKRegexLib.EmOpener, '<i$1' ) ; html = html.replace( FCKRegexLib.EmCloser, '<\/i>' ) ; } this._ForceResetIsDirty = ( resetIsDirty === true ) ; var sHtml = '' ; if ( FCKConfig.FullPage ) { // The HTML must be fixed if the <head> is not available. if ( !FCKRegexLib.HeadOpener.test( html ) ) { // Check if the <html> is available. if ( !FCKRegexLib.HtmlOpener.test( html ) ) html = '<html dir="' + FCKConfig.ContentLangDirection + '">' + html + '</html>' ; // Add the <head>. html = html.replace( FCKRegexLib.HtmlOpener, '$&<head></head>' ) ; } // Save the DOCTYPE. FCK.DocTypeDeclaration = html.match( FCKRegexLib.DocTypeTag ) ; if ( FCKBrowserInfo.IsIE ) sHtml = FCK._GetBehaviorsStyle() ; else if ( FCKConfig.ShowBorders ) sHtml = '<link href="' + FCKConfig.FullBasePath + 'css/fck_showtableborders_gecko.css" rel="stylesheet" type="text/css" _fcktemp="true" />' ; sHtml += '<link href="' + FCKConfig.FullBasePath + 'css/fck_internal.css' + '" rel="stylesheet" type="text/css" _fcktemp="true" />' ; // Attention: do not change it before testing it well (sample07)! // This is tricky... if the head ends with <meta ... content type>, // Firefox will break. But, it works if we include the temporary // links as the last elements in the HEAD. sHtml = html.replace( FCKRegexLib.HeadCloser, sHtml + '$&' ) ; // Insert the base tag (FCKConfig.BaseHref), if not exists in the source. // The base must be the first tag in the HEAD, to get relative // links on styles, for example. if ( FCK.TempBaseTag.length > 0 && !FCKRegexLib.HasBaseTag.test( html ) ) sHtml = sHtml.replace( FCKRegexLib.HeadOpener, '$&' + FCK.TempBaseTag ) ; } else { sHtml = FCKConfig.DocType + '<html dir="' + FCKConfig.ContentLangDirection + '"' ; // On IE, if you are use a DOCTYPE differenft of HTML 4 (like // XHTML), you must force the vertical scroll to show, otherwise // the horizontal one may appear when the page needs vertical scrolling. if ( FCKBrowserInfo.IsIE && !FCKRegexLib.Html4DocType.test( FCKConfig.DocType ) ) sHtml += ' style="overflow-y: scroll"' ; sHtml += '><head><title></title>' + _FCK_GetEditorAreaStyleTags() + '<link href="' + FCKConfig.FullBasePath + 'css/fck_internal.css' + '" rel="stylesheet" type="text/css" _fcktemp="true" />' ; if ( FCKBrowserInfo.IsIE ) sHtml += FCK._GetBehaviorsStyle() ; else if ( FCKConfig.ShowBorders ) sHtml += '<link href="' + FCKConfig.FullBasePath + 'css/fck_showtableborders_gecko.css" rel="stylesheet" type="text/css" _fcktemp="true" />' ; sHtml += FCK.TempBaseTag ; // Add ID and Class to the body var sBodyTag = '<body' ; if ( FCKConfig.BodyId && FCKConfig.BodyId.length > 0 ) sBodyTag += ' id="' + FCKConfig.BodyId + '"' ; if ( FCKConfig.BodyClass && FCKConfig.BodyClass.length > 0 ) sBodyTag += ' class="' + FCKConfig.BodyClass + '"' ; sHtml += '</head>' + sBodyTag + '>' ; if ( FCKBrowserInfo.IsGecko && ( html.length == 0 || FCKRegexLib.EmptyParagraph.test( html ) ) ) sHtml += GECKO_BOGUS ; else sHtml += html ; sHtml += '</body></html>' ; } this.EditingArea.OnLoad = _FCK_EditingArea_OnLoad ; this.EditingArea.Start( sHtml ) ;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?