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 + -
显示快捷键?