# HG changeset patch # User Byeongweon [tasyblue@gmail.com] # Date 1218430489 -32400 # Node ID f5c322ae1c7ba5d88f3ce801f9f33307d23f5284 # Parent 3791b2e8e4718d78cc8369036b86f31833d64831 add recent version of fckeditor 2.6.3 diff -r 3791b2e8e471 -r f5c322ae1c7b wiki/htdocs/applets/FCKeditor/_documentation.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wiki/htdocs/applets/FCKeditor/_documentation.html Mon Aug 11 13:54:49 2008 +0900 @@ -0,0 +1,38 @@ + + + + + FCKeditor - Documentation + + + + +

+ FCKeditor Documentation

+

+ You can find the official documentation for FCKeditor online, at + http://docs.fckeditor.net/.

+ + diff -r 3791b2e8e471 -r f5c322ae1c7b wiki/htdocs/applets/FCKeditor/_upgrade.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wiki/htdocs/applets/FCKeditor/_upgrade.html Mon Aug 11 13:54:49 2008 +0900 @@ -0,0 +1,39 @@ + + + + + FCKeditor - Upgrade + + + + +

+ FCKeditor Upgrade

+

+ Please check the following URL for notes regarding upgrade:
+ + http://docs.fckeditor.net/FCKeditor_2.x/Developers_Guide/Installation/Upgrading

+ + diff -r 3791b2e8e471 -r f5c322ae1c7b wiki/htdocs/applets/FCKeditor/_whatsnew.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wiki/htdocs/applets/FCKeditor/_whatsnew.html Mon Aug 11 13:54:49 2008 +0900 @@ -0,0 +1,167 @@ + + + + + FCKeditor ChangeLog - What's New? + + + + +

+ FCKeditor ChangeLog - What's New?

+

+ Version 2.6.3

+

+ Fixed Bugs:

+ +

+ This version has been sponsored by Data Illusion + survey software solutions.

+

+ Version 2.6.3 Beta

+

+ New Features and Improvements:

+ +

+ Fixed Bugs:

+ +

+ See previous versions history

+ + diff -r 3791b2e8e471 -r f5c322ae1c7b wiki/htdocs/applets/FCKeditor/_whatsnew_history.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wiki/htdocs/applets/FCKeditor/_whatsnew_history.html Mon Aug 11 13:54:49 2008 +0900 @@ -0,0 +1,3787 @@ + + + + + FCKeditor ChangeLog - What's New? + + + + +

+ FCKeditor ChangeLog - What's New?

+

+ Version 2.6.2

+

+ New Features and Improvements:

+ +

+ Fixed Bugs:

+ +

+ Version 2.6.1

+

+ New Features and Improvements:

+ +

+ Fixed Bugs:

+ +

+ Version 2.6

+

+ No changes. The stabilization of the 2.6 RC was completed successfully, as expected.

+

+ Version 2.6 RC

+

+ New Features and Improvements:

+ +

+ Fixed Bugs:

+ +

+ Version 2.6 Beta 1

+

+ New Features and Improvements:

+ +

+ Fixed Bugs:

+ +

+ Version 2.5.1

+

+ New Features and Improvements:

+ +

+ Fixed Bugs:

+ +

+ Version 2.5

+

+ New Features and Improvements:

+ +

+ Fixed Bugs:

+ +

+ Version 2.5 Beta

+

+ New Features and Improvements:

+ +

+ Fixed Bugs:

+ +

+ # This version has been partially sponsored + by the Council of Europe. +

+

+ Version 2.4.3

+

+ New Features and Improvements:

+ +

+ Fixed Bugs:

+ +

+ Version 2.4.2

+

+ Fixed Bugs:

+ +

+ Version 2.4.1

+

+ New Features and Improvements:

+ +

+ Fixed Bugs:

+ +

+ Version 2.4

+

+ New Features and Improvements:

+ +

+ Fixed Bugs:

+ +

+ * This version has been partially sponsored by Medical + Media Lab.

+

+ Version 2.3.3

+

+ New Features and Improvements:

+ +

+ Version 2.3.2

+

+ New Features and Improvements:

+ +

+ Fixed Bugs:

+ +

+ Version 2.3.1

+

+ Fixed Bugs:

+ +

+ Version 2.3

+

+ New Features and Improvements:

+ +

+ Fixed Bugs:

+ +

+ * This version has been partially sponsored by Footsteps + and Kentico.

+

+ Version 2.3 Beta

+

+ New Features and Improvements:

+ +

+ Fixed Bugs:

+ +

+ * This version has been partially sponsored by Footsteps + and Kentico. +
+ ** This version has been partially sponsored by Nextide.

+

+ Version 2.2

+

+ New Features and Improvements:

+ +

+ Fixed Bugs:

+ +

+ Special thanks to + Alfonso Martinez, who have provided many patches and suggestions for the + following features / fixes present in this version. I encourage all you to + donate to Alfonso, as a way to say thanks for his nice open source approach. + Thanks Alfonso!. Check out his contributions:

+ +

+ * This version has been partially sponsored by + Alkacon Software.

+

+ Version 2.1.1

+

+ New Features and Improvements:

+ +

+ Fixed Bugs:

+ +

+ * This version has been partially sponsored by + Acctive Software S.A..

+

+ Version 2.1

+

+ New Features and Improvements:

+ +

+ Fixed Bugs:

+ +

+ Version 2.0

+

+ New Features and Improvements:

+ +

+ Fixed Bugs:

+ +

+ * This version has been partially sponsored by + Infineon Technologies AG.
+ ** This version has been partially sponsored by + Visualsoft Web Solutions.
+ *** This version has been partially sponsored by + Web Crossing, Inc.

+

+ Version 2.0 FC (Final Candidate)

+

+ New Features and Improvements:

+ +

+ Fixed Bugs:

+ +

+ * This version has been partially sponsored by the + Hamilton College.
+ ** This version has been partially sponsored by + Infineon Technologies AG.

+

+ Version 2.0 RC3 (Release Candidate 3)

+

+ New Features and Improvements:

+ +

+ Fixed Bugs:

+ +

+ Version 2.0 RC2 (Release Candidate 2)

+ +

+ Version 2.0 RC1 (Release Candidate 1)

+ +

+ Version 2.0 Beta 2

+ +

+ Version 2.0 Beta 1

+

+ This is the first beta of the 2.x series. It brings a lot of new and important things. + Beta versions will be released until all features available on version 1.x will + be introduced in the 2.0.
+
+ Note: As it is a beta, it is not yet completely developed. Future + versions can bring new features that can break backward compatibility with this + version. +

+ +

+ Version 1.6.1

+ +

+ * This version has been partially sponsored by Genuitec, + LLC.

+

+ Version 1.6

+ +

+ * This version has been partially sponsored by Genuitec, + LLC.

+

+ Version 1.5

+ +

+ Version 1.4

+ +

+ Version 1.3.1

+ +

+ Version 1.3

+ +

+ Version 1.2.4

+ +

+ Version 1.2.2

+ +

+ Version 1.2

+ +

+ Version 1.1

+ +

+ Version 1.0

+ +

+ Version 1.0 Final Candidate

+ +

+ Version 1.0 Release Candidate 1 (RC1)

+ +

+ Version 0.9.5 beta

+ +

+ Version 0.9.4 beta

+ + + diff -r 3791b2e8e471 -r f5c322ae1c7b wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckcontextmenu.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckcontextmenu.js Mon Aug 11 13:54:49 2008 +0900 @@ -0,0 +1,223 @@ +/* + * FCKeditor - The text editor for Internet - http://www.fckeditor.net + * Copyright (C) 2003-2008 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 == + * + * FCKContextMenu Class: renders an control a context menu. + */ + +var FCKContextMenu = function( parentWindow, langDir ) +{ + this.CtrlDisable = false ; + + var oPanel = this._Panel = new FCKPanel( parentWindow ) ; + oPanel.AppendStyleSheet( FCKConfig.SkinEditorCSS ) ; + oPanel.IsContextMenu = true ; + + // The FCKTools.DisableSelection doesn't seems to work to avoid dragging of the icons in Mozilla + // so we stop the start of the dragging + if ( FCKBrowserInfo.IsGecko ) + oPanel.Document.addEventListener( 'draggesture', function(e) {e.preventDefault(); return false;}, true ) ; + + var oMenuBlock = this._MenuBlock = new FCKMenuBlock() ; + oMenuBlock.Panel = oPanel ; + oMenuBlock.OnClick = FCKTools.CreateEventListener( FCKContextMenu_MenuBlock_OnClick, this ) ; + + this._Redraw = true ; +} + + +FCKContextMenu.prototype.SetMouseClickWindow = function( mouseClickWindow ) +{ + if ( !FCKBrowserInfo.IsIE ) + { + this._Document = mouseClickWindow.document ; + if ( FCKBrowserInfo.IsOpera && !( 'oncontextmenu' in document.createElement('foo') ) ) + { + this._Document.addEventListener( 'mousedown', FCKContextMenu_Document_OnMouseDown, false ) ; + this._Document.addEventListener( 'mouseup', FCKContextMenu_Document_OnMouseUp, false ) ; + } + this._Document.addEventListener( 'contextmenu', FCKContextMenu_Document_OnContextMenu, false ) ; + } +} + +/** + The customData parameter is just a value that will be send to the command that is executed, + so it's possible to reuse the same command for several items just by assigning different data for each one. +*/ +FCKContextMenu.prototype.AddItem = function( name, label, iconPathOrStripInfoArrayOrIndex, isDisabled, customData ) +{ + var oItem = this._MenuBlock.AddItem( name, label, iconPathOrStripInfoArrayOrIndex, isDisabled, customData ) ; + this._Redraw = true ; + return oItem ; +} + +FCKContextMenu.prototype.AddSeparator = function() +{ + this._MenuBlock.AddSeparator() ; + this._Redraw = true ; +} + +FCKContextMenu.prototype.RemoveAllItems = function() +{ + this._MenuBlock.RemoveAllItems() ; + this._Redraw = true ; +} + +FCKContextMenu.prototype.AttachToElement = function( element ) +{ + if ( FCKBrowserInfo.IsIE ) + FCKTools.AddEventListenerEx( element, 'contextmenu', FCKContextMenu_AttachedElement_OnContextMenu, this ) ; + else + element._FCKContextMenu = this ; +} + +function FCKContextMenu_Document_OnContextMenu( e ) +{ + if ( FCKConfig.BrowserContextMenu ) + return true ; + + var el = e.target ; + + while ( el ) + { + if ( el._FCKContextMenu ) + { + if ( el._FCKContextMenu.CtrlDisable && ( e.ctrlKey || e.metaKey ) ) + return true ; + + FCKTools.CancelEvent( e ) ; + FCKContextMenu_AttachedElement_OnContextMenu( e, el._FCKContextMenu, el ) ; + return false ; + } + el = el.parentNode ; + } + return true ; +} + +var FCKContextMenu_OverrideButton ; + +function FCKContextMenu_Document_OnMouseDown( e ) +{ + if( !e || e.button != 2 ) + return false ; + + if ( FCKConfig.BrowserContextMenu ) + return true ; + + var el = e.target ; + + while ( el ) + { + if ( el._FCKContextMenu ) + { + if ( el._FCKContextMenu.CtrlDisable && ( e.ctrlKey || e.metaKey ) ) + return true ; + + var overrideButton = FCKContextMenu_OverrideButton ; + if( !overrideButton ) + { + var doc = FCKTools.GetElementDocument( e.target ) ; + overrideButton = FCKContextMenu_OverrideButton = doc.createElement('input') ; + overrideButton.type = 'button' ; + var buttonHolder = doc.createElement('p') ; + doc.body.appendChild( buttonHolder ) ; + buttonHolder.appendChild( overrideButton ) ; + } + + overrideButton.style.cssText = 'position:absolute;top:' + ( e.clientY - 2 ) + + 'px;left:' + ( e.clientX - 2 ) + + 'px;width:5px;height:5px;opacity:0.01' ; + } + el = el.parentNode ; + } + return false ; +} + +function FCKContextMenu_Document_OnMouseUp( e ) +{ + if ( FCKConfig.BrowserContextMenu ) + return true ; + + var overrideButton = FCKContextMenu_OverrideButton ; + + if ( overrideButton ) + { + var parent = overrideButton.parentNode ; + parent.parentNode.removeChild( parent ) ; + FCKContextMenu_OverrideButton = undefined ; + + if( e && e.button == 2 ) + { + FCKContextMenu_Document_OnContextMenu( e ) ; + return false ; + } + } + return true ; +} + +function FCKContextMenu_AttachedElement_OnContextMenu( ev, fckContextMenu, el ) +{ + if ( ( fckContextMenu.CtrlDisable && ( ev.ctrlKey || ev.metaKey ) ) || FCKConfig.BrowserContextMenu ) + return true ; + + var eTarget = el || this ; + + if ( fckContextMenu.OnBeforeOpen ) + fckContextMenu.OnBeforeOpen.call( fckContextMenu, eTarget ) ; + + if ( fckContextMenu._MenuBlock.Count() == 0 ) + return false ; + + if ( fckContextMenu._Redraw ) + { + fckContextMenu._MenuBlock.Create( fckContextMenu._Panel.MainNode ) ; + fckContextMenu._Redraw = false ; + } + + // This will avoid that the content of the context menu can be dragged in IE + // as the content of the panel is recreated we need to do it every time + FCKTools.DisableSelection( fckContextMenu._Panel.Document.body ) ; + + var x = 0 ; + var y = 0 ; + if ( FCKBrowserInfo.IsIE ) + { + x = ev.screenX ; + y = ev.screenY ; + } + else if ( FCKBrowserInfo.IsSafari ) + { + x = ev.clientX ; + y = ev.clientY ; + } + else + { + x = ev.pageX ; + y = ev.pageY ; + } + fckContextMenu._Panel.Show( x, y, ev.currentTarget || null ) ; + + return false ; +} + +function FCKContextMenu_MenuBlock_OnClick( menuItem, contextMenu ) +{ + contextMenu._Panel.Hide() ; + FCKTools.RunFunction( contextMenu.OnItemClick, contextMenu, menuItem ) ; +} diff -r 3791b2e8e471 -r f5c322ae1c7b wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckdataprocessor.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckdataprocessor.js Mon Aug 11 13:54:49 2008 +0900 @@ -0,0 +1,119 @@ +/* + * FCKeditor - The text editor for Internet - http://www.fckeditor.net + * Copyright (C) 2003-2008 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 == + * + * The Data Processor is responsible for transforming the input and output data + * in the editor. For more info: + * http://dev.fckeditor.net/wiki/Components/DataProcessor + * + * The default implementation offers the base XHTML compatibility features of + * FCKeditor. Further Data Processors may be implemented for other purposes. + * + */ + +var FCKDataProcessor = function() +{} + +FCKDataProcessor.prototype = +{ + /* + * Returns a string representing the HTML format of "data". The returned + * value will be loaded in the editor. + * The HTML must be from to , including , and + * eventually the DOCTYPE. + * Note: HTML comments may already be part of the data because of the + * pre-processing made with ProtectedSource. + * @param {String} data The data to be converted in the + * DataProcessor specific format. + */ + ConvertToHtml : function( data ) + { + // The default data processor must handle two different cases depending + // on the FullPage setting. Custom Data Processors will not be + // compatible with FullPage, much probably. + if ( FCKConfig.FullPage ) + { + // Save the DOCTYPE. + FCK.DocTypeDeclaration = data.match( FCKRegexLib.DocTypeTag ) ; + + // Check if the tag is available. + if ( !FCKRegexLib.HasBodyTag.test( data ) ) + data = '' + data + '' ; + + // Check if the tag is available. + if ( !FCKRegexLib.HtmlOpener.test( data ) ) + data = '' + data + '' ; + + // Check if the tag is available. + if ( !FCKRegexLib.HeadOpener.test( data ) ) + data = data.replace( FCKRegexLib.HtmlOpener, '$&' ) ; + + return data ; + } + else + { + var html = + FCKConfig.DocType + + ' 0 && !FCKRegexLib.Html4DocType.test( FCKConfig.DocType ) ) + html += ' style="overflow-y: scroll"' ; + + html += '>' + + '' + + data + + '' ; + + return html ; + } + }, + + /* + * Converts a DOM (sub-)tree to a string in the data format. + * @param {Object} rootNode The node that contains the DOM tree to be + * converted to the data format. + * @param {Boolean} excludeRoot Indicates that the root node must not + * be included in the conversion, only its children. + * @param {Boolean} format Indicates that the data must be formatted + * for human reading. Not all Data Processors may provide it. + */ + ConvertToDataFormat : function( rootNode, excludeRoot, ignoreIfEmptyParagraph, format ) + { + var data = FCKXHtml.GetXHTML( rootNode, !excludeRoot, format ) ; + + if ( ignoreIfEmptyParagraph && FCKRegexLib.EmptyOutParagraph.test( data ) ) + return '' ; + + return data ; + }, + + /* + * Makes any necessary changes to a piece of HTML for insertion in the + * editor selection position. + * @param {String} html The HTML to be fixed. + */ + FixHtml : function( html ) + { + return html ; + } +} ; diff -r 3791b2e8e471 -r f5c322ae1c7b wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckdocumentfragment_gecko.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckdocumentfragment_gecko.js Mon Aug 11 13:54:49 2008 +0900 @@ -0,0 +1,53 @@ +/* + * FCKeditor - The text editor for Internet - http://www.fckeditor.net + * Copyright (C) 2003-2008 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 == + * + * This is a generic Document Fragment object. It is not intended to provide + * the W3C implementation, but is a way to fix the missing of a real Document + * Fragment in IE (where document.createDocumentFragment() returns a normal + * document instead), giving a standard interface for it. + * (IE Implementation) + */ + +var FCKDocumentFragment = function( parentDocument, baseDocFrag ) +{ + this.RootNode = baseDocFrag || parentDocument.createDocumentFragment() ; +} + +FCKDocumentFragment.prototype = +{ + + // Append the contents of this Document Fragment to another element. + AppendTo : function( targetNode ) + { + targetNode.appendChild( this.RootNode ) ; + }, + + AppendHtml : function( html ) + { + var eTmpDiv = this.RootNode.ownerDocument.createElement( 'div' ) ; + eTmpDiv.innerHTML = html ; + FCKDomTools.MoveChildren( eTmpDiv, this.RootNode ) ; + }, + + InsertAfterNode : function( existingNode ) + { + FCKDomTools.InsertAfterNode( existingNode, this.RootNode ) ; + } +} diff -r 3791b2e8e471 -r f5c322ae1c7b wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckdocumentfragment_ie.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckdocumentfragment_ie.js Mon Aug 11 13:54:49 2008 +0900 @@ -0,0 +1,58 @@ +/* + * FCKeditor - The text editor for Internet - http://www.fckeditor.net + * Copyright (C) 2003-2008 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 == + * + * This is a generic Document Fragment object. It is not intended to provide + * the W3C implementation, but is a way to fix the missing of a real Document + * Fragment in IE (where document.createDocumentFragment() returns a normal + * document instead), giving a standard interface for it. + * (IE Implementation) + */ + +var FCKDocumentFragment = function( parentDocument ) +{ + this._Document = parentDocument ; + this.RootNode = parentDocument.createElement( 'div' ) ; +} + +// Append the contents of this Document Fragment to another node. +FCKDocumentFragment.prototype = +{ + + AppendTo : function( targetNode ) + { + FCKDomTools.MoveChildren( this.RootNode, targetNode ) ; + }, + + AppendHtml : function( html ) + { + var eTmpDiv = this._Document.createElement( 'div' ) ; + eTmpDiv.innerHTML = html ; + FCKDomTools.MoveChildren( eTmpDiv, this.RootNode ) ; + }, + + InsertAfterNode : function( existingNode ) + { + var eRoot = this.RootNode ; + var eLast ; + + while( ( eLast = eRoot.lastChild ) ) + FCKDomTools.InsertAfterNode( existingNode, eRoot.removeChild( eLast ) ) ; + } +} ; diff -r 3791b2e8e471 -r f5c322ae1c7b wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckdomrange.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckdomrange.js Mon Aug 11 13:54:49 2008 +0900 @@ -0,0 +1,935 @@ +/* + * FCKeditor - The text editor for Internet - http://www.fckeditor.net + * Copyright (C) 2003-2008 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 == + * + * Class for working with a selection range, much like the W3C DOM Range, but + * it is not intended to be an implementation of the W3C interface. + */ + +var FCKDomRange = function( sourceWindow ) +{ + this.Window = sourceWindow ; + this._Cache = {} ; +} + +FCKDomRange.prototype = +{ + + _UpdateElementInfo : function() + { + var innerRange = this._Range ; + + if ( !innerRange ) + this.Release( true ) ; + else + { + // For text nodes, the node itself is the StartNode. + var eStart = innerRange.startContainer ; + + var oElementPath = new FCKElementPath( eStart ) ; + this.StartNode = eStart.nodeType == 3 ? eStart : eStart.childNodes[ innerRange.startOffset ] ; + this.StartContainer = eStart ; + this.StartBlock = oElementPath.Block ; + this.StartBlockLimit = oElementPath.BlockLimit ; + + if ( innerRange.collapsed ) + { + this.EndNode = this.StartNode ; + this.EndContainer = this.StartContainer ; + this.EndBlock = this.StartBlock ; + this.EndBlockLimit = this.StartBlockLimit ; + } + else + { + var eEnd = innerRange.endContainer ; + + if ( eStart != eEnd ) + oElementPath = new FCKElementPath( eEnd ) ; + + // The innerRange.endContainer[ innerRange.endOffset ] is not + // usually part of the range, but the marker for the range end. So, + // let's get the previous available node as the real end. + var eEndNode = eEnd ; + if ( innerRange.endOffset == 0 ) + { + while ( eEndNode && !eEndNode.previousSibling ) + eEndNode = eEndNode.parentNode ; + + if ( eEndNode ) + eEndNode = eEndNode.previousSibling ; + } + else if ( eEndNode.nodeType == 1 ) + eEndNode = eEndNode.childNodes[ innerRange.endOffset - 1 ] ; + + this.EndNode = eEndNode ; + this.EndContainer = eEnd ; + this.EndBlock = oElementPath.Block ; + this.EndBlockLimit = oElementPath.BlockLimit ; + } + } + + this._Cache = {} ; + }, + + CreateRange : function() + { + return new FCKW3CRange( this.Window.document ) ; + }, + + DeleteContents : function() + { + if ( this._Range ) + { + this._Range.deleteContents() ; + this._UpdateElementInfo() ; + } + }, + + ExtractContents : function() + { + if ( this._Range ) + { + var docFrag = this._Range.extractContents() ; + this._UpdateElementInfo() ; + return docFrag ; + } + return null ; + }, + + CheckIsCollapsed : function() + { + if ( this._Range ) + return this._Range.collapsed ; + + return false ; + }, + + Collapse : function( toStart ) + { + if ( this._Range ) + this._Range.collapse( toStart ) ; + + this._UpdateElementInfo() ; + }, + + Clone : function() + { + var oClone = FCKTools.CloneObject( this ) ; + + if ( this._Range ) + oClone._Range = this._Range.cloneRange() ; + + return oClone ; + }, + + MoveToNodeContents : function( targetNode ) + { + if ( !this._Range ) + this._Range = this.CreateRange() ; + + this._Range.selectNodeContents( targetNode ) ; + + this._UpdateElementInfo() ; + }, + + MoveToElementStart : function( targetElement ) + { + this.SetStart(targetElement,1) ; + this.SetEnd(targetElement,1) ; + }, + + // Moves to the first editing point inside a element. For example, in a + // element tree like "

Text

", the start editing point + // is "

^ Text

" (inside ). + MoveToElementEditStart : function( targetElement ) + { + var editableElement ; + + while ( targetElement && targetElement.nodeType == 1 ) + { + if ( FCKDomTools.CheckIsEditable( targetElement ) ) + editableElement = targetElement ; + else if ( editableElement ) + break ; // If we already found an editable element, stop the loop. + + targetElement = targetElement.firstChild ; + } + + if ( editableElement ) + this.MoveToElementStart( editableElement ) ; + }, + + InsertNode : function( node ) + { + if ( this._Range ) + this._Range.insertNode( node ) ; + }, + + CheckIsEmpty : function() + { + if ( this.CheckIsCollapsed() ) + return true ; + + // Inserts the contents of the range in a div tag. + var eToolDiv = this.Window.document.createElement( 'div' ) ; + this._Range.cloneContents().AppendTo( eToolDiv ) ; + + FCKDomTools.TrimNode( eToolDiv ) ; + + return ( eToolDiv.innerHTML.length == 0 ) ; + }, + + /** + * Checks if the start boundary of the current range is "visually" (like a + * selection caret) at the beginning of the block. It means that some + * things could be brefore the range, like spaces or empty inline elements, + * but it would still be considered at the beginning of the block. + */ + CheckStartOfBlock : function() + { + var cache = this._Cache ; + var bIsStartOfBlock = cache.IsStartOfBlock ; + + if ( bIsStartOfBlock != undefined ) + return bIsStartOfBlock ; + + // Take the block reference. + var block = this.StartBlock || this.StartBlockLimit ; + + var container = this._Range.startContainer ; + var offset = this._Range.startOffset ; + var currentNode ; + + if ( offset > 0 ) + { + // First, check the start container. If it is a text node, get the + // substring of the node value before the range offset. + if ( container.nodeType == 3 ) + { + var textValue = container.nodeValue.substr( 0, offset ).Trim() ; + + // If we have some text left in the container, we are not at + // the end for the block. + if ( textValue.length != 0 ) + return cache.IsStartOfBlock = false ; + } + else + currentNode = container.childNodes[ offset - 1 ] ; + } + + // We'll not have a currentNode if the container was a text node, or + // the offset is zero. + if ( !currentNode ) + currentNode = FCKDomTools.GetPreviousSourceNode( container, true, null, block ) ; + + while ( currentNode ) + { + switch ( currentNode.nodeType ) + { + case 1 : + // It's not an inline element. + if ( !FCKListsLib.InlineChildReqElements[ currentNode.nodeName.toLowerCase() ] ) + return cache.IsStartOfBlock = false ; + + break ; + + case 3 : + // It's a text node with real text. + if ( currentNode.nodeValue.Trim().length > 0 ) + return cache.IsStartOfBlock = false ; + } + + currentNode = FCKDomTools.GetPreviousSourceNode( currentNode, false, null, block ) ; + } + + return cache.IsStartOfBlock = true ; + }, + + /** + * Checks if the end boundary of the current range is "visually" (like a + * selection caret) at the end of the block. It means that some things + * could be after the range, like spaces, empty inline elements, or a + * single
, but it would still be considered at the end of the block. + */ + CheckEndOfBlock : function( refreshSelection ) + { + var isEndOfBlock = this._Cache.IsEndOfBlock ; + + if ( isEndOfBlock != undefined ) + return isEndOfBlock ; + + // Take the block reference. + var block = this.EndBlock || this.EndBlockLimit ; + + var container = this._Range.endContainer ; + var offset = this._Range.endOffset ; + var currentNode ; + + // First, check the end container. If it is a text node, get the + // substring of the node value after the range offset. + if ( container.nodeType == 3 ) + { + var textValue = container.nodeValue ; + if ( offset < textValue.length ) + { + textValue = textValue.substr( offset ) ; + + // If we have some text left in the container, we are not at + // the end for the block. + if ( textValue.Trim().length != 0 ) + return this._Cache.IsEndOfBlock = false ; + } + } + else + currentNode = container.childNodes[ offset ] ; + + // We'll not have a currentNode if the container was a text node, of + // the offset is out the container children limits (after it probably). + if ( !currentNode ) + currentNode = FCKDomTools.GetNextSourceNode( container, true, null, block ) ; + + var hadBr = false ; + + while ( currentNode ) + { + switch ( currentNode.nodeType ) + { + case 1 : + var nodeName = currentNode.nodeName.toLowerCase() ; + + // It's an inline element. + if ( FCKListsLib.InlineChildReqElements[ nodeName ] ) + break ; + + // It is the first
found. + if ( nodeName == 'br' && !hadBr ) + { + hadBr = true ; + break ; + } + + return this._Cache.IsEndOfBlock = false ; + + case 3 : + // It's a text node with real text. + if ( currentNode.nodeValue.Trim().length > 0 ) + return this._Cache.IsEndOfBlock = false ; + } + + currentNode = FCKDomTools.GetNextSourceNode( currentNode, false, null, block ) ; + } + + if ( refreshSelection ) + this.Select() ; + + return this._Cache.IsEndOfBlock = true ; + }, + + // This is an "intrusive" way to create a bookmark. It includes tags + // in the range boundaries. The advantage of it is that it is possible to + // handle DOM mutations when moving back to the bookmark. + // Attention: the inclusion of nodes in the DOM is a design choice and + // should not be changed as there are other points in the code that may be + // using those nodes to perform operations. See GetBookmarkNode. + // For performance, includeNodes=true if intended to SelectBookmark. + CreateBookmark : function( includeNodes ) + { + // Create the bookmark info (random IDs). + var oBookmark = + { + StartId : (new Date()).valueOf() + Math.floor(Math.random()*1000) + 'S', + EndId : (new Date()).valueOf() + Math.floor(Math.random()*1000) + 'E' + } ; + + var oDoc = this.Window.document ; + var eStartSpan ; + var eEndSpan ; + var oClone ; + + // For collapsed ranges, add just the start marker. + if ( !this.CheckIsCollapsed() ) + { + eEndSpan = oDoc.createElement( 'span' ) ; + eEndSpan.style.display = 'none' ; + eEndSpan.id = oBookmark.EndId ; + eEndSpan.setAttribute( '_fck_bookmark', true ) ; + + // For IE, it must have something inside, otherwise it may be + // removed during DOM operations. +// if ( FCKBrowserInfo.IsIE ) + eEndSpan.innerHTML = ' ' ; + + oClone = this.Clone() ; + oClone.Collapse( false ) ; + oClone.InsertNode( eEndSpan ) ; + } + + eStartSpan = oDoc.createElement( 'span' ) ; + eStartSpan.style.display = 'none' ; + eStartSpan.id = oBookmark.StartId ; + eStartSpan.setAttribute( '_fck_bookmark', true ) ; + + // For IE, it must have something inside, otherwise it may be removed + // during DOM operations. +// if ( FCKBrowserInfo.IsIE ) + eStartSpan.innerHTML = ' ' ; + + oClone = this.Clone() ; + oClone.Collapse( true ) ; + oClone.InsertNode( eStartSpan ) ; + + if ( includeNodes ) + { + oBookmark.StartNode = eStartSpan ; + oBookmark.EndNode = eEndSpan ; + } + + // Update the range position. + if ( eEndSpan ) + { + this.SetStart( eStartSpan, 4 ) ; + this.SetEnd( eEndSpan, 3 ) ; + } + else + this.MoveToPosition( eStartSpan, 4 ) ; + + return oBookmark ; + }, + + // This one should be a part of a hypothetic "bookmark" object. + GetBookmarkNode : function( bookmark, start ) + { + var doc = this.Window.document ; + + if ( start ) + return bookmark.StartNode || doc.getElementById( bookmark.StartId ) ; + else + return bookmark.EndNode || doc.getElementById( bookmark.EndId ) ; + }, + + MoveToBookmark : function( bookmark, preserveBookmark ) + { + var eStartSpan = this.GetBookmarkNode( bookmark, true ) ; + var eEndSpan = this.GetBookmarkNode( bookmark, false ) ; + + this.SetStart( eStartSpan, 3 ) ; + + if ( !preserveBookmark ) + FCKDomTools.RemoveNode( eStartSpan ) ; + + // If collapsed, the end span will not be available. + if ( eEndSpan ) + { + this.SetEnd( eEndSpan, 3 ) ; + + if ( !preserveBookmark ) + FCKDomTools.RemoveNode( eEndSpan ) ; + } + else + this.Collapse( true ) ; + + this._UpdateElementInfo() ; + }, + + // Non-intrusive bookmark algorithm + CreateBookmark2 : function() + { + // If there is no range then get out of here. + // It happens on initial load in Safari #962 and if the editor it's hidden also in Firefox + if ( ! this._Range ) + return { "Start" : 0, "End" : 0 } ; + + // First, we record down the offset values + var bookmark = + { + "Start" : [ this._Range.startOffset ], + "End" : [ this._Range.endOffset ] + } ; + // Since we're treating the document tree as normalized, we need to backtrack the text lengths + // of previous text nodes into the offset value. + var curStart = this._Range.startContainer.previousSibling ; + var curEnd = this._Range.endContainer.previousSibling ; + + // Also note that the node that we use for "address base" would change during backtracking. + var addrStart = this._Range.startContainer ; + var addrEnd = this._Range.endContainer ; + while ( curStart && addrStart.nodeType == 3 ) + { + bookmark.Start[0] += curStart.length ; + addrStart = curStart ; + curStart = curStart.previousSibling ; + } + while ( curEnd && addrEnd.nodeType == 3 ) + { + bookmark.End[0] += curEnd.length ; + addrEnd = curEnd ; + curEnd = curEnd.previousSibling ; + } + + // If the object pointed to by the startOffset and endOffset are text nodes, we need + // to backtrack and add in the text offset to the bookmark addresses. + if ( addrStart.nodeType == 1 && addrStart.childNodes[bookmark.Start[0]] && addrStart.childNodes[bookmark.Start[0]].nodeType == 3 ) + { + var curNode = addrStart.childNodes[bookmark.Start[0]] ; + var offset = 0 ; + while ( curNode.previousSibling && curNode.previousSibling.nodeType == 3 ) + { + curNode = curNode.previousSibling ; + offset += curNode.length ; + } + addrStart = curNode ; + bookmark.Start[0] = offset ; + } + if ( addrEnd.nodeType == 1 && addrEnd.childNodes[bookmark.End[0]] && addrEnd.childNodes[bookmark.End[0]].nodeType == 3 ) + { + var curNode = addrEnd.childNodes[bookmark.End[0]] ; + var offset = 0 ; + while ( curNode.previousSibling && curNode.previousSibling.nodeType == 3 ) + { + curNode = curNode.previousSibling ; + offset += curNode.length ; + } + addrEnd = curNode ; + bookmark.End[0] = offset ; + } + + // Then, we record down the precise position of the container nodes + // by walking up the DOM tree and counting their childNode index + bookmark.Start = FCKDomTools.GetNodeAddress( addrStart, true ).concat( bookmark.Start ) ; + bookmark.End = FCKDomTools.GetNodeAddress( addrEnd, true ).concat( bookmark.End ) ; + return bookmark; + }, + + MoveToBookmark2 : function( bookmark ) + { + // Reverse the childNode counting algorithm in CreateBookmark2() + var curStart = FCKDomTools.GetNodeFromAddress( this.Window.document, bookmark.Start.slice( 0, -1 ), true ) ; + var curEnd = FCKDomTools.GetNodeFromAddress( this.Window.document, bookmark.End.slice( 0, -1 ), true ) ; + + // Generate the W3C Range object and update relevant data + this.Release( true ) ; + this._Range = new FCKW3CRange( this.Window.document ) ; + var startOffset = bookmark.Start[ bookmark.Start.length - 1 ] ; + var endOffset = bookmark.End[ bookmark.End.length - 1 ] ; + while ( curStart.nodeType == 3 && startOffset > curStart.length ) + { + if ( ! curStart.nextSibling || curStart.nextSibling.nodeType != 3 ) + break ; + startOffset -= curStart.length ; + curStart = curStart.nextSibling ; + } + while ( curEnd.nodeType == 3 && endOffset > curEnd.length ) + { + if ( ! curEnd.nextSibling || curEnd.nextSibling.nodeType != 3 ) + break ; + endOffset -= curEnd.length ; + curEnd = curEnd.nextSibling ; + } + this._Range.setStart( curStart, startOffset ) ; + this._Range.setEnd( curEnd, endOffset ) ; + this._UpdateElementInfo() ; + }, + + MoveToPosition : function( targetElement, position ) + { + this.SetStart( targetElement, position ) ; + this.Collapse( true ) ; + }, + + /* + * Moves the position of the start boundary of the range to a specific position + * relatively to a element. + * @position: + * 1 = After Start ^contents + * 2 = Before End contents^ + * 3 = Before Start ^contents + * 4 = After End contents^ + */ + SetStart : function( targetElement, position, noInfoUpdate ) + { + var oRange = this._Range ; + if ( !oRange ) + oRange = this._Range = this.CreateRange() ; + + switch( position ) + { + case 1 : // After Start ^contents + oRange.setStart( targetElement, 0 ) ; + break ; + + case 2 : // Before End contents^ + oRange.setStart( targetElement, targetElement.childNodes.length ) ; + break ; + + case 3 : // Before Start ^contents + oRange.setStartBefore( targetElement ) ; + break ; + + case 4 : // After End contents^ + oRange.setStartAfter( targetElement ) ; + } + + if ( !noInfoUpdate ) + this._UpdateElementInfo() ; + }, + + /* + * Moves the position of the start boundary of the range to a specific position + * relatively to a element. + * @position: + * 1 = After Start ^contents + * 2 = Before End contents^ + * 3 = Before Start ^contents + * 4 = After End contents^ + */ + SetEnd : function( targetElement, position, noInfoUpdate ) + { + var oRange = this._Range ; + if ( !oRange ) + oRange = this._Range = this.CreateRange() ; + + switch( position ) + { + case 1 : // After Start ^contents + oRange.setEnd( targetElement, 0 ) ; + break ; + + case 2 : // Before End contents^ + oRange.setEnd( targetElement, targetElement.childNodes.length ) ; + break ; + + case 3 : // Before Start ^contents + oRange.setEndBefore( targetElement ) ; + break ; + + case 4 : // After End contents^ + oRange.setEndAfter( targetElement ) ; + } + + if ( !noInfoUpdate ) + this._UpdateElementInfo() ; + }, + + Expand : function( unit ) + { + var oNode, oSibling ; + + switch ( unit ) + { + // Expand the range to include all inline parent elements if we are + // are in their boundary limits. + // For example (where [ ] are the range limits): + // Before => Some [Some sample text]. + // After => Some [Some sample text]. + case 'inline_elements' : + // Expand the start boundary. + if ( this._Range.startOffset == 0 ) + { + oNode = this._Range.startContainer ; + + if ( oNode.nodeType != 1 ) + oNode = oNode.previousSibling ? null : oNode.parentNode ; + + if ( oNode ) + { + while ( FCKListsLib.InlineNonEmptyElements[ oNode.nodeName.toLowerCase() ] ) + { + this._Range.setStartBefore( oNode ) ; + + if ( oNode != oNode.parentNode.firstChild ) + break ; + + oNode = oNode.parentNode ; + } + } + } + + // Expand the end boundary. + oNode = this._Range.endContainer ; + var offset = this._Range.endOffset ; + + if ( ( oNode.nodeType == 3 && offset >= oNode.nodeValue.length ) || ( oNode.nodeType == 1 && offset >= oNode.childNodes.length ) || ( oNode.nodeType != 1 && oNode.nodeType != 3 ) ) + { + if ( oNode.nodeType != 1 ) + oNode = oNode.nextSibling ? null : oNode.parentNode ; + + if ( oNode ) + { + while ( FCKListsLib.InlineNonEmptyElements[ oNode.nodeName.toLowerCase() ] ) + { + this._Range.setEndAfter( oNode ) ; + + if ( oNode != oNode.parentNode.lastChild ) + break ; + + oNode = oNode.parentNode ; + } + } + } + + break ; + + case 'block_contents' : + case 'list_contents' : + var boundarySet = FCKListsLib.BlockBoundaries ; + if ( unit == 'list_contents' || FCKConfig.EnterMode == 'br' ) + boundarySet = FCKListsLib.ListBoundaries ; + + if ( this.StartBlock && FCKConfig.EnterMode != 'br' && unit == 'block_contents' ) + this.SetStart( this.StartBlock, 1 ) ; + else + { + // Get the start node for the current range. + oNode = this._Range.startContainer ; + + // If it is an element, get the node right before of it (in source order). + if ( oNode.nodeType == 1 ) + { + var lastNode = oNode.childNodes[ this._Range.startOffset ] ; + if ( lastNode ) + oNode = FCKDomTools.GetPreviousSourceNode( lastNode, true ) ; + else + oNode = oNode.lastChild || oNode ; + } + + // We must look for the left boundary, relative to the range + // start, which is limited by a block element. + while ( oNode + && ( oNode.nodeType != 1 + || ( oNode != this.StartBlockLimit + && !boundarySet[ oNode.nodeName.toLowerCase() ] ) ) ) + { + this._Range.setStartBefore( oNode ) ; + oNode = oNode.previousSibling || oNode.parentNode ; + } + } + + if ( this.EndBlock && FCKConfig.EnterMode != 'br' && unit == 'block_contents' && this.EndBlock.nodeName.toLowerCase() != 'li' ) + this.SetEnd( this.EndBlock, 2 ) ; + else + { + oNode = this._Range.endContainer ; + if ( oNode.nodeType == 1 ) + oNode = oNode.childNodes[ this._Range.endOffset ] || oNode.lastChild ; + + // We must look for the right boundary, relative to the range + // end, which is limited by a block element. + while ( oNode + && ( oNode.nodeType != 1 + || ( oNode != this.StartBlockLimit + && !boundarySet[ oNode.nodeName.toLowerCase() ] ) ) ) + { + this._Range.setEndAfter( oNode ) ; + oNode = oNode.nextSibling || oNode.parentNode ; + } + + // In EnterMode='br', the end
boundary element must + // be included in the expanded range. + if ( oNode && oNode.nodeName.toLowerCase() == 'br' ) + this._Range.setEndAfter( oNode ) ; + } + + this._UpdateElementInfo() ; + } + }, + + /** + * Split the block element for the current range. It deletes the contents + * of the range and splits the block in the collapsed position, resulting + * in two sucessive blocks. The range is then positioned in the middle of + * them. + * + * It returns and object with the following properties: + * - PreviousBlock : a reference to the block element that preceeds + * the range after the split. + * - NextBlock : a reference to the block element that follows the + * range after the split. + * - WasStartOfBlock : a boolean indicating that the range was + * originaly at the start of the block. + * - WasEndOfBlock : a boolean indicating that the range was originaly + * at the end of the block. + * + * If the range was originaly at the start of the block, no split will happen + * and the PreviousBlock value will be null. The same is valid for the + * NextBlock value if the range was at the end of the block. + */ + SplitBlock : function( forceBlockTag ) + { + var blockTag = forceBlockTag || FCKConfig.EnterMode ; + + if ( !this._Range ) + this.MoveToSelection() ; + + // The range boundaries must be in the same "block limit" element. + if ( this.StartBlockLimit == this.EndBlockLimit ) + { + // Get the current blocks. + var eStartBlock = this.StartBlock ; + var eEndBlock = this.EndBlock ; + var oElementPath = null ; + + if ( blockTag != 'br' ) + { + if ( !eStartBlock ) + { + eStartBlock = this.FixBlock( true, blockTag ) ; + eEndBlock = this.EndBlock ; // FixBlock may have fixed the EndBlock too. + } + + if ( !eEndBlock ) + eEndBlock = this.FixBlock( false, blockTag ) ; + } + + // Get the range position. + var bIsStartOfBlock = ( eStartBlock != null && this.CheckStartOfBlock() ) ; + var bIsEndOfBlock = ( eEndBlock != null && this.CheckEndOfBlock() ) ; + + // Delete the current contents. + if ( !this.CheckIsEmpty() ) + this.DeleteContents() ; + + if ( eStartBlock && eEndBlock && eStartBlock == eEndBlock ) + { + if ( bIsEndOfBlock ) + { + oElementPath = new FCKElementPath( this.StartContainer ) ; + this.MoveToPosition( eEndBlock, 4 ) ; + eEndBlock = null ; + } + else if ( bIsStartOfBlock ) + { + oElementPath = new FCKElementPath( this.StartContainer ) ; + this.MoveToPosition( eStartBlock, 3 ) ; + eStartBlock = null ; + } + else + { + // Extract the contents of the block from the selection point to the end of its contents. + this.SetEnd( eStartBlock, 2 ) ; + var eDocFrag = this.ExtractContents() ; + + // Duplicate the block element after it. + eEndBlock = eStartBlock.cloneNode( false ) ; + eEndBlock.removeAttribute( 'id', false ) ; + + // Place the extracted contents in the duplicated block. + eDocFrag.AppendTo( eEndBlock ) ; + + FCKDomTools.InsertAfterNode( eStartBlock, eEndBlock ) ; + + this.MoveToPosition( eStartBlock, 4 ) ; + + // In Gecko, the last child node must be a bogus
. + // Note: bogus
added under
    or
      would cause lists to be incorrectly rendered. + if ( FCKBrowserInfo.IsGecko && + ! eStartBlock.nodeName.IEquals( ['ul', 'ol'] ) ) + FCKTools.AppendBogusBr( eStartBlock ) ; + } + } + + return { + PreviousBlock : eStartBlock, + NextBlock : eEndBlock, + WasStartOfBlock : bIsStartOfBlock, + WasEndOfBlock : bIsEndOfBlock, + ElementPath : oElementPath + } ; + } + + return null ; + }, + + // Transform a block without a block tag in a valid block (orphan text in the body or td, usually). + FixBlock : function( isStart, blockTag ) + { + // Bookmark the range so we can restore it later. + var oBookmark = this.CreateBookmark() ; + + // Collapse the range to the requested ending boundary. + this.Collapse( isStart ) ; + + // Expands it to the block contents. + this.Expand( 'block_contents' ) ; + + // Create the fixed block. + var oFixedBlock = this.Window.document.createElement( blockTag ) ; + + // Move the contents of the temporary range to the fixed block. + this.ExtractContents().AppendTo( oFixedBlock ) ; + FCKDomTools.TrimNode( oFixedBlock ) ; + + // If the fixed block is empty (not counting bookmark nodes) + // Add a
      inside to expand it. + if ( FCKDomTools.CheckIsEmptyElement(oFixedBlock, function( element ) { return element.getAttribute('_fck_bookmark') != 'true' ; } ) + && FCKBrowserInfo.IsGeckoLike ) + FCKTools.AppendBogusBr( oFixedBlock ) ; + + // Insert the fixed block into the DOM. + this.InsertNode( oFixedBlock ) ; + + // Move the range back to the bookmarked place. + this.MoveToBookmark( oBookmark ) ; + + return oFixedBlock ; + }, + + Release : function( preserveWindow ) + { + if ( !preserveWindow ) + this.Window = null ; + + this.StartNode = null ; + this.StartContainer = null ; + this.StartBlock = null ; + this.StartBlockLimit = null ; + this.EndNode = null ; + this.EndContainer = null ; + this.EndBlock = null ; + this.EndBlockLimit = null ; + this._Range = null ; + this._Cache = null ; + }, + + CheckHasRange : function() + { + return !!this._Range ; + }, + + GetTouchedStartNode : function() + { + var range = this._Range ; + var container = range.startContainer ; + + if ( range.collapsed || container.nodeType != 1 ) + return container ; + + return container.childNodes[ range.startOffset ] || container ; + }, + + GetTouchedEndNode : function() + { + var range = this._Range ; + var container = range.endContainer ; + + if ( range.collapsed || container.nodeType != 1 ) + return container ; + + return container.childNodes[ range.endOffset - 1 ] || container ; + } +} ; diff -r 3791b2e8e471 -r f5c322ae1c7b wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckdomrange_gecko.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckdomrange_gecko.js Mon Aug 11 13:54:49 2008 +0900 @@ -0,0 +1,104 @@ +/* + * FCKeditor - The text editor for Internet - http://www.fckeditor.net + * Copyright (C) 2003-2008 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 == + * + * Class for working with a selection range, much like the W3C DOM Range, but + * it is not intended to be an implementation of the W3C interface. + * (Gecko Implementation) + */ + +FCKDomRange.prototype.MoveToSelection = function() +{ + this.Release( true ) ; + + var oSel = this.Window.getSelection() ; + + if ( oSel && oSel.rangeCount > 0 ) + { + this._Range = FCKW3CRange.CreateFromRange( this.Window.document, oSel.getRangeAt(0) ) ; + this._UpdateElementInfo() ; + } + else + if ( this.Window.document ) + this.MoveToElementStart( this.Window.document.body ) ; +} + +FCKDomRange.prototype.Select = function() +{ + var oRange = this._Range ; + if ( oRange ) + { + var startContainer = oRange.startContainer ; + + // If we have a collapsed range, inside an empty element, we must add + // something to it, otherwise the caret will not be visible. + if ( oRange.collapsed && startContainer.nodeType == 1 && startContainer.childNodes.length == 0 ) + startContainer.appendChild( oRange._Document.createTextNode('') ) ; + + var oDocRange = this.Window.document.createRange() ; + oDocRange.setStart( startContainer, oRange.startOffset ) ; + + try + { + oDocRange.setEnd( oRange.endContainer, oRange.endOffset ) ; + } + catch ( e ) + { + // There is a bug in Firefox implementation (it would be too easy + // otherwise). The new start can't be after the end (W3C says it can). + // So, let's create a new range and collapse it to the desired point. + if ( e.toString().Contains( 'NS_ERROR_ILLEGAL_VALUE' ) ) + { + oRange.collapse( true ) ; + oDocRange.setEnd( oRange.endContainer, oRange.endOffset ) ; + } + else + throw( e ) ; + } + + var oSel = this.Window.getSelection() ; + oSel.removeAllRanges() ; + + // We must add a clone otherwise Firefox will have rendering issues. + oSel.addRange( oDocRange ) ; + } +} + +// Not compatible with bookmark created with CreateBookmark2. +// The bookmark nodes will be deleted from the document. +FCKDomRange.prototype.SelectBookmark = function( bookmark ) +{ + var domRange = this.Window.document.createRange() ; + + var startNode = this.GetBookmarkNode( bookmark, true ) ; + var endNode = this.GetBookmarkNode( bookmark, false ) ; + + domRange.setStart( startNode.parentNode, FCKDomTools.GetIndexOf( startNode ) ) ; + FCKDomTools.RemoveNode( startNode ) ; + + if ( endNode ) + { + domRange.setEnd( endNode.parentNode, FCKDomTools.GetIndexOf( endNode ) ) ; + FCKDomTools.RemoveNode( endNode ) ; + } + + var selection = this.Window.getSelection() ; + selection.removeAllRanges() ; + selection.addRange( domRange ) ; +} diff -r 3791b2e8e471 -r f5c322ae1c7b wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckdomrange_ie.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckdomrange_ie.js Mon Aug 11 13:54:49 2008 +0900 @@ -0,0 +1,199 @@ +/* + * FCKeditor - The text editor for Internet - http://www.fckeditor.net + * Copyright (C) 2003-2008 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 == + * + * Class for working with a selection range, much like the W3C DOM Range, but + * it is not intended to be an implementation of the W3C interface. + * (IE Implementation) + */ + +FCKDomRange.prototype.MoveToSelection = function() +{ + this.Release( true ) ; + + this._Range = new FCKW3CRange( this.Window.document ) ; + + var oSel = this.Window.document.selection ; + + if ( oSel.type != 'Control' ) + { + var eMarkerStart = this._GetSelectionMarkerTag( true ) ; + var eMarkerEnd = this._GetSelectionMarkerTag( false ) ; + + if ( !eMarkerStart && !eMarkerEnd ) + { + this._Range.setStart( this.Window.document.body, 0 ) ; + this._UpdateElementInfo() ; + return ; + } + + // Set the start boundary. + this._Range.setStart( eMarkerStart.parentNode, FCKDomTools.GetIndexOf( eMarkerStart ) ) ; + eMarkerStart.parentNode.removeChild( eMarkerStart ) ; + + // Set the end boundary. + this._Range.setEnd( eMarkerEnd.parentNode, FCKDomTools.GetIndexOf( eMarkerEnd ) ) ; + eMarkerEnd.parentNode.removeChild( eMarkerEnd ) ; + + this._UpdateElementInfo() ; + } + else + { + var oControl = oSel.createRange().item(0) ; + + if ( oControl ) + { + this._Range.setStartBefore( oControl ) ; + this._Range.setEndAfter( oControl ) ; + this._UpdateElementInfo() ; + } + } +} + +FCKDomRange.prototype.Select = function( forceExpand ) +{ + if ( this._Range ) + this.SelectBookmark( this.CreateBookmark( true ), forceExpand ) ; +} + +// Not compatible with bookmark created with CreateBookmark2. +// The bookmark nodes will be deleted from the document. +FCKDomRange.prototype.SelectBookmark = function( bookmark, forceExpand ) +{ + var bIsCollapsed = this.CheckIsCollapsed() ; + var bIsStartMakerAlone ; + var dummySpan ; + + // Create marker tags for the start and end boundaries. + var eStartMarker = this.GetBookmarkNode( bookmark, true ) ; + + if ( !eStartMarker ) + return ; + + var eEndMarker ; + if ( !bIsCollapsed ) + eEndMarker = this.GetBookmarkNode( bookmark, false ) ; + + // Create the main range which will be used for the selection. + var oIERange = this.Window.document.body.createTextRange() ; + + // Position the range at the start boundary. + oIERange.moveToElementText( eStartMarker ) ; + oIERange.moveStart( 'character', 1 ) ; + + if ( eEndMarker ) + { + // Create a tool range for the end. + var oIERangeEnd = this.Window.document.body.createTextRange() ; + + // Position the tool range at the end. + oIERangeEnd.moveToElementText( eEndMarker ) ; + + // Move the end boundary of the main range to match the tool range. + oIERange.setEndPoint( 'EndToEnd', oIERangeEnd ) ; + oIERange.moveEnd( 'character', -1 ) ; + } + else + { + bIsStartMakerAlone = ( forceExpand || !eStartMarker.previousSibling || eStartMarker.previousSibling.nodeName.toLowerCase() == 'br' ) && !eStartMarker.nextSibing ; + + // Append a temporary  before the selection. + // This is needed to avoid IE destroying selections inside empty + // inline elements, like (#253). + // It is also needed when placing the selection right after an inline + // element to avoid the selection moving inside of it. + dummySpan = this.Window.document.createElement( 'span' ) ; + dummySpan.innerHTML = '' ; // Zero Width No-Break Space (U+FEFF). See #1359. + eStartMarker.parentNode.insertBefore( dummySpan, eStartMarker ) ; + + if ( bIsStartMakerAlone ) + { + // To expand empty blocks or line spaces after
      , we need + // instead to have any char, which will be later deleted using the + // selection. + // \ufeff = Zero Width No-Break Space (U+FEFF). See #1359. + eStartMarker.parentNode.insertBefore( this.Window.document.createTextNode( '\ufeff' ), eStartMarker ) ; + } + } + + if ( !this._Range ) + this._Range = this.CreateRange() ; + + // Remove the markers (reset the position, because of the changes in the DOM tree). + this._Range.setStartBefore( eStartMarker ) ; + eStartMarker.parentNode.removeChild( eStartMarker ) ; + + if ( bIsCollapsed ) + { + if ( bIsStartMakerAlone ) + { + // Move the selection start to include the temporary . + oIERange.moveStart( 'character', -1 ) ; + + oIERange.select() ; + + // Remove our temporary stuff. + this.Window.document.selection.clear() ; + } + else + oIERange.select() ; + + FCKDomTools.RemoveNode( dummySpan ) ; + } + else + { + this._Range.setEndBefore( eEndMarker ) ; + eEndMarker.parentNode.removeChild( eEndMarker ) ; + oIERange.select() ; + } +} + +FCKDomRange.prototype._GetSelectionMarkerTag = function( toStart ) +{ + var doc = this.Window.document ; + var selection = doc.selection ; + + // Get a range for the start boundary. + var oRange ; + + // IE may throw an "unspecified error" on some cases (it happened when + // loading _samples/default.html), so try/catch. + try + { + oRange = selection.createRange() ; + } + catch (e) + { + return null ; + } + + // IE might take the range object to the main window instead of inside the editor iframe window. + // This is known to happen when the editor window has not been selected before (See #933). + // We need to avoid that. + if ( oRange.parentElement().document != doc ) + return null ; + + oRange.collapse( toStart === true ) ; + + // Paste a marker element at the collapsed range and get it from the DOM. + var sMarkerId = 'fck_dom_range_temp_' + (new Date()).valueOf() + '_' + Math.floor(Math.random()*1000) ; + oRange.pasteHTML( '' ) ; + + return doc.getElementById( sMarkerId ) ; +} diff -r 3791b2e8e471 -r f5c322ae1c7b wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckdomrangeiterator.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckdomrangeiterator.js Mon Aug 11 13:54:49 2008 +0900 @@ -0,0 +1,327 @@ +/* + * FCKeditor - The text editor for Internet - http://www.fckeditor.net + * Copyright (C) 2003-2008 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 == + * + * This class can be used to interate through nodes inside a range. + * + * During interation, the provided range can become invalid, due to document + * mutations, so CreateBookmark() used to restore it after processing, if + * needed. + */ + +var FCKDomRangeIterator = function( range ) +{ + /** + * The FCKDomRange object that marks the interation boundaries. + */ + this.Range = range ; + + /** + * Indicates that
      elements must be used as paragraph boundaries. + */ + this.ForceBrBreak = false ; + + /** + * Guarantees that the iterator will always return "real" block elements. + * If "false", elements like
    1. , and are returned. If "true", a + * dedicated block element block element will be created inside those + * elements to hold the selected content. + */ + this.EnforceRealBlocks = false ; +} + +FCKDomRangeIterator.CreateFromSelection = function( targetWindow ) +{ + var range = new FCKDomRange( targetWindow ) ; + range.MoveToSelection() ; + return new FCKDomRangeIterator( range ) ; +} + +FCKDomRangeIterator.prototype = +{ + /** + * Get the next paragraph element. It automatically breaks the document + * when necessary to generate block elements for the paragraphs. + */ + GetNextParagraph : function() + { + // The block element to be returned. + var block ; + + // The range object used to identify the paragraph contents. + var range ; + + // Indicated that the current element in the loop is the last one. + var isLast ; + + // Instructs to cleanup remaining BRs. + var removePreviousBr ; + var removeLastBr ; + + var boundarySet = this.ForceBrBreak ? FCKListsLib.ListBoundaries : FCKListsLib.BlockBoundaries ; + + // This is the first iteration. Let's initialize it. + if ( !this._LastNode ) + { + var range = this.Range.Clone() ; + range.Expand( this.ForceBrBreak ? 'list_contents' : 'block_contents' ) ; + + this._NextNode = range.GetTouchedStartNode() ; + this._LastNode = range.GetTouchedEndNode() ; + + // Let's reuse this variable. + range = null ; + } + + var currentNode = this._NextNode ; + var lastNode = this._LastNode ; + + this._NextNode = null ; + + while ( currentNode ) + { + // closeRange indicates that a paragraph boundary has been found, + // so the range can be closed. + var closeRange = false ; + + // includeNode indicates that the current node is good to be part + // of the range. By default, any non-element node is ok for it. + var includeNode = ( currentNode.nodeType != 1 ) ; + + var continueFromSibling = false ; + + // If it is an element node, let's check if it can be part of the + // range. + if ( !includeNode ) + { + var nodeName = currentNode.nodeName.toLowerCase() ; + + if ( boundarySet[ nodeName ] && ( !FCKBrowserInfo.IsIE || currentNode.scopeName == 'HTML' ) ) + { + //
      boundaries must be part of the range. It will + // happen only if ForceBrBreak. + if ( nodeName == 'br' ) + includeNode = true ; + else if ( !range && currentNode.childNodes.length == 0 && nodeName != 'hr' ) + { + // If we have found an empty block, and haven't started + // the range yet, it means we must return this block. + block = currentNode ; + isLast = currentNode == lastNode ; + break ; + } + + // The range must finish right before the boundary, + // including possibly skipped empty spaces. (#1603) + if ( range ) + { + range.SetEnd( currentNode, 3, true ) ; + + // The found boundary must be set as the next one at this + // point. (#1717) + if ( nodeName != 'br' ) + this._NextNode = FCKDomTools.GetNextSourceNode( currentNode, true, null, lastNode ) ; + } + + closeRange = true ; + } + else + { + // If we have child nodes, let's check them. + if ( currentNode.firstChild ) + { + // If we don't have a range yet, let's start it. + if ( !range ) + { + range = new FCKDomRange( this.Range.Window ) ; + range.SetStart( currentNode, 3, true ) ; + } + + currentNode = currentNode.firstChild ; + continue ; + } + includeNode = true ; + } + } + else if ( currentNode.nodeType == 3 ) + { + // Ignore normal whitespaces (i.e. not including   or + // other unicode whitespaces) before/after a block node. + if ( /^[\r\n\t ]+$/.test( currentNode.nodeValue ) ) + includeNode = false ; + } + + // The current node is good to be part of the range and we are + // starting a new range, initialize it first. + if ( includeNode && !range ) + { + range = new FCKDomRange( this.Range.Window ) ; + range.SetStart( currentNode, 3, true ) ; + } + + // The last node has been found. + isLast = ( ( !closeRange || includeNode ) && currentNode == lastNode ) ; +// isLast = ( currentNode == lastNode && ( currentNode.nodeType != 1 || currentNode.childNodes.length == 0 ) ) ; + + // If we are in an element boundary, let's check if it is time + // to close the range, otherwise we include the parent within it. + if ( range && !closeRange ) + { + while ( !currentNode.nextSibling && !isLast ) + { + var parentNode = currentNode.parentNode ; + + if ( boundarySet[ parentNode.nodeName.toLowerCase() ] ) + { + closeRange = true ; + isLast = isLast || ( parentNode == lastNode ) ; + break ; + } + + currentNode = parentNode ; + includeNode = true ; + isLast = ( currentNode == lastNode ) ; + continueFromSibling = true ; + } + } + + // Now finally include the node. + if ( includeNode ) + range.SetEnd( currentNode, 4, true ) ; + + // We have found a block boundary. Let's close the range and move out of the + // loop. + if ( ( closeRange || isLast ) && range ) + { + range._UpdateElementInfo() ; + + if ( range.StartNode == range.EndNode + && range.StartNode.parentNode == range.StartBlockLimit + && range.StartNode.getAttribute && range.StartNode.getAttribute( '_fck_bookmark' ) ) + range = null ; + else + break ; + } + + if ( isLast ) + break ; + + currentNode = FCKDomTools.GetNextSourceNode( currentNode, continueFromSibling, null, lastNode ) ; + } + + // Now, based on the processed range, look for (or create) the block to be returned. + if ( !block ) + { + // If no range has been found, this is the end. + if ( !range ) + { + this._NextNode = null ; + return null ; + } + + block = range.StartBlock ; + + if ( !block + && !this.EnforceRealBlocks + && range.StartBlockLimit.nodeName.IEquals( 'DIV', 'TH', 'TD' ) + && range.CheckStartOfBlock() + && range.CheckEndOfBlock() ) + { + block = range.StartBlockLimit ; + } + else if ( !block || ( this.EnforceRealBlocks && block.nodeName.toLowerCase() == 'li' ) ) + { + // Create the fixed block. + block = this.Range.Window.document.createElement( FCKConfig.EnterMode == 'p' ? 'p' : 'div' ) ; + + // Move the contents of the temporary range to the fixed block. + range.ExtractContents().AppendTo( block ) ; + FCKDomTools.TrimNode( block ) ; + + // Insert the fixed block into the DOM. + range.InsertNode( block ) ; + + removePreviousBr = true ; + removeLastBr = true ; + } + else if ( block.nodeName.toLowerCase() != 'li' ) + { + // If the range doesn't includes the entire contents of the + // block, we must split it, isolating the range in a dedicated + // block. + if ( !range.CheckStartOfBlock() || !range.CheckEndOfBlock() ) + { + // The resulting block will be a clone of the current one. + block = block.cloneNode( false ) ; + + // Extract the range contents, moving it to the new block. + range.ExtractContents().AppendTo( block ) ; + FCKDomTools.TrimNode( block ) ; + + // Split the block. At this point, the range will be in the + // right position for our intents. + var splitInfo = range.SplitBlock() ; + + removePreviousBr = !splitInfo.WasStartOfBlock ; + removeLastBr = !splitInfo.WasEndOfBlock ; + + // Insert the new block into the DOM. + range.InsertNode( block ) ; + } + } + else if ( !isLast ) + { + // LIs are returned as is, with all their children (due to the + // nested lists). But, the next node is the node right after + // the current range, which could be an
    2. child (nested + // lists) or the next sibling
    3. . + + this._NextNode = block == lastNode ? null : FCKDomTools.GetNextSourceNode( range.EndNode, true, null, lastNode ) ; + return block ; + } + } + + if ( removePreviousBr ) + { + var previousSibling = block.previousSibling ; + if ( previousSibling && previousSibling.nodeType == 1 ) + { + if ( previousSibling.nodeName.toLowerCase() == 'br' ) + previousSibling.parentNode.removeChild( previousSibling ) ; + else if ( previousSibling.lastChild && previousSibling.lastChild.nodeName.IEquals( 'br' ) ) + previousSibling.removeChild( previousSibling.lastChild ) ; + } + } + + if ( removeLastBr ) + { + var lastChild = block.lastChild ; + if ( lastChild && lastChild.nodeType == 1 && lastChild.nodeName.toLowerCase() == 'br' ) + block.removeChild( lastChild ) ; + } + + // Get a reference for the next element. This is important because the + // above block can be removed or changed, so we can rely on it for the + // next interation. + if ( !this._NextNode ) + this._NextNode = ( isLast || block == lastNode ) ? null : FCKDomTools.GetNextSourceNode( block, true, null, lastNode ) ; + + return block ; + } +} ; diff -r 3791b2e8e471 -r f5c322ae1c7b wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckeditingarea.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckeditingarea.js Mon Aug 11 13:54:49 2008 +0900 @@ -0,0 +1,368 @@ +/* + * FCKeditor - The text editor for Internet - http://www.fckeditor.net + * Copyright (C) 2003-2008 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 == + * + * FCKEditingArea Class: renders an editable area. + */ + +/** + * @constructor + * @param {String} targetElement The element that will hold the editing area. Any child element present in the target will be deleted. + */ +var FCKEditingArea = function( targetElement ) +{ + this.TargetElement = targetElement ; + this.Mode = FCK_EDITMODE_WYSIWYG ; + + if ( FCK.IECleanup ) + FCK.IECleanup.AddItem( this, FCKEditingArea_Cleanup ) ; +} + + +/** + * @param {String} html The complete HTML for the page, including DOCTYPE and the tag. + */ +FCKEditingArea.prototype.Start = function( html, secondCall ) +{ + var eTargetElement = this.TargetElement ; + var oTargetDocument = FCKTools.GetElementDocument( eTargetElement ) ; + + // Remove all child nodes from the target. + while( eTargetElement.firstChild ) + eTargetElement.removeChild( eTargetElement.firstChild ) ; + + if ( this.Mode == FCK_EDITMODE_WYSIWYG ) + { + // For FF, document.domain must be set only when different, otherwhise + // we'll strangely have "Permission denied" issues. + if ( FCK_IS_CUSTOM_DOMAIN ) + html = '' + html ; + + // IE has a bug with the tag... it must have a closer, + // otherwise the all successive tags will be set as children nodes of the . + if ( FCKBrowserInfo.IsIE ) + html = html.replace( /(]*?)\s*\/?>(?!\s*<\/base>)/gi, '$1>' ) ; + else if ( !secondCall ) + { + // Gecko moves some tags out of the body to the head, so we must use + // innerHTML to set the body contents (SF BUG 1526154). + + // Extract the BODY contents from the html. + var oMatchBefore = html.match( FCKRegexLib.BeforeBody ) ; + var oMatchAfter = html.match( FCKRegexLib.AfterBody ) ; + + if ( oMatchBefore && oMatchAfter ) + { + var sBody = html.substr( oMatchBefore[1].length, + html.length - oMatchBefore[1].length - oMatchAfter[1].length ) ; // This is the BODY tag contents. + + html = + oMatchBefore[1] + // This is the HTML until the tag, inclusive. + ' ' + + oMatchAfter[1] ; // This is the HTML from the tag, inclusive. + + // If nothing in the body, place a BOGUS tag so the cursor will appear. + if ( FCKBrowserInfo.IsGecko && ( sBody.length == 0 || FCKRegexLib.EmptyParagraph.test( sBody ) ) ) + sBody = '
      ' ; + + this._BodyHTML = sBody ; + + } + else + this._BodyHTML = html ; // Invalid HTML input. + } + + // Create the editing area IFRAME. + var oIFrame = this.IFrame = oTargetDocument.createElement( 'iframe' ) ; + + // IE: Avoid JavaScript errors thrown by the editing are source (like tags events). + // See #1055. + var sOverrideError = '' ; + + oIFrame.frameBorder = 0 ; + oIFrame.style.width = oIFrame.style.height = '100%' ; + + if ( FCK_IS_CUSTOM_DOMAIN && FCKBrowserInfo.IsIE ) + { + window._FCKHtmlToLoad = html.replace( //i, '' + sOverrideError ) ; + oIFrame.src = 'javascript:void( (function(){' + + 'document.open() ;' + + 'document.domain="' + document.domain + '" ;' + + 'document.write( window.parent._FCKHtmlToLoad );' + + 'document.close() ;' + + 'window.parent._FCKHtmlToLoad = null ;' + + '})() )' ; + } + else if ( !FCKBrowserInfo.IsGecko ) + { + // Firefox will render the tables inside the body in Quirks mode if the + // source of the iframe is set to javascript. see #515 + oIFrame.src = 'javascript:void(0)' ; + } + + // Append the new IFRAME to the target. For IE, it must be done after + // setting the "src", to avoid the "secure/unsecure" message under HTTPS. + eTargetElement.appendChild( oIFrame ) ; + + // Get the window and document objects used to interact with the newly created IFRAME. + this.Window = oIFrame.contentWindow ; + + // IE: Avoid JavaScript errors thrown by the editing are source (like tags events). + // TODO: This error handler is not being fired. + // this.Window.onerror = function() { alert( 'Error!' ) ; return true ; } + + if ( !FCK_IS_CUSTOM_DOMAIN || !FCKBrowserInfo.IsIE ) + { + var oDoc = this.Window.document ; + + oDoc.open() ; + oDoc.write( html.replace( //i, '' + sOverrideError ) ) ; + oDoc.close() ; + } + + if ( FCKBrowserInfo.IsAIR ) + FCKAdobeAIR.EditingArea_Start( oDoc, html ) ; + + // Firefox 1.0.x is buggy... ohh yes... so let's do it two times and it + // will magically work. + if ( FCKBrowserInfo.IsGecko10 && !secondCall ) + { + this.Start( html, true ) ; + return ; + } + + if ( oIFrame.readyState && oIFrame.readyState != 'completed' ) + { + var editArea = this ; + + // Using a IE alternative for DOMContentLoaded, similar to the + // solution proposed at http://javascript.nwbox.com/IEContentLoaded/ + setTimeout( function() + { + try + { + editArea.Window.document.documentElement.doScroll("left") ; + } + catch(e) + { + setTimeout( arguments.callee, 0 ) ; + return ; + } + editArea.Window._FCKEditingArea = editArea ; + FCKEditingArea_CompleteStart.call( editArea.Window ) ; + }, 0 ) ; + } + else + { + this.Window._FCKEditingArea = this ; + + // FF 1.0.x is buggy... we must wait a lot to enable editing because + // sometimes the content simply disappears, for example when pasting + // "bla1!!bla2" in the source and then switching + // back to design. + if ( FCKBrowserInfo.IsGecko10 ) + this.Window.setTimeout( FCKEditingArea_CompleteStart, 500 ) ; + else + FCKEditingArea_CompleteStart.call( this.Window ) ; + } + } + else + { + var eTextarea = this.Textarea = oTargetDocument.createElement( 'textarea' ) ; + eTextarea.className = 'SourceField' ; + eTextarea.dir = 'ltr' ; + FCKDomTools.SetElementStyles( eTextarea, + { + width : '100%', + height : '100%', + border : 'none', + resize : 'none', + outline : 'none' + } ) ; + eTargetElement.appendChild( eTextarea ) ; + + eTextarea.value = html ; + + // Fire the "OnLoad" event. + FCKTools.RunFunction( this.OnLoad ) ; + } +} + +// "this" here is FCKEditingArea.Window +function FCKEditingArea_CompleteStart() +{ + // On Firefox, the DOM takes a little to become available. So we must wait for it in a loop. + if ( !this.document.body ) + { + this.setTimeout( FCKEditingArea_CompleteStart, 50 ) ; + return ; + } + + var oEditorArea = this._FCKEditingArea ; + + // Save this reference to be re-used later. + oEditorArea.Document = oEditorArea.Window.document ; + + oEditorArea.MakeEditable() ; + + // Fire the "OnLoad" event. + FCKTools.RunFunction( oEditorArea.OnLoad ) ; +} + +FCKEditingArea.prototype.MakeEditable = function() +{ + var oDoc = this.Document ; + + if ( FCKBrowserInfo.IsIE ) + { + // Kludge for #141 and #523 + oDoc.body.disabled = true ; + oDoc.body.contentEditable = true ; + oDoc.body.removeAttribute( "disabled" ) ; + + /* The following commands don't throw errors, but have no effect. + oDoc.execCommand( 'AutoDetect', false, false ) ; + oDoc.execCommand( 'KeepSelection', false, true ) ; + */ + } + else + { + try + { + // Disable Firefox 2 Spell Checker. + oDoc.body.spellcheck = ( this.FFSpellChecker !== false ) ; + + if ( this._BodyHTML ) + { + oDoc.body.innerHTML = this._BodyHTML ; + oDoc.body.offsetLeft ; // Don't remove, this is a hack to fix Opera 9.50, see #2264. + this._BodyHTML = null ; + } + + oDoc.designMode = 'on' ; + + // Tell Gecko (Firefox 1.5+) to enable or not live resizing of objects (by Alfonso Martinez) + oDoc.execCommand( 'enableObjectResizing', false, !FCKConfig.DisableObjectResizing ) ; + + // Disable the standard table editing features of Firefox. + oDoc.execCommand( 'enableInlineTableEditing', false, !FCKConfig.DisableFFTableHandles ) ; + } + catch (e) + { + // In Firefox if the iframe is initially hidden it can't be set to designMode and it raises an exception + // So we set up a DOM Mutation event Listener on the HTML, as it will raise several events when the document is visible again + FCKTools.AddEventListener( this.Window.frameElement, 'DOMAttrModified', FCKEditingArea_Document_AttributeNodeModified ) ; + } + + } +} + +// This function processes the notifications of the DOM Mutation event on the document +// We use it to know that the document will be ready to be editable again (or we hope so) +function FCKEditingArea_Document_AttributeNodeModified( evt ) +{ + var editingArea = evt.currentTarget.contentWindow._FCKEditingArea ; + + // We want to run our function after the events no longer fire, so we can know that it's a stable situation + if ( editingArea._timer ) + window.clearTimeout( editingArea._timer ) ; + + editingArea._timer = FCKTools.SetTimeout( FCKEditingArea_MakeEditableByMutation, 1000, editingArea ) ; +} + +// This function ideally should be called after the document is visible, it does clean up of the +// mutation tracking and tries again to make the area editable. +function FCKEditingArea_MakeEditableByMutation() +{ + // Clean up + delete this._timer ; + // Now we don't want to keep on getting this event + FCKTools.RemoveEventListener( this.Window.frameElement, 'DOMAttrModified', FCKEditingArea_Document_AttributeNodeModified ) ; + // Let's try now to set the editing area editable + // If it fails it will set up the Mutation Listener again automatically + this.MakeEditable() ; +} + +FCKEditingArea.prototype.Focus = function() +{ + try + { + if ( this.Mode == FCK_EDITMODE_WYSIWYG ) + { + if ( FCKBrowserInfo.IsIE ) + this._FocusIE() ; + else + this.Window.focus() ; + } + else + { + var oDoc = FCKTools.GetElementDocument( this.Textarea ) ; + if ( (!oDoc.hasFocus || oDoc.hasFocus() ) && oDoc.activeElement == this.Textarea ) + return ; + + this.Textarea.focus() ; + } + } + catch(e) {} +} + +FCKEditingArea.prototype._FocusIE = function() +{ + // In IE it can happen that the document is in theory focused but the + // active element is outside of it. + this.Document.body.setActive() ; + + this.Window.focus() ; + + // Kludge for #141... yet more code to workaround IE bugs + var range = this.Document.selection.createRange() ; + + var parentNode = range.parentElement() ; + var parentTag = parentNode.nodeName.toLowerCase() ; + + // Only apply the fix when in a block, and the block is empty. + if ( parentNode.childNodes.length > 0 || + !( FCKListsLib.BlockElements[parentTag] || + FCKListsLib.NonEmptyBlockElements[parentTag] ) ) + { + return ; + } + + // Force the selection to happen, in this way we guarantee the focus will + // be there. + range = new FCKDomRange( this.Window ) ; + range.MoveToElementEditStart( parentNode ) ; + range.Select() ; +} + +function FCKEditingArea_Cleanup() +{ + if ( this.Document ) + this.Document.body.innerHTML = "" ; + this.TargetElement = null ; + this.IFrame = null ; + this.Document = null ; + this.Textarea = null ; + + if ( this.Window ) + { + this.Window._FCKEditingArea = null ; + this.Window = null ; + } +} diff -r 3791b2e8e471 -r f5c322ae1c7b wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckelementpath.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckelementpath.js Mon Aug 11 13:54:49 2008 +0900 @@ -0,0 +1,89 @@ +/* + * FCKeditor - The text editor for Internet - http://www.fckeditor.net + * Copyright (C) 2003-2008 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 == + * + * Manages the DOM ascensors element list of a specific DOM node + * (limited to body, inclusive). + */ + +var FCKElementPath = function( lastNode ) +{ + var eBlock = null ; + var eBlockLimit = null ; + + var aElements = new Array() ; + + var e = lastNode ; + while ( e ) + { + if ( e.nodeType == 1 ) + { + if ( !this.LastElement ) + this.LastElement = e ; + + var sElementName = e.nodeName.toLowerCase() ; + if ( FCKBrowserInfo.IsIE && e.scopeName != 'HTML' ) + sElementName = e.scopeName.toLowerCase() + ':' + sElementName ; + + if ( !eBlockLimit ) + { + if ( !eBlock && FCKListsLib.PathBlockElements[ sElementName ] != null ) + eBlock = e ; + + if ( FCKListsLib.PathBlockLimitElements[ sElementName ] != null ) + { + // DIV is considered the Block, if no block is available (#525) + // and if it doesn't contain other blocks. + if ( !eBlock && sElementName == 'div' && !FCKElementPath._CheckHasBlock( e ) ) + eBlock = e ; + else + eBlockLimit = e ; + } + } + + aElements.push( e ) ; + + if ( sElementName == 'body' ) + break ; + } + e = e.parentNode ; + } + + this.Block = eBlock ; + this.BlockLimit = eBlockLimit ; + this.Elements = aElements ; +} + +/** + * Check if an element contains any block element. + */ +FCKElementPath._CheckHasBlock = function( element ) +{ + var childNodes = element.childNodes ; + + for ( var i = 0, count = childNodes.length ; i < count ; i++ ) + { + var child = childNodes[i] ; + + if ( child.nodeType == 1 && FCKListsLib.BlockElements[ child.nodeName.toLowerCase() ] ) + return true ; + } + + return false ; +} diff -r 3791b2e8e471 -r f5c322ae1c7b wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckenterkey.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckenterkey.js Mon Aug 11 13:54:49 2008 +0900 @@ -0,0 +1,688 @@ +/* + * FCKeditor - The text editor for Internet - http://www.fckeditor.net + * Copyright (C) 2003-2008 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 == + * + * Controls the [Enter] keystroke behavior in a document. + */ + +/* + * Constructor. + * @targetDocument : the target document. + * @enterMode : the behavior for the keystroke. + * May be "p", "div", "br". Default is "p". + * @shiftEnterMode : the behavior for the + keystroke. + * May be "p", "div", "br". Defaults to "br". + */ +var FCKEnterKey = function( targetWindow, enterMode, shiftEnterMode, tabSpaces ) +{ + this.Window = targetWindow ; + this.EnterMode = enterMode || 'p' ; + this.ShiftEnterMode = shiftEnterMode || 'br' ; + + // Setup the Keystroke Handler. + var oKeystrokeHandler = new FCKKeystrokeHandler( false ) ; + oKeystrokeHandler._EnterKey = this ; + oKeystrokeHandler.OnKeystroke = FCKEnterKey_OnKeystroke ; + + oKeystrokeHandler.SetKeystrokes( [ + [ 13 , 'Enter' ], + [ SHIFT + 13, 'ShiftEnter' ], + [ 8 , 'Backspace' ], + [ CTRL + 8 , 'CtrlBackspace' ], + [ 46 , 'Delete' ] + ] ) ; + + this.TabText = '' ; + + // Safari by default inserts 4 spaces on TAB, while others make the editor + // loose focus. So, we need to handle it here to not include those spaces. + if ( tabSpaces > 0 || FCKBrowserInfo.IsSafari ) + { + while ( tabSpaces-- ) + this.TabText += '\xa0' ; + + oKeystrokeHandler.SetKeystrokes( [ 9, 'Tab' ] ); + } + + oKeystrokeHandler.AttachToElement( targetWindow.document ) ; +} + + +function FCKEnterKey_OnKeystroke( keyCombination, keystrokeValue ) +{ + var oEnterKey = this._EnterKey ; + + try + { + switch ( keystrokeValue ) + { + case 'Enter' : + return oEnterKey.DoEnter() ; + break ; + case 'ShiftEnter' : + return oEnterKey.DoShiftEnter() ; + break ; + case 'Backspace' : + return oEnterKey.DoBackspace() ; + break ; + case 'Delete' : + return oEnterKey.DoDelete() ; + break ; + case 'Tab' : + return oEnterKey.DoTab() ; + break ; + case 'CtrlBackspace' : + return oEnterKey.DoCtrlBackspace() ; + break ; + } + } + catch (e) + { + // If for any reason we are not able to handle it, go + // ahead with the browser default behavior. + } + + return false ; +} + +/* + * Executes the key behavior. + */ +FCKEnterKey.prototype.DoEnter = function( mode, hasShift ) +{ + // Save an undo snapshot before doing anything + FCKUndo.SaveUndoStep() ; + + this._HasShift = ( hasShift === true ) ; + + var parentElement = FCKSelection.GetParentElement() ; + var parentPath = new FCKElementPath( parentElement ) ; + var sMode = mode || this.EnterMode ; + + if ( sMode == 'br' || parentPath.Block && parentPath.Block.tagName.toLowerCase() == 'pre' ) + return this._ExecuteEnterBr() ; + else + return this._ExecuteEnterBlock( sMode ) ; +} + +/* + * Executes the + key behavior. + */ +FCKEnterKey.prototype.DoShiftEnter = function() +{ + return this.DoEnter( this.ShiftEnterMode, true ) ; +} + +/* + * Executes the key behavior. + */ +FCKEnterKey.prototype.DoBackspace = function() +{ + var bCustom = false ; + + // Get the current selection. + var oRange = new FCKDomRange( this.Window ) ; + oRange.MoveToSelection() ; + + // Kludge for #247 + if ( FCKBrowserInfo.IsIE && this._CheckIsAllContentsIncluded( oRange, this.Window.document.body ) ) + { + this._FixIESelectAllBug( oRange ) ; + return true ; + } + + var isCollapsed = oRange.CheckIsCollapsed() ; + + if ( !isCollapsed ) + { + // Bug #327, Backspace with an img selection would activate the default action in IE. + // Let's override that with our logic here. + if ( FCKBrowserInfo.IsIE && this.Window.document.selection.type.toLowerCase() == "control" ) + { + var controls = this.Window.document.selection.createRange() ; + for ( var i = controls.length - 1 ; i >= 0 ; i-- ) + { + var el = controls.item( i ) ; + el.parentNode.removeChild( el ) ; + } + return true ; + } + + return false ; + } + + // On IE, it is better for us handle the deletion if the caret is preceeded + // by a
      (#1383). + if ( FCKBrowserInfo.IsIE ) + { + var previousElement = FCKDomTools.GetPreviousSourceElement( oRange.StartNode, true ) ; + + if ( previousElement && previousElement.nodeName.toLowerCase() == 'br' ) + { + // Create a range that starts after the
      and ends at the + // current range position. + var testRange = oRange.Clone() ; + testRange.SetStart( previousElement, 4 ) ; + + // If that range is empty, we can proceed cleaning that
      manually. + if ( testRange.CheckIsEmpty() ) + { + previousElement.parentNode.removeChild( previousElement ) ; + return true ; + } + } + } + + var oStartBlock = oRange.StartBlock ; + var oEndBlock = oRange.EndBlock ; + + // The selection boundaries must be in the same "block limit" element + if ( oRange.StartBlockLimit == oRange.EndBlockLimit && oStartBlock && oEndBlock ) + { + if ( !isCollapsed ) + { + var bEndOfBlock = oRange.CheckEndOfBlock() ; + + oRange.DeleteContents() ; + + if ( oStartBlock != oEndBlock ) + { + oRange.SetStart(oEndBlock,1) ; + oRange.SetEnd(oEndBlock,1) ; + +// if ( bEndOfBlock ) +// oEndBlock.parentNode.removeChild( oEndBlock ) ; + } + + oRange.Select() ; + + bCustom = ( oStartBlock == oEndBlock ) ; + } + + if ( oRange.CheckStartOfBlock() ) + { + var oCurrentBlock = oRange.StartBlock ; + + var ePrevious = FCKDomTools.GetPreviousSourceElement( oCurrentBlock, true, [ 'BODY', oRange.StartBlockLimit.nodeName ], ['UL','OL'] ) ; + + bCustom = this._ExecuteBackspace( oRange, ePrevious, oCurrentBlock ) ; + } + else if ( FCKBrowserInfo.IsGeckoLike ) + { + // Firefox and Opera (#1095) loose the selection when executing + // CheckStartOfBlock, so we must reselect. + oRange.Select() ; + } + } + + oRange.Release() ; + return bCustom ; +} + +FCKEnterKey.prototype.DoCtrlBackspace = function() +{ + FCKUndo.SaveUndoStep() ; + var oRange = new FCKDomRange( this.Window ) ; + oRange.MoveToSelection() ; + if ( FCKBrowserInfo.IsIE && this._CheckIsAllContentsIncluded( oRange, this.Window.document.body ) ) + { + this._FixIESelectAllBug( oRange ) ; + return true ; + } + return false ; +} + +FCKEnterKey.prototype._ExecuteBackspace = function( range, previous, currentBlock ) +{ + var bCustom = false ; + + // We could be in a nested LI. + if ( !previous && currentBlock && currentBlock.nodeName.IEquals( 'LI' ) && currentBlock.parentNode.parentNode.nodeName.IEquals( 'LI' ) ) + { + this._OutdentWithSelection( currentBlock, range ) ; + return true ; + } + + if ( previous && previous.nodeName.IEquals( 'LI' ) ) + { + var oNestedList = FCKDomTools.GetLastChild( previous, ['UL','OL'] ) ; + + while ( oNestedList ) + { + previous = FCKDomTools.GetLastChild( oNestedList, 'LI' ) ; + oNestedList = FCKDomTools.GetLastChild( previous, ['UL','OL'] ) ; + } + } + + if ( previous && currentBlock ) + { + // If we are in a LI, and the previous block is not an LI, we must outdent it. + if ( currentBlock.nodeName.IEquals( 'LI' ) && !previous.nodeName.IEquals( 'LI' ) ) + { + this._OutdentWithSelection( currentBlock, range ) ; + return true ; + } + + // Take a reference to the parent for post processing cleanup. + var oCurrentParent = currentBlock.parentNode ; + + var sPreviousName = previous.nodeName.toLowerCase() ; + if ( FCKListsLib.EmptyElements[ sPreviousName ] != null || sPreviousName == 'table' ) + { + FCKDomTools.RemoveNode( previous ) ; + bCustom = true ; + } + else + { + // Remove the current block. + FCKDomTools.RemoveNode( currentBlock ) ; + + // Remove any empty tag left by the block removal. + while ( oCurrentParent.innerHTML.Trim().length == 0 ) + { + var oParent = oCurrentParent.parentNode ; + oParent.removeChild( oCurrentParent ) ; + oCurrentParent = oParent ; + } + + // Cleanup the previous and the current elements. + FCKDomTools.LTrimNode( currentBlock ) ; + FCKDomTools.RTrimNode( previous ) ; + + // Append a space to the previous. + // Maybe it is not always desirable... + // previous.appendChild( this.Window.document.createTextNode( ' ' ) ) ; + + // Set the range to the end of the previous element and bookmark it. + range.SetStart( previous, 2, true ) ; + range.Collapse( true ) ; + var oBookmark = range.CreateBookmark( true ) ; + + // Move the contents of the block to the previous element and delete it. + // But for some block types (e.g. table), moving the children to the previous block makes no sense. + // So a check is needed. (See #1081) + if ( ! currentBlock.tagName.IEquals( [ 'TABLE' ] ) ) + FCKDomTools.MoveChildren( currentBlock, previous ) ; + + // Place the selection at the bookmark. + range.SelectBookmark( oBookmark ) ; + + bCustom = true ; + } + } + + return bCustom ; +} + +/* + * Executes the key behavior. + */ +FCKEnterKey.prototype.DoDelete = function() +{ + // Save an undo snapshot before doing anything + // This is to conform with the behavior seen in MS Word + FCKUndo.SaveUndoStep() ; + + // The has the same effect as the , so we have the same + // results if we just move to the next block and apply the same logic. + + var bCustom = false ; + + // Get the current selection. + var oRange = new FCKDomRange( this.Window ) ; + oRange.MoveToSelection() ; + + // Kludge for #247 + if ( FCKBrowserInfo.IsIE && this._CheckIsAllContentsIncluded( oRange, this.Window.document.body ) ) + { + this._FixIESelectAllBug( oRange ) ; + return true ; + } + + // There is just one special case for collapsed selections at the end of a block. + if ( oRange.CheckIsCollapsed() && oRange.CheckEndOfBlock( FCKBrowserInfo.IsGeckoLike ) ) + { + var oCurrentBlock = oRange.StartBlock ; + var eCurrentCell = FCKTools.GetElementAscensor( oCurrentBlock, 'td' ); + + var eNext = FCKDomTools.GetNextSourceElement( oCurrentBlock, true, [ oRange.StartBlockLimit.nodeName ], + ['UL','OL','TR'], true ) ; + + // Bug #1323 : if we're in a table cell, and the next node belongs to a different cell, then don't + // delete anything. + if ( eCurrentCell ) + { + var eNextCell = FCKTools.GetElementAscensor( eNext, 'td' ); + if ( eNextCell != eCurrentCell ) + return true ; + } + + bCustom = this._ExecuteBackspace( oRange, oCurrentBlock, eNext ) ; + } + + oRange.Release() ; + return bCustom ; +} + +/* + * Executes the key behavior. + */ +FCKEnterKey.prototype.DoTab = function() +{ + var oRange = new FCKDomRange( this.Window ); + oRange.MoveToSelection() ; + + // If the user pressed inside a table, we should give him the default behavior ( moving between cells ) + // instead of giving him more non-breaking spaces. (Bug #973) + var node = oRange._Range.startContainer ; + while ( node ) + { + if ( node.nodeType == 1 ) + { + var tagName = node.tagName.toLowerCase() ; + if ( tagName == "tr" || tagName == "td" || tagName == "th" || tagName == "tbody" || tagName == "table" ) + return false ; + else + break ; + } + node = node.parentNode ; + } + + if ( this.TabText ) + { + oRange.DeleteContents() ; + oRange.InsertNode( this.Window.document.createTextNode( this.TabText ) ) ; + oRange.Collapse( false ) ; + oRange.Select() ; + } + return true ; +} + +FCKEnterKey.prototype._ExecuteEnterBlock = function( blockTag, range ) +{ + // Get the current selection. + var oRange = range || new FCKDomRange( this.Window ) ; + + var oSplitInfo = oRange.SplitBlock( blockTag ) ; + + if ( oSplitInfo ) + { + // Get the current blocks. + var ePreviousBlock = oSplitInfo.PreviousBlock ; + var eNextBlock = oSplitInfo.NextBlock ; + + var bIsStartOfBlock = oSplitInfo.WasStartOfBlock ; + var bIsEndOfBlock = oSplitInfo.WasEndOfBlock ; + + // If there is one block under a list item, modify the split so that the list item gets split as well. (Bug #1647) + if ( eNextBlock ) + { + if ( eNextBlock.parentNode.nodeName.IEquals( 'li' ) ) + { + FCKDomTools.BreakParent( eNextBlock, eNextBlock.parentNode ) ; + FCKDomTools.MoveNode( eNextBlock, eNextBlock.nextSibling, true ) ; + } + } + else if ( ePreviousBlock && ePreviousBlock.parentNode.nodeName.IEquals( 'li' ) ) + { + FCKDomTools.BreakParent( ePreviousBlock, ePreviousBlock.parentNode ) ; + oRange.MoveToElementEditStart( ePreviousBlock.nextSibling ); + FCKDomTools.MoveNode( ePreviousBlock, ePreviousBlock.previousSibling ) ; + } + + // If we have both the previous and next blocks, it means that the + // boundaries were on separated blocks, or none of them where on the + // block limits (start/end). + if ( !bIsStartOfBlock && !bIsEndOfBlock ) + { + // If the next block is an
    4. with another list tree as the first child + // We'll need to append a placeholder or the list item wouldn't be editable. (Bug #1420) + if ( eNextBlock.nodeName.IEquals( 'li' ) && eNextBlock.firstChild + && eNextBlock.firstChild.nodeName.IEquals( ['ul', 'ol'] ) ) + eNextBlock.insertBefore( FCKTools.GetElementDocument( eNextBlock ).createTextNode( '\xa0' ), eNextBlock.firstChild ) ; + // Move the selection to the end block. + if ( eNextBlock ) + oRange.MoveToElementEditStart( eNextBlock ) ; + } + else + { + if ( bIsStartOfBlock && bIsEndOfBlock && ePreviousBlock.tagName.toUpperCase() == 'LI' ) + { + oRange.MoveToElementStart( ePreviousBlock ) ; + this._OutdentWithSelection( ePreviousBlock, oRange ) ; + oRange.Release() ; + return true ; + } + + var eNewBlock ; + + if ( ePreviousBlock ) + { + var sPreviousBlockTag = ePreviousBlock.tagName.toUpperCase() ; + + // If is a header tag, or we are in a Shift+Enter (#77), + // create a new block element (later in the code). + if ( !this._HasShift && !(/^H[1-6]$/).test( sPreviousBlockTag ) ) + { + // Otherwise, duplicate the previous block. + eNewBlock = FCKDomTools.CloneElement( ePreviousBlock ) ; + } + } + else if ( eNextBlock ) + eNewBlock = FCKDomTools.CloneElement( eNextBlock ) ; + + if ( !eNewBlock ) + eNewBlock = this.Window.document.createElement( blockTag ) ; + + // Recreate the inline elements tree, which was available + // before the hitting enter, so the same styles will be + // available in the new block. + var elementPath = oSplitInfo.ElementPath ; + if ( elementPath ) + { + for ( var i = 0, len = elementPath.Elements.length ; i < len ; i++ ) + { + var element = elementPath.Elements[i] ; + + if ( element == elementPath.Block || element == elementPath.BlockLimit ) + break ; + + if ( FCKListsLib.InlineChildReqElements[ element.nodeName.toLowerCase() ] ) + { + element = FCKDomTools.CloneElement( element ) ; + FCKDomTools.MoveChildren( eNewBlock, element ) ; + eNewBlock.appendChild( element ) ; + } + } + } + + if ( FCKBrowserInfo.IsGeckoLike ) + FCKTools.AppendBogusBr( eNewBlock ) ; + + oRange.InsertNode( eNewBlock ) ; + + // This is tricky, but to make the new block visible correctly + // we must select it. + if ( FCKBrowserInfo.IsIE ) + { + // Move the selection to the new block. + oRange.MoveToElementEditStart( eNewBlock ) ; + oRange.Select() ; + } + + // Move the selection to the new block. + oRange.MoveToElementEditStart( bIsStartOfBlock && !bIsEndOfBlock ? eNextBlock : eNewBlock ) ; + } + + if ( FCKBrowserInfo.IsGeckoLike ) + FCKDomTools.ScrollIntoView( eNextBlock || eNewBlock, false ) ; + + oRange.Select() ; + } + + // Release the resources used by the range. + oRange.Release() ; + + return true ; +} + +FCKEnterKey.prototype._ExecuteEnterBr = function( blockTag ) +{ + // Get the current selection. + var oRange = new FCKDomRange( this.Window ) ; + oRange.MoveToSelection() ; + + // The selection boundaries must be in the same "block limit" element. + if ( oRange.StartBlockLimit == oRange.EndBlockLimit ) + { + oRange.DeleteContents() ; + + // Get the new selection (it is collapsed at this point). + oRange.MoveToSelection() ; + + var bIsStartOfBlock = oRange.CheckStartOfBlock() ; + var bIsEndOfBlock = oRange.CheckEndOfBlock() ; + + var sStartBlockTag = oRange.StartBlock ? oRange.StartBlock.tagName.toUpperCase() : '' ; + + var bHasShift = this._HasShift ; + var bIsPre = false ; + + if ( !bHasShift && sStartBlockTag == 'LI' ) + return this._ExecuteEnterBlock( null, oRange ) ; + + // If we are at the end of a header block. + if ( !bHasShift && bIsEndOfBlock && (/^H[1-6]$/).test( sStartBlockTag ) ) + { + // Insert a BR after the current paragraph. + FCKDomTools.InsertAfterNode( oRange.StartBlock, this.Window.document.createElement( 'br' ) ) ; + + // The space is required by Gecko only to make the cursor blink. + if ( FCKBrowserInfo.IsGecko ) + FCKDomTools.InsertAfterNode( oRange.StartBlock, this.Window.document.createTextNode( '' ) ) ; + + // IE and Gecko have different behaviors regarding the position. + oRange.SetStart( oRange.StartBlock.nextSibling, FCKBrowserInfo.IsIE ? 3 : 1 ) ; + } + else + { + var eLineBreak ; + bIsPre = sStartBlockTag.IEquals( 'pre' ) ; + if ( bIsPre ) + eLineBreak = this.Window.document.createTextNode( FCKBrowserInfo.IsIE ? '\r' : '\n' ) ; + else + eLineBreak = this.Window.document.createElement( 'br' ) ; + + oRange.InsertNode( eLineBreak ) ; + + // The space is required by Gecko only to make the cursor blink. + if ( FCKBrowserInfo.IsGecko ) + FCKDomTools.InsertAfterNode( eLineBreak, this.Window.document.createTextNode( '' ) ) ; + + // If we are at the end of a block, we must be sure the bogus node is available in that block. + if ( bIsEndOfBlock && FCKBrowserInfo.IsGeckoLike ) + FCKTools.AppendBogusBr( eLineBreak.parentNode ) ; + + if ( FCKBrowserInfo.IsIE ) + oRange.SetStart( eLineBreak, 4 ) ; + else + oRange.SetStart( eLineBreak.nextSibling, 1 ) ; + + if ( ! FCKBrowserInfo.IsIE ) + { + var dummy = null ; + if ( FCKBrowserInfo.IsOpera ) + dummy = this.Window.document.createElement( 'span' ) ; + else + dummy = this.Window.document.createElement( 'br' ) ; + + eLineBreak.parentNode.insertBefore( dummy, eLineBreak.nextSibling ) ; + + FCKDomTools.ScrollIntoView( dummy, false ) ; + + dummy.parentNode.removeChild( dummy ) ; + } + } + + // This collapse guarantees the cursor will be blinking. + oRange.Collapse( true ) ; + + oRange.Select( bIsPre ) ; + } + + // Release the resources used by the range. + oRange.Release() ; + + return true ; +} + +// Outdents a LI, maintaining the selection defined on a range. +FCKEnterKey.prototype._OutdentWithSelection = function( li, range ) +{ + var oBookmark = range.CreateBookmark() ; + + FCKListHandler.OutdentListItem( li ) ; + + range.MoveToBookmark( oBookmark ) ; + range.Select() ; +} + +// Is all the contents under a node included by a range? +FCKEnterKey.prototype._CheckIsAllContentsIncluded = function( range, node ) +{ + var startOk = false ; + var endOk = false ; + + /* + FCKDebug.Output( 'sc='+range.StartContainer.nodeName+ + ',so='+range._Range.startOffset+ + ',ec='+range.EndContainer.nodeName+ + ',eo='+range._Range.endOffset ) ; + */ + if ( range.StartContainer == node || range.StartContainer == node.firstChild ) + startOk = ( range._Range.startOffset == 0 ) ; + + if ( range.EndContainer == node || range.EndContainer == node.lastChild ) + { + var nodeLength = range.EndContainer.nodeType == 3 ? range.EndContainer.length : range.EndContainer.childNodes.length ; + endOk = ( range._Range.endOffset == nodeLength ) ; + } + + return startOk && endOk ; +} + +// Kludge for #247 +FCKEnterKey.prototype._FixIESelectAllBug = function( range ) +{ + var doc = this.Window.document ; + doc.body.innerHTML = '' ; + var editBlock ; + if ( FCKConfig.EnterMode.IEquals( ['div', 'p'] ) ) + { + editBlock = doc.createElement( FCKConfig.EnterMode ) ; + doc.body.appendChild( editBlock ) ; + } + else + editBlock = doc.body ; + + range.MoveToNodeContents( editBlock ) ; + range.Collapse( true ) ; + range.Select() ; + range.Release() ; +} diff -r 3791b2e8e471 -r f5c322ae1c7b wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckevents.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckevents.js Mon Aug 11 13:54:49 2008 +0900 @@ -0,0 +1,71 @@ +/* + * FCKeditor - The text editor for Internet - http://www.fckeditor.net + * Copyright (C) 2003-2008 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 == + * + * FCKEvents Class: used to handle events is a advanced way. + */ + +var FCKEvents = function( eventsOwner ) +{ + this.Owner = eventsOwner ; + this._RegisteredEvents = new Object() ; +} + +FCKEvents.prototype.AttachEvent = function( eventName, functionPointer ) +{ + var aTargets ; + + if ( !( aTargets = this._RegisteredEvents[ eventName ] ) ) + this._RegisteredEvents[ eventName ] = [ functionPointer ] ; + else + { + // Check that the event handler isn't already registered with the same listener + // It doesn't detect function pointers belonging to an object (at least in Gecko) + if ( aTargets.IndexOf( functionPointer ) == -1 ) + aTargets.push( functionPointer ) ; + } +} + +FCKEvents.prototype.FireEvent = function( eventName, params ) +{ + var bReturnValue = true ; + + var oCalls = this._RegisteredEvents[ eventName ] ; + + if ( oCalls ) + { + for ( var i = 0 ; i < oCalls.length ; i++ ) + { + try + { + bReturnValue = ( oCalls[ i ]( this.Owner, params ) && bReturnValue ) ; + } + catch(e) + { + // Ignore the following error. It may happen if pointing to a + // script not anymore available (#934): + // -2146823277 = Can't execute code from a freed script + if ( e.number != -2146823277 ) + throw e ; + } + } + } + + return bReturnValue ; +} diff -r 3791b2e8e471 -r f5c322ae1c7b wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckhtmliterator.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckhtmliterator.js Mon Aug 11 13:54:49 2008 +0900 @@ -0,0 +1,142 @@ +/* + * FCKeditor - The text editor for Internet - http://www.fckeditor.net + * Copyright (C) 2003-2008 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 == + * + * This class can be used to interate through nodes inside a range. + * + * During interation, the provided range can become invalid, due to document + * mutations, so CreateBookmark() used to restore it after processing, if + * needed. + */ + +var FCKHtmlIterator = function( source ) +{ + this._sourceHtml = source ; +} +FCKHtmlIterator.prototype = +{ + Next : function() + { + var sourceHtml = this._sourceHtml ; + if ( sourceHtml == null ) + return null ; + + var match = FCKRegexLib.HtmlTag.exec( sourceHtml ) ; + var isTag = false ; + var value = "" ; + if ( match ) + { + if ( match.index > 0 ) + { + value = sourceHtml.substr( 0, match.index ) ; + this._sourceHtml = sourceHtml.substr( match.index ) ; + } + else + { + isTag = true ; + value = match[0] ; + this._sourceHtml = sourceHtml.substr( match[0].length ) ; + } + } + else + { + value = sourceHtml ; + this._sourceHtml = null ; + } + return { 'isTag' : isTag, 'value' : value } ; + }, + + Each : function( func ) + { + var chunk ; + while ( ( chunk = this.Next() ) ) + func( chunk.isTag, chunk.value ) ; + } +} ; +/* + * FCKeditor - The text editor for Internet - http://www.fckeditor.net + * Copyright (C) 2003-2008 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 == + * + * This class can be used to interate through nodes inside a range. + * + * During interation, the provided range can become invalid, due to document + * mutations, so CreateBookmark() used to restore it after processing, if + * needed. + */ + +var FCKHtmlIterator = function( source ) +{ + this._sourceHtml = source ; +} +FCKHtmlIterator.prototype = +{ + Next : function() + { + var sourceHtml = this._sourceHtml ; + if ( sourceHtml == null ) + return null ; + + var match = FCKRegexLib.HtmlTag.exec( sourceHtml ) ; + var isTag = false ; + var value = "" ; + if ( match ) + { + if ( match.index > 0 ) + { + value = sourceHtml.substr( 0, match.index ) ; + this._sourceHtml = sourceHtml.substr( match.index ) ; + } + else + { + isTag = true ; + value = match[0] ; + this._sourceHtml = sourceHtml.substr( match[0].length ) ; + } + } + else + { + value = sourceHtml ; + this._sourceHtml = null ; + } + return { 'isTag' : isTag, 'value' : value } ; + }, + + Each : function( func ) + { + var chunk ; + while ( ( chunk = this.Next() ) ) + func( chunk.isTag, chunk.value ) ; + } +} ; diff -r 3791b2e8e471 -r f5c322ae1c7b wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckicon.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckicon.js Mon Aug 11 13:54:49 2008 +0900 @@ -0,0 +1,103 @@ +/* + * FCKeditor - The text editor for Internet - http://www.fckeditor.net + * Copyright (C) 2003-2008 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 == + * + * FCKIcon Class: renders an icon from a single image, a strip or even a + * spacer. + */ + +var FCKIcon = function( iconPathOrStripInfoArray ) +{ + var sTypeOf = iconPathOrStripInfoArray ? typeof( iconPathOrStripInfoArray ) : 'undefined' ; + switch ( sTypeOf ) + { + case 'number' : + this.Path = FCKConfig.SkinPath + 'fck_strip.gif' ; + this.Size = 16 ; + this.Position = iconPathOrStripInfoArray ; + break ; + + case 'undefined' : + this.Path = FCK_SPACER_PATH ; + break ; + + case 'string' : + this.Path = iconPathOrStripInfoArray ; + break ; + + default : + // It is an array in the format [ StripFilePath, IconSize, IconPosition ] + this.Path = iconPathOrStripInfoArray[0] ; + this.Size = iconPathOrStripInfoArray[1] ; + this.Position = iconPathOrStripInfoArray[2] ; + } +} + +FCKIcon.prototype.CreateIconElement = function( document ) +{ + var eIcon, eIconImage ; + + if ( this.Position ) // It is using an icons strip image. + { + var sPos = '-' + ( ( this.Position - 1 ) * this.Size ) + 'px' ; + + if ( FCKBrowserInfo.IsIE ) + { + //
      + + eIcon = document.createElement( 'DIV' ) ; + + eIconImage = eIcon.appendChild( document.createElement( 'IMG' ) ) ; + eIconImage.src = this.Path ; + eIconImage.style.top = sPos ; + } + else + { + // + + eIcon = document.createElement( 'IMG' ) ; + eIcon.src = FCK_SPACER_PATH ; + eIcon.style.backgroundPosition = '0px ' + sPos ; + eIcon.style.backgroundImage = 'url("' + this.Path + '")' ; + } + } + else // It is using a single icon image. + { + if ( FCKBrowserInfo.IsIE ) + { + // IE makes the button 1px higher if using the directly, so we + // are changing to the
      system to clip the image correctly. + eIcon = document.createElement( 'DIV' ) ; + + eIconImage = eIcon.appendChild( document.createElement( 'IMG' ) ) ; + eIconImage.src = this.Path ? this.Path : FCK_SPACER_PATH ; + } + else + { + // This is not working well with IE. See notes above. + // + eIcon = document.createElement( 'IMG' ) ; + eIcon.src = this.Path ? this.Path : FCK_SPACER_PATH ; + } + } + + eIcon.className = 'TB_Button_Image' ; + + return eIcon ; +} diff -r 3791b2e8e471 -r f5c322ae1c7b wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckiecleanup.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckiecleanup.js Mon Aug 11 13:54:49 2008 +0900 @@ -0,0 +1,68 @@ +/* + * FCKeditor - The text editor for Internet - http://www.fckeditor.net + * Copyright (C) 2003-2008 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 == + * + * FCKIECleanup Class: a generic class used as a tool to remove IE leaks. + */ + +var FCKIECleanup = function( attachWindow ) +{ + // If the attachWindow already have a cleanup object, just use that one. + if ( attachWindow._FCKCleanupObj ) + this.Items = attachWindow._FCKCleanupObj.Items ; + else + { + this.Items = new Array() ; + + attachWindow._FCKCleanupObj = this ; + FCKTools.AddEventListenerEx( attachWindow, 'unload', FCKIECleanup_Cleanup ) ; +// attachWindow.attachEvent( 'onunload', FCKIECleanup_Cleanup ) ; + } +} + +FCKIECleanup.prototype.AddItem = function( dirtyItem, cleanupFunction ) +{ + this.Items.push( [ dirtyItem, cleanupFunction ] ) ; +} + +function FCKIECleanup_Cleanup() +{ + if ( !this._FCKCleanupObj || ( FCKConfig.MsWebBrowserControlCompat && !window.FCKUnloadFlag ) ) + return ; + + var aItems = this._FCKCleanupObj.Items ; + + while ( aItems.length > 0 ) + { + + // It is important to remove from the end to the beginning (pop()), + // because of the order things get created in the editor. In the code, + // elements in deeper position in the DOM are placed at the end of the + // cleanup function, so we must cleanup then first, otherwise IE could + // throw some crazy memory errors (IE bug). + var oItem = aItems.pop() ; + if ( oItem ) + oItem[1].call( oItem[0] ) ; + } + + this._FCKCleanupObj = null ; + + if ( CollectGarbage ) + CollectGarbage() ; +} diff -r 3791b2e8e471 -r f5c322ae1c7b wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckimagepreloader.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckimagepreloader.js Mon Aug 11 13:54:49 2008 +0900 @@ -0,0 +1,64 @@ +/* + * FCKeditor - The text editor for Internet - http://www.fckeditor.net + * Copyright (C) 2003-2008 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 == + * + * Preload a list of images, firing an event when complete. + */ + +var FCKImagePreloader = function() +{ + this._Images = new Array() ; +} + +FCKImagePreloader.prototype = +{ + AddImages : function( images ) + { + if ( typeof( images ) == 'string' ) + images = images.split( ';' ) ; + + this._Images = this._Images.concat( images ) ; + }, + + Start : function() + { + var aImages = this._Images ; + this._PreloadCount = aImages.length ; + + for ( var i = 0 ; i < aImages.length ; i++ ) + { + var eImg = document.createElement( 'img' ) ; + FCKTools.AddEventListenerEx( eImg, 'load', _FCKImagePreloader_OnImage, this ) ; + FCKTools.AddEventListenerEx( eImg, 'error', _FCKImagePreloader_OnImage, this ) ; + eImg.src = aImages[i] ; + + _FCKImagePreloader_ImageCache.push( eImg ) ; + } + } +}; + +// All preloaded images must be placed in a global array, otherwise the preload +// magic will not happen. +var _FCKImagePreloader_ImageCache = new Array() ; + +function _FCKImagePreloader_OnImage( ev, imagePreloader ) +{ + if ( (--imagePreloader._PreloadCount) == 0 && imagePreloader.OnComplete ) + imagePreloader.OnComplete() ; +} diff -r 3791b2e8e471 -r f5c322ae1c7b wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckkeystrokehandler.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckkeystrokehandler.js Mon Aug 11 13:54:49 2008 +0900 @@ -0,0 +1,141 @@ +/* + * FCKeditor - The text editor for Internet - http://www.fckeditor.net + * Copyright (C) 2003-2008 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 == + * + * Control keyboard keystroke combinations. + */ + +var FCKKeystrokeHandler = function( cancelCtrlDefaults ) +{ + this.Keystrokes = new Object() ; + this.CancelCtrlDefaults = ( cancelCtrlDefaults !== false ) ; +} + +/* + * Listen to keystroke events in an element or DOM document object. + * @target: The element or document to listen to keystroke events. + */ +FCKKeystrokeHandler.prototype.AttachToElement = function( target ) +{ + // For newer browsers, it is enough to listen to the keydown event only. + // Some browsers instead, don't cancel key events in the keydown, but in the + // keypress. So we must do a longer trip in those cases. + FCKTools.AddEventListenerEx( target, 'keydown', _FCKKeystrokeHandler_OnKeyDown, this ) ; + if ( FCKBrowserInfo.IsGecko10 || FCKBrowserInfo.IsOpera || ( FCKBrowserInfo.IsGecko && FCKBrowserInfo.IsMac ) ) + FCKTools.AddEventListenerEx( target, 'keypress', _FCKKeystrokeHandler_OnKeyPress, this ) ; +} + +/* + * Sets a list of keystrokes. It can receive either a single array or "n" + * arguments, each one being an array of 1 or 2 elemenst. The first element + * is the keystroke combination, and the second is the value to assign to it. + * If the second element is missing, the keystroke definition is removed. + */ +FCKKeystrokeHandler.prototype.SetKeystrokes = function() +{ + // Look through the arguments. + for ( var i = 0 ; i < arguments.length ; i++ ) + { + var keyDef = arguments[i] ; + + // If the configuration for the keystrokes is missing some element or has any extra comma + // this item won't be valid, so skip it and keep on processing. + if ( !keyDef ) + continue ; + + if ( typeof( keyDef[0] ) == 'object' ) // It is an array with arrays defining the keystrokes. + this.SetKeystrokes.apply( this, keyDef ) ; + else + { + if ( keyDef.length == 1 ) // If it has only one element, remove the keystroke. + delete this.Keystrokes[ keyDef[0] ] ; + else // Otherwise add it. + this.Keystrokes[ keyDef[0] ] = keyDef[1] === true ? true : keyDef ; + } + } +} + +function _FCKKeystrokeHandler_OnKeyDown( ev, keystrokeHandler ) +{ + // Get the key code. + var keystroke = ev.keyCode || ev.which ; + + // Combine it with the CTRL, SHIFT and ALT states. + var keyModifiers = 0 ; + + if ( ev.ctrlKey || ev.metaKey ) + keyModifiers += CTRL ; + + if ( ev.shiftKey ) + keyModifiers += SHIFT ; + + if ( ev.altKey ) + keyModifiers += ALT ; + + var keyCombination = keystroke + keyModifiers ; + + var cancelIt = keystrokeHandler._CancelIt = false ; + + // Look for its definition availability. + var keystrokeValue = keystrokeHandler.Keystrokes[ keyCombination ] ; + +// FCKDebug.Output( 'KeyDown: ' + keyCombination + ' - Value: ' + keystrokeValue ) ; + + // If the keystroke is defined + if ( keystrokeValue ) + { + // If the keystroke has been explicitly set to "true" OR calling the + // "OnKeystroke" event, it doesn't return "true", the default behavior + // must be preserved. + if ( keystrokeValue === true || !( keystrokeHandler.OnKeystroke && keystrokeHandler.OnKeystroke.apply( keystrokeHandler, keystrokeValue ) ) ) + return true ; + + cancelIt = true ; + } + + // By default, it will cancel all combinations with the CTRL key only (except positioning keys). + if ( cancelIt || ( keystrokeHandler.CancelCtrlDefaults && keyModifiers == CTRL && ( keystroke < 33 || keystroke > 40 ) ) ) + { + keystrokeHandler._CancelIt = true ; + + if ( ev.preventDefault ) + return ev.preventDefault() ; + + ev.returnValue = false ; + ev.cancelBubble = true ; + return false ; + } + + return true ; +} + +function _FCKKeystrokeHandler_OnKeyPress( ev, keystrokeHandler ) +{ + if ( keystrokeHandler._CancelIt ) + { +// FCKDebug.Output( 'KeyPress Cancel', 'Red') ; + + if ( ev.preventDefault ) + return ev.preventDefault() ; + + return false ; + } + + return true ; +} diff -r 3791b2e8e471 -r f5c322ae1c7b wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckmenublock.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckmenublock.js Mon Aug 11 13:54:49 2008 +0900 @@ -0,0 +1,153 @@ +/* + * FCKeditor - The text editor for Internet - http://www.fckeditor.net + * Copyright (C) 2003-2008 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 == + * + * Renders a list of menu items. + */ + +var FCKMenuBlock = function() +{ + this._Items = new Array() ; +} + + +FCKMenuBlock.prototype.Count = function() +{ + return this._Items.length ; +} + +FCKMenuBlock.prototype.AddItem = function( name, label, iconPathOrStripInfoArrayOrIndex, isDisabled, customData ) +{ + var oItem = new FCKMenuItem( this, name, label, iconPathOrStripInfoArrayOrIndex, isDisabled, customData ) ; + + oItem.OnClick = FCKTools.CreateEventListener( FCKMenuBlock_Item_OnClick, this ) ; + oItem.OnActivate = FCKTools.CreateEventListener( FCKMenuBlock_Item_OnActivate, this ) ; + + this._Items.push( oItem ) ; + + return oItem ; +} + +FCKMenuBlock.prototype.AddSeparator = function() +{ + this._Items.push( new FCKMenuSeparator() ) ; +} + +FCKMenuBlock.prototype.RemoveAllItems = function() +{ + this._Items = new Array() ; + + var eItemsTable = this._ItemsTable ; + if ( eItemsTable ) + { + while ( eItemsTable.rows.length > 0 ) + eItemsTable.deleteRow( 0 ) ; + } +} + +FCKMenuBlock.prototype.Create = function( parentElement ) +{ + if ( !this._ItemsTable ) + { + if ( FCK.IECleanup ) + FCK.IECleanup.AddItem( this, FCKMenuBlock_Cleanup ) ; + + this._Window = FCKTools.GetElementWindow( parentElement ) ; + + var oDoc = FCKTools.GetElementDocument( parentElement ) ; + + var eTable = parentElement.appendChild( oDoc.createElement( 'table' ) ) ; + eTable.cellPadding = 0 ; + eTable.cellSpacing = 0 ; + + FCKTools.DisableSelection( eTable ) ; + + var oMainElement = eTable.insertRow(-1).insertCell(-1) ; + oMainElement.className = 'MN_Menu' ; + + var eItemsTable = this._ItemsTable = oMainElement.appendChild( oDoc.createElement( 'table' ) ) ; + eItemsTable.cellPadding = 0 ; + eItemsTable.cellSpacing = 0 ; + } + + for ( var i = 0 ; i < this._Items.length ; i++ ) + this._Items[i].Create( this._ItemsTable ) ; +} + +/* Events */ + +function FCKMenuBlock_Item_OnClick( clickedItem, menuBlock ) +{ + if ( menuBlock.Hide ) + menuBlock.Hide() ; + + FCKTools.RunFunction( menuBlock.OnClick, menuBlock, [ clickedItem ] ) ; +} + +function FCKMenuBlock_Item_OnActivate( menuBlock ) +{ + var oActiveItem = menuBlock._ActiveItem ; + + if ( oActiveItem && oActiveItem != this ) + { + // Set the focus to this menu block window (to fire OnBlur on opened panels). + if ( !FCKBrowserInfo.IsIE && oActiveItem.HasSubMenu && !this.HasSubMenu ) + { + menuBlock._Window.focus() ; + + // Due to the event model provided by Opera, we need to set + // HasFocus here as the above focus() call will not fire the focus + // event in the panel immediately (#1200). + menuBlock.Panel.HasFocus = true ; + } + + oActiveItem.Deactivate() ; + } + + menuBlock._ActiveItem = this ; +} + +function FCKMenuBlock_Cleanup() +{ + this._Window = null ; + this._ItemsTable = null ; +} + +// ################# // + +var FCKMenuSeparator = function() +{} + +FCKMenuSeparator.prototype.Create = function( parentTable ) +{ + var oDoc = FCKTools.GetElementDocument( parentTable ) ; + + var r = parentTable.insertRow(-1) ; + + var eCell = r.insertCell(-1) ; + eCell.className = 'MN_Separator MN_Icon' ; + + eCell = r.insertCell(-1) ; + eCell.className = 'MN_Separator' ; + eCell.appendChild( oDoc.createElement( 'DIV' ) ).className = 'MN_Separator_Line' ; + + eCell = r.insertCell(-1) ; + eCell.className = 'MN_Separator' ; + eCell.appendChild( oDoc.createElement( 'DIV' ) ).className = 'MN_Separator_Line' ; +} diff -r 3791b2e8e471 -r f5c322ae1c7b wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckmenublockpanel.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckmenublockpanel.js Mon Aug 11 13:54:49 2008 +0900 @@ -0,0 +1,54 @@ +/* + * FCKeditor - The text editor for Internet - http://www.fckeditor.net + * Copyright (C) 2003-2008 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 == + * + * This class is a menu block that behaves like a panel. It's a mix of the + * FCKMenuBlock and FCKPanel classes. + */ + +var FCKMenuBlockPanel = function() +{ + // Call the "base" constructor. + FCKMenuBlock.call( this ) ; +} + +FCKMenuBlockPanel.prototype = new FCKMenuBlock() ; + + +// Override the create method. +FCKMenuBlockPanel.prototype.Create = function() +{ + var oPanel = this.Panel = ( this.Parent && this.Parent.Panel ? this.Parent.Panel.CreateChildPanel() : new FCKPanel() ) ; + oPanel.AppendStyleSheet( FCKConfig.SkinEditorCSS ) ; + + // Call the "base" implementation. + FCKMenuBlock.prototype.Create.call( this, oPanel.MainNode ) ; +} + +FCKMenuBlockPanel.prototype.Show = function( x, y, relElement ) +{ + if ( !this.Panel.CheckIsOpened() ) + this.Panel.Show( x, y, relElement ) ; +} + +FCKMenuBlockPanel.prototype.Hide = function() +{ + if ( this.Panel.CheckIsOpened() ) + this.Panel.Hide() ; +} diff -r 3791b2e8e471 -r f5c322ae1c7b wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckmenuitem.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckmenuitem.js Mon Aug 11 13:54:49 2008 +0900 @@ -0,0 +1,161 @@ +/* + * FCKeditor - The text editor for Internet - http://www.fckeditor.net + * Copyright (C) 2003-2008 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 == + * + * Defines and renders a menu items in a menu block. + */ + +var FCKMenuItem = function( parentMenuBlock, name, label, iconPathOrStripInfoArray, isDisabled, customData ) +{ + this.Name = name ; + this.Label = label || name ; + this.IsDisabled = isDisabled ; + + this.Icon = new FCKIcon( iconPathOrStripInfoArray ) ; + + this.SubMenu = new FCKMenuBlockPanel() ; + this.SubMenu.Parent = parentMenuBlock ; + this.SubMenu.OnClick = FCKTools.CreateEventListener( FCKMenuItem_SubMenu_OnClick, this ) ; + this.CustomData = customData ; + + if ( FCK.IECleanup ) + FCK.IECleanup.AddItem( this, FCKMenuItem_Cleanup ) ; +} + + +FCKMenuItem.prototype.AddItem = function( name, label, iconPathOrStripInfoArrayOrIndex, isDisabled, customData ) +{ + this.HasSubMenu = true ; + return this.SubMenu.AddItem( name, label, iconPathOrStripInfoArrayOrIndex, isDisabled, customData ) ; +} + +FCKMenuItem.prototype.AddSeparator = function() +{ + this.SubMenu.AddSeparator() ; +} + +FCKMenuItem.prototype.Create = function( parentTable ) +{ + var bHasSubMenu = this.HasSubMenu ; + + var oDoc = FCKTools.GetElementDocument( parentTable ) ; + + // Add a row in the table to hold the menu item. + var r = this.MainElement = parentTable.insertRow(-1) ; + r.className = this.IsDisabled ? 'MN_Item_Disabled' : 'MN_Item' ; + + // Set the row behavior. + if ( !this.IsDisabled ) + { + FCKTools.AddEventListenerEx( r, 'mouseover', FCKMenuItem_OnMouseOver, [ this ] ) ; + FCKTools.AddEventListenerEx( r, 'click', FCKMenuItem_OnClick, [ this ] ) ; + + if ( !bHasSubMenu ) + FCKTools.AddEventListenerEx( r, 'mouseout', FCKMenuItem_OnMouseOut, [ this ] ) ; + } + + // Create the icon cell. + var eCell = r.insertCell(-1) ; + eCell.className = 'MN_Icon' ; + eCell.appendChild( this.Icon.CreateIconElement( oDoc ) ) ; + + // Create the label cell. + eCell = r.insertCell(-1) ; + eCell.className = 'MN_Label' ; + eCell.noWrap = true ; + eCell.appendChild( oDoc.createTextNode( this.Label ) ) ; + + // Create the arrow cell and setup the sub menu panel (if needed). + eCell = r.insertCell(-1) ; + if ( bHasSubMenu ) + { + eCell.className = 'MN_Arrow' ; + + // The arrow is a fixed size image. + var eArrowImg = eCell.appendChild( oDoc.createElement( 'IMG' ) ) ; + eArrowImg.src = FCK_IMAGES_PATH + 'arrow_' + FCKLang.Dir + '.gif' ; + eArrowImg.width = 4 ; + eArrowImg.height = 7 ; + + this.SubMenu.Create() ; + this.SubMenu.Panel.OnHide = FCKTools.CreateEventListener( FCKMenuItem_SubMenu_OnHide, this ) ; + } +} + +FCKMenuItem.prototype.Activate = function() +{ + this.MainElement.className = 'MN_Item_Over' ; + + if ( this.HasSubMenu ) + { + // Show the child menu block. The ( +2, -2 ) correction is done because + // of the padding in the skin. It is not a good solution because one + // could change the skin and so the final result would not be accurate. + // For now it is ok because we are controlling the skin. + this.SubMenu.Show( this.MainElement.offsetWidth + 2, -2, this.MainElement ) ; + } + + FCKTools.RunFunction( this.OnActivate, this ) ; +} + +FCKMenuItem.prototype.Deactivate = function() +{ + this.MainElement.className = 'MN_Item' ; + + if ( this.HasSubMenu ) + this.SubMenu.Hide() ; +} + +/* Events */ + +function FCKMenuItem_SubMenu_OnClick( clickedItem, listeningItem ) +{ + FCKTools.RunFunction( listeningItem.OnClick, listeningItem, [ clickedItem ] ) ; +} + +function FCKMenuItem_SubMenu_OnHide( menuItem ) +{ + menuItem.Deactivate() ; +} + +function FCKMenuItem_OnClick( ev, menuItem ) +{ + if ( menuItem.HasSubMenu ) + menuItem.Activate() ; + else + { + menuItem.Deactivate() ; + FCKTools.RunFunction( menuItem.OnClick, menuItem, [ menuItem ] ) ; + } +} + +function FCKMenuItem_OnMouseOver( ev, menuItem ) +{ + menuItem.Activate() ; +} + +function FCKMenuItem_OnMouseOut( ev, menuItem ) +{ + menuItem.Deactivate() ; +} + +function FCKMenuItem_Cleanup() +{ + this.MainElement = null ; +} diff -r 3791b2e8e471 -r f5c322ae1c7b wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckpanel.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckpanel.js Mon Aug 11 13:54:49 2008 +0900 @@ -0,0 +1,386 @@ +/* + * FCKeditor - The text editor for Internet - http://www.fckeditor.net + * Copyright (C) 2003-2008 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 == + * + * Component that creates floating panels. It is used by many + * other components, like the toolbar items, context menu, etc... + */ + +var FCKPanel = function( parentWindow ) +{ + this.IsRTL = ( FCKLang.Dir == 'rtl' ) ; + this.IsContextMenu = false ; + this._LockCounter = 0 ; + + this._Window = parentWindow || window ; + + var oDocument ; + + if ( FCKBrowserInfo.IsIE ) + { + // Create the Popup that will hold the panel. + // The popup has to be created before playing with domain hacks, see #1666. + this._Popup = this._Window.createPopup() ; + + // this._Window cannot be accessed while playing with domain hacks, but local variable is ok. + // See #1666. + var pDoc = this._Window.document ; + + // This is a trick to IE6 (not IE7). The original domain must be set + // before creating the popup, so we are able to take a refence to the + // document inside of it, and the set the proper domain for it. (#123) + if ( FCK_IS_CUSTOM_DOMAIN && !FCKBrowserInfo.IsIE7 ) + { + pDoc.domain = FCK_ORIGINAL_DOMAIN ; + document.domain = FCK_ORIGINAL_DOMAIN ; + } + + oDocument = this.Document = this._Popup.document ; + + // Set the proper domain inside the popup. + if ( FCK_IS_CUSTOM_DOMAIN ) + { + oDocument.domain = FCK_RUNTIME_DOMAIN ; + pDoc.domain = FCK_RUNTIME_DOMAIN ; + document.domain = FCK_RUNTIME_DOMAIN ; + } + + FCK.IECleanup.AddItem( this, FCKPanel_Cleanup ) ; + } + else + { + var oIFrame = this._IFrame = this._Window.document.createElement('iframe') ; + FCKTools.ResetStyles( oIFrame ); + oIFrame.src = 'javascript:void(0)' ; + oIFrame.allowTransparency = true ; + oIFrame.frameBorder = '0' ; + oIFrame.scrolling = 'no' ; + oIFrame.style.width = oIFrame.style.height = '0px' ; + FCKDomTools.SetElementStyles( oIFrame, + { + position : 'absolute', + zIndex : FCKConfig.FloatingPanelsZIndex + } ) ; + + this._Window.document.body.appendChild( oIFrame ) ; + + var oIFrameWindow = oIFrame.contentWindow ; + + oDocument = this.Document = oIFrameWindow.document ; + + // Workaround for Safari 12256. Ticket #63 + var sBase = '' ; + if ( FCKBrowserInfo.IsSafari ) + sBase = '' ; + + // Initialize the IFRAME document body. + oDocument.open() ; + oDocument.write( '' + sBase + '<\/head><\/body><\/html>' ) ; + oDocument.close() ; + + if( FCKBrowserInfo.IsAIR ) + FCKAdobeAIR.Panel_Contructor( oDocument, window.document.location ) ; + + FCKTools.AddEventListenerEx( oIFrameWindow, 'focus', FCKPanel_Window_OnFocus, this ) ; + FCKTools.AddEventListenerEx( oIFrameWindow, 'blur', FCKPanel_Window_OnBlur, this ) ; + } + + oDocument.dir = FCKLang.Dir ; + + FCKTools.AddEventListener( oDocument, 'contextmenu', FCKTools.CancelEvent ) ; + + + // Create the main DIV that is used as the panel base. + this.MainNode = oDocument.body.appendChild( oDocument.createElement('DIV') ) ; + + // The "float" property must be set so Firefox calculates the size correctly. + this.MainNode.style.cssFloat = this.IsRTL ? 'right' : 'left' ; +} + + +FCKPanel.prototype.AppendStyleSheet = function( styleSheet ) +{ + FCKTools.AppendStyleSheet( this.Document, styleSheet ) ; +} + +FCKPanel.prototype.Preload = function( x, y, relElement ) +{ + // The offsetWidth and offsetHeight properties are not available if the + // element is not visible. So we must "show" the popup with no size to + // be able to use that values in the second call (IE only). + if ( this._Popup ) + this._Popup.show( x, y, 0, 0, relElement ) ; +} + +FCKPanel.prototype.Show = function( x, y, relElement, width, height ) +{ + var iMainWidth ; + var eMainNode = this.MainNode ; + + if ( this._Popup ) + { + // The offsetWidth and offsetHeight properties are not available if the + // element is not visible. So we must "show" the popup with no size to + // be able to use that values in the second call. + this._Popup.show( x, y, 0, 0, relElement ) ; + + // The following lines must be place after the above "show", otherwise it + // doesn't has the desired effect. + FCKDomTools.SetElementStyles( eMainNode, + { + width : width ? width + 'px' : '', + height : height ? height + 'px' : '' + } ) ; + + iMainWidth = eMainNode.offsetWidth ; + + if ( this.IsRTL ) + { + if ( this.IsContextMenu ) + x = x - iMainWidth + 1 ; + else if ( relElement ) + x = ( x * -1 ) + relElement.offsetWidth - iMainWidth ; + } + + // Second call: Show the Popup at the specified location, with the correct size. + this._Popup.show( x, y, iMainWidth, eMainNode.offsetHeight, relElement ) ; + + if ( this.OnHide ) + { + if ( this._Timer ) + CheckPopupOnHide.call( this, true ) ; + + this._Timer = FCKTools.SetInterval( CheckPopupOnHide, 100, this ) ; + } + } + else + { + // Do not fire OnBlur while the panel is opened. + if ( typeof( FCK.ToolbarSet.CurrentInstance.FocusManager ) != 'undefined' ) + FCK.ToolbarSet.CurrentInstance.FocusManager.Lock() ; + + if ( this.ParentPanel ) + { + this.ParentPanel.Lock() ; + + // Due to a bug on FF3, we must ensure that the parent panel will + // blur (#1584). + FCKPanel_Window_OnBlur( null, this.ParentPanel ) ; + } + + // Toggle the iframe scrolling attribute to prevent the panel + // scrollbars from disappearing in FF Mac. (#191) + if ( FCKBrowserInfo.IsGecko && FCKBrowserInfo.IsMac ) + { + this._IFrame.scrolling = '' ; + FCKTools.RunFunction( function(){ this._IFrame.scrolling = 'no'; }, this ) ; + } + + // Be sure we'll not have more than one Panel opened at the same time. + // Do not unlock focus manager here because we're displaying another floating panel + // instead of returning the editor to a "no panel" state (Bug #1514). + if ( FCK.ToolbarSet.CurrentInstance.GetInstanceObject( 'FCKPanel' )._OpenedPanel && + FCK.ToolbarSet.CurrentInstance.GetInstanceObject( 'FCKPanel' )._OpenedPanel != this ) + FCK.ToolbarSet.CurrentInstance.GetInstanceObject( 'FCKPanel' )._OpenedPanel.Hide( false, true ) ; + + FCKDomTools.SetElementStyles( eMainNode, + { + width : width ? width + 'px' : '', + height : height ? height + 'px' : '' + } ) ; + + iMainWidth = eMainNode.offsetWidth ; + + if ( !width ) this._IFrame.width = 1 ; + if ( !height ) this._IFrame.height = 1 ; + + // This is weird... but with Firefox, we must get the offsetWidth before + // setting the _IFrame size (which returns "0"), and then after that, + // to return the correct width. Remove the first step and it will not + // work when the editor is in RTL. + // + // The "|| eMainNode.firstChild.offsetWidth" part has been added + // for Opera compatibility (see #570). + iMainWidth = eMainNode.offsetWidth || eMainNode.firstChild.offsetWidth ; + + // Base the popup coordinates upon the coordinates of relElement. + var oPos = FCKTools.GetDocumentPosition( this._Window, + relElement.nodeType == 9 ? + ( FCKTools.IsStrictMode( relElement ) ? relElement.documentElement : relElement.body ) : + relElement ) ; + + // Minus the offsets provided by any positioned parent element of the panel iframe. + var positionedAncestor = FCKDomTools.GetPositionedAncestor( this._IFrame.parentNode ) ; + if ( positionedAncestor ) + { + var nPos = FCKTools.GetDocumentPosition( FCKTools.GetElementWindow( positionedAncestor ), positionedAncestor ) ; + oPos.x -= nPos.x ; + oPos.y -= nPos.y ; + } + + if ( this.IsRTL && !this.IsContextMenu ) + x = ( x * -1 ) ; + + x += oPos.x ; + y += oPos.y ; + + if ( this.IsRTL ) + { + if ( this.IsContextMenu ) + x = x - iMainWidth + 1 ; + else if ( relElement ) + x = x + relElement.offsetWidth - iMainWidth ; + } + else + { + var oViewPaneSize = FCKTools.GetViewPaneSize( this._Window ) ; + var oScrollPosition = FCKTools.GetScrollPosition( this._Window ) ; + + var iViewPaneHeight = oViewPaneSize.Height + oScrollPosition.Y ; + var iViewPaneWidth = oViewPaneSize.Width + oScrollPosition.X ; + + if ( ( x + iMainWidth ) > iViewPaneWidth ) + x -= x + iMainWidth - iViewPaneWidth ; + + if ( ( y + eMainNode.offsetHeight ) > iViewPaneHeight ) + y -= y + eMainNode.offsetHeight - iViewPaneHeight ; + } + + // Set the context menu DIV in the specified location. + FCKDomTools.SetElementStyles( this._IFrame, + { + left : x + 'px', + top : y + 'px' + } ) ; + + // Move the focus to the IFRAME so we catch the "onblur". + this._IFrame.contentWindow.focus() ; + this._IsOpened = true ; + + var me = this ; + this._resizeTimer = setTimeout( function() + { + var iWidth = eMainNode.offsetWidth || eMainNode.firstChild.offsetWidth ; + var iHeight = eMainNode.offsetHeight ; + me._IFrame.style.width = iWidth + 'px' ; + me._IFrame.style.height = iHeight + 'px' ; + + }, 0 ) ; + + FCK.ToolbarSet.CurrentInstance.GetInstanceObject( 'FCKPanel' )._OpenedPanel = this ; + } + + FCKTools.RunFunction( this.OnShow, this ) ; +} + +FCKPanel.prototype.Hide = function( ignoreOnHide, ignoreFocusManagerUnlock ) +{ + if ( this._Popup ) + this._Popup.hide() ; + else + { + if ( !this._IsOpened || this._LockCounter > 0 ) + return ; + + // Enable the editor to fire the "OnBlur". + if ( typeof( FCKFocusManager ) != 'undefined' && !ignoreFocusManagerUnlock ) + FCKFocusManager.Unlock() ; + + // It is better to set the sizes to 0, otherwise Firefox would have + // rendering problems. + this._IFrame.style.width = this._IFrame.style.height = '0px' ; + + this._IsOpened = false ; + + if ( this._resizeTimer ) + { + clearTimeout( this._resizeTimer ) ; + this._resizeTimer = null ; + } + + if ( this.ParentPanel ) + this.ParentPanel.Unlock() ; + + if ( !ignoreOnHide ) + FCKTools.RunFunction( this.OnHide, this ) ; + } +} + +FCKPanel.prototype.CheckIsOpened = function() +{ + if ( this._Popup ) + return this._Popup.isOpen ; + else + return this._IsOpened ; +} + +FCKPanel.prototype.CreateChildPanel = function() +{ + var oWindow = this._Popup ? FCKTools.GetDocumentWindow( this.Document ) : this._Window ; + + var oChildPanel = new FCKPanel( oWindow ) ; + oChildPanel.ParentPanel = this ; + + return oChildPanel ; +} + +FCKPanel.prototype.Lock = function() +{ + this._LockCounter++ ; +} + +FCKPanel.prototype.Unlock = function() +{ + if ( --this._LockCounter == 0 && !this.HasFocus ) + this.Hide() ; +} + +/* Events */ + +function FCKPanel_Window_OnFocus( e, panel ) +{ + panel.HasFocus = true ; +} + +function FCKPanel_Window_OnBlur( e, panel ) +{ + panel.HasFocus = false ; + + if ( panel._LockCounter == 0 ) + FCKTools.RunFunction( panel.Hide, panel ) ; +} + +function CheckPopupOnHide( forceHide ) +{ + if ( forceHide || !this._Popup.isOpen ) + { + window.clearInterval( this._Timer ) ; + this._Timer = null ; + + FCKTools.RunFunction( this.OnHide, this ) ; + } +} + +function FCKPanel_Cleanup() +{ + this._Popup = null ; + this._Window = null ; + this.Document = null ; + this.MainNode = null ; +} diff -r 3791b2e8e471 -r f5c322ae1c7b wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckplugin.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckplugin.js Mon Aug 11 13:54:49 2008 +0900 @@ -0,0 +1,56 @@ +/* + * FCKeditor - The text editor for Internet - http://www.fckeditor.net + * Copyright (C) 2003-2008 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 == + * + * FCKPlugin Class: Represents a single plugin. + */ + +var FCKPlugin = function( name, availableLangs, basePath ) +{ + this.Name = name ; + this.BasePath = basePath ? basePath : FCKConfig.PluginsPath ; + this.Path = this.BasePath + name + '/' ; + + if ( !availableLangs || availableLangs.length == 0 ) + this.AvailableLangs = new Array() ; + else + this.AvailableLangs = availableLangs.split(',') ; +} + +FCKPlugin.prototype.Load = function() +{ + // Load the language file, if defined. + if ( this.AvailableLangs.length > 0 ) + { + var sLang ; + + // Check if the plugin has the language file for the active language. + if ( this.AvailableLangs.IndexOf( FCKLanguageManager.ActiveLanguage.Code ) >= 0 ) + sLang = FCKLanguageManager.ActiveLanguage.Code ; + else + // Load the default language file (first one) if the current one is not available. + sLang = this.AvailableLangs[0] ; + + // Add the main plugin script. + LoadScript( this.Path + 'lang/' + sLang + '.js' ) ; + } + + // Add the main plugin script. + LoadScript( this.Path + 'fckplugin.js' ) ; +} diff -r 3791b2e8e471 -r f5c322ae1c7b wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckspecialcombo.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckspecialcombo.js Mon Aug 11 13:54:49 2008 +0900 @@ -0,0 +1,376 @@ +/* + * FCKeditor - The text editor for Internet - http://www.fckeditor.net + * Copyright (C) 2003-2008 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 == + * + * FCKSpecialCombo Class: represents a special combo. + */ + +var FCKSpecialCombo = function( caption, fieldWidth, panelWidth, panelMaxHeight, parentWindow ) +{ + // Default properties values. + this.FieldWidth = fieldWidth || 100 ; + this.PanelWidth = panelWidth || 150 ; + this.PanelMaxHeight = panelMaxHeight || 150 ; + this.Label = ' ' ; + this.Caption = caption ; + this.Tooltip = caption ; + this.Style = FCK_TOOLBARITEM_ICONTEXT ; + + this.Enabled = true ; + + this.Items = new Object() ; + + this._Panel = new FCKPanel( parentWindow || window ) ; + this._Panel.AppendStyleSheet( FCKConfig.SkinEditorCSS ) ; + this._PanelBox = this._Panel.MainNode.appendChild( this._Panel.Document.createElement( 'DIV' ) ) ; + this._PanelBox.className = 'SC_Panel' ; + this._PanelBox.style.width = this.PanelWidth + 'px' ; + + this._PanelBox.innerHTML = '
      ' ; + + this._ItemsHolderEl = this._PanelBox.getElementsByTagName('TD')[0] ; + + if ( FCK.IECleanup ) + FCK.IECleanup.AddItem( this, FCKSpecialCombo_Cleanup ) ; + +// this._Panel.StyleSheet = FCKConfig.SkinPath + 'fck_contextmenu.css' ; +// this._Panel.Create() ; +// this._Panel.PanelDiv.className += ' SC_Panel' ; +// this._Panel.PanelDiv.innerHTML = '
      ' ; +// this._ItemsHolderEl = this._Panel.PanelDiv.getElementsByTagName('TD')[0] ; +} + +function FCKSpecialCombo_ItemOnMouseOver() +{ + this.className += ' SC_ItemOver' ; +} + +function FCKSpecialCombo_ItemOnMouseOut() +{ + this.className = this.originalClass ; +} + +function FCKSpecialCombo_ItemOnClick( ev, specialCombo, itemId ) +{ + this.className = this.originalClass ; + + specialCombo._Panel.Hide() ; + + specialCombo.SetLabel( this.FCKItemLabel ) ; + + if ( typeof( specialCombo.OnSelect ) == 'function' ) + specialCombo.OnSelect( itemId, this ) ; +} + +FCKSpecialCombo.prototype.ClearItems = function () +{ + if ( this.Items ) + this.Items = {} ; + + var itemsholder = this._ItemsHolderEl ; + while ( itemsholder.firstChild ) + itemsholder.removeChild( itemsholder.firstChild ) ; +} + +FCKSpecialCombo.prototype.AddItem = function( id, html, label, bgColor ) +{ + //
      Bold 1
      + var oDiv = this._ItemsHolderEl.appendChild( this._Panel.Document.createElement( 'DIV' ) ) ; + oDiv.className = oDiv.originalClass = 'SC_Item' ; + oDiv.innerHTML = html ; + oDiv.FCKItemLabel = label || id ; + oDiv.Selected = false ; + + // In IE, the width must be set so the borders are shown correctly when the content overflows. + if ( FCKBrowserInfo.IsIE ) + oDiv.style.width = '100%' ; + + if ( bgColor ) + oDiv.style.backgroundColor = bgColor ; + + FCKTools.AddEventListenerEx( oDiv, 'mouseover', FCKSpecialCombo_ItemOnMouseOver ) ; + FCKTools.AddEventListenerEx( oDiv, 'mouseout', FCKSpecialCombo_ItemOnMouseOut ) ; + FCKTools.AddEventListenerEx( oDiv, 'click', FCKSpecialCombo_ItemOnClick, [ this, id ] ) ; + + this.Items[ id.toString().toLowerCase() ] = oDiv ; + + return oDiv ; +} + +FCKSpecialCombo.prototype.SelectItem = function( item ) +{ + if ( typeof item == 'string' ) + item = this.Items[ item.toString().toLowerCase() ] ; + + if ( item ) + { + item.className = item.originalClass = 'SC_ItemSelected' ; + item.Selected = true ; + } +} + +FCKSpecialCombo.prototype.SelectItemByLabel = function( itemLabel, setLabel ) +{ + for ( var id in this.Items ) + { + var oDiv = this.Items[id] ; + + if ( oDiv.FCKItemLabel == itemLabel ) + { + oDiv.className = oDiv.originalClass = 'SC_ItemSelected' ; + oDiv.Selected = true ; + + if ( setLabel ) + this.SetLabel( itemLabel ) ; + } + } +} + +FCKSpecialCombo.prototype.DeselectAll = function( clearLabel ) +{ + for ( var i in this.Items ) + { + if ( !this.Items[i] ) continue; + this.Items[i].className = this.Items[i].originalClass = 'SC_Item' ; + this.Items[i].Selected = false ; + } + + if ( clearLabel ) + this.SetLabel( '' ) ; +} + +FCKSpecialCombo.prototype.SetLabelById = function( id ) +{ + id = id ? id.toString().toLowerCase() : '' ; + + var oDiv = this.Items[ id ] ; + this.SetLabel( oDiv ? oDiv.FCKItemLabel : '' ) ; +} + +FCKSpecialCombo.prototype.SetLabel = function( text ) +{ + text = ( !text || text.length == 0 ) ? ' ' : text ; + + if ( text == this.Label ) + return ; + + this.Label = text ; + + var labelEl = this._LabelEl ; + if ( labelEl ) + { + labelEl.innerHTML = text ; + + // It may happen that the label is some HTML, including tags. This + // would be a problem because when the user click on those tags, the + // combo will get the selection from the editing area. So we must + // disable any kind of selection here. + FCKTools.DisableSelection( labelEl ) ; + } +} + +FCKSpecialCombo.prototype.SetEnabled = function( isEnabled ) +{ + this.Enabled = isEnabled ; + + // In IE it can happen when the page is reloaded that _OuterTable is null, so check its existence + if ( this._OuterTable ) + this._OuterTable.className = isEnabled ? '' : 'SC_FieldDisabled' ; +} + +FCKSpecialCombo.prototype.Create = function( targetElement ) +{ + var oDoc = FCKTools.GetElementDocument( targetElement ) ; + var eOuterTable = this._OuterTable = targetElement.appendChild( oDoc.createElement( 'TABLE' ) ) ; + eOuterTable.cellPadding = 0 ; + eOuterTable.cellSpacing = 0 ; + + eOuterTable.insertRow(-1) ; + + var sClass ; + var bShowLabel ; + + switch ( this.Style ) + { + case FCK_TOOLBARITEM_ONLYICON : + sClass = 'TB_ButtonType_Icon' ; + bShowLabel = false; + break ; + case FCK_TOOLBARITEM_ONLYTEXT : + sClass = 'TB_ButtonType_Text' ; + bShowLabel = false; + break ; + case FCK_TOOLBARITEM_ICONTEXT : + bShowLabel = true; + break ; + } + + if ( this.Caption && this.Caption.length > 0 && bShowLabel ) + { + var oCaptionCell = eOuterTable.rows[0].insertCell(-1) ; + oCaptionCell.innerHTML = this.Caption ; + oCaptionCell.className = 'SC_FieldCaption' ; + } + + // Create the main DIV element. + var oField = FCKTools.AppendElement( eOuterTable.rows[0].insertCell(-1), 'div' ) ; + if ( bShowLabel ) + { + oField.className = 'SC_Field' ; + oField.style.width = this.FieldWidth + 'px' ; + oField.innerHTML = '
       
      ' ; + + this._LabelEl = oField.getElementsByTagName('label')[0] ; // Memory Leak + this._LabelEl.innerHTML = this.Label ; + } + else + { + oField.className = 'TB_Button_Off' ; + //oField.innerHTML = '' + this.Caption + '
       
      ' ; + //oField.innerHTML = '
       
      ' ; + + // Gets the correct CSS class to use for the specified style (param). + oField.innerHTML = '' + + '' + + //'' + + '' + + '' + + '' + + '' + + '' + + '' + + '
      ' + this.Caption + '
      ' ; + } + + + // Events Handlers + + FCKTools.AddEventListenerEx( oField, 'mouseover', FCKSpecialCombo_OnMouseOver, this ) ; + FCKTools.AddEventListenerEx( oField, 'mouseout', FCKSpecialCombo_OnMouseOut, this ) ; + FCKTools.AddEventListenerEx( oField, 'click', FCKSpecialCombo_OnClick, this ) ; + + FCKTools.DisableSelection( this._Panel.Document.body ) ; +} + +function FCKSpecialCombo_Cleanup() +{ + this._LabelEl = null ; + this._OuterTable = null ; + this._ItemsHolderEl = null ; + this._PanelBox = null ; + + if ( this.Items ) + { + for ( var key in this.Items ) + this.Items[key] = null ; + } +} + +function FCKSpecialCombo_OnMouseOver( ev, specialCombo ) +{ + if ( specialCombo.Enabled ) + { + switch ( specialCombo.Style ) + { + case FCK_TOOLBARITEM_ONLYICON : + this.className = 'TB_Button_On_Over'; + break ; + case FCK_TOOLBARITEM_ONLYTEXT : + this.className = 'TB_Button_On_Over'; + break ; + case FCK_TOOLBARITEM_ICONTEXT : + this.className = 'SC_Field SC_FieldOver' ; + break ; + } + } +} + +function FCKSpecialCombo_OnMouseOut( ev, specialCombo ) +{ + switch ( specialCombo.Style ) + { + case FCK_TOOLBARITEM_ONLYICON : + this.className = 'TB_Button_Off'; + break ; + case FCK_TOOLBARITEM_ONLYTEXT : + this.className = 'TB_Button_Off'; + break ; + case FCK_TOOLBARITEM_ICONTEXT : + this.className='SC_Field' ; + break ; + } +} + +function FCKSpecialCombo_OnClick( e, specialCombo ) +{ + // For Mozilla we must stop the event propagation to avoid it hiding + // the panel because of a click outside of it. +// if ( e ) +// { +// e.stopPropagation() ; +// FCKPanelEventHandlers.OnDocumentClick( e ) ; +// } + + if ( specialCombo.Enabled ) + { + var oPanel = specialCombo._Panel ; + var oPanelBox = specialCombo._PanelBox ; + var oItemsHolder = specialCombo._ItemsHolderEl ; + var iMaxHeight = specialCombo.PanelMaxHeight ; + + if ( specialCombo.OnBeforeClick ) + specialCombo.OnBeforeClick( specialCombo ) ; + + // This is a tricky thing. We must call the "Load" function, otherwise + // it will not be possible to retrieve "oItemsHolder.offsetHeight" (IE only). + if ( FCKBrowserInfo.IsIE ) + oPanel.Preload( 0, this.offsetHeight, this ) ; + + if ( oItemsHolder.offsetHeight > iMaxHeight ) +// { + oPanelBox.style.height = iMaxHeight + 'px' ; + +// if ( FCKBrowserInfo.IsGecko ) +// oPanelBox.style.overflow = '-moz-scrollbars-vertical' ; +// } + else + oPanelBox.style.height = '' ; + +// oPanel.PanelDiv.style.width = specialCombo.PanelWidth + 'px' ; + + oPanel.Show( 0, this.offsetHeight, this ) ; + } + +// return false ; +} + +/* +Sample Combo Field HTML output: + +
      + + + + + + + +
       
      +
      +*/ diff -r 3791b2e8e471 -r f5c322ae1c7b wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckstyle.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wiki/htdocs/applets/FCKeditor/editor/_source/classes/fckstyle.js Mon Aug 11 13:54:49 2008 +0900 @@ -0,0 +1,1500 @@ +/* + * FCKeditor - The text editor for Internet - http://www.fckeditor.net + * Copyright (C) 2003-2008 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 == + * + * FCKStyle Class: contains a style definition, and all methods to work with + * the style in a document. + */ + +/** + * @param {Object} styleDesc A "style descriptor" object, containing the raw + * style definition in the following format: + * '' ; + FCK._BehaviorsStyle = sStyle ; + } + + return FCK._BehaviorsStyle ; +} + +function Doc_OnMouseUp() +{ + if ( FCK.EditorWindow.event.srcElement.tagName == 'HTML' ) + { + FCK.Focus() ; + FCK.EditorWindow.event.cancelBubble = true ; + FCK.EditorWindow.event.returnValue = false ; + } +} + +function Doc_OnPaste() +{ + var body = FCK.EditorDocument.body ; + + body.detachEvent( 'onpaste', Doc_OnPaste ) ; + + var ret = FCK.Paste( !FCKConfig.ForcePasteAsPlainText && !FCKConfig.AutoDetectPasteFromWord ) ; + + body.attachEvent( 'onpaste', Doc_OnPaste ) ; + + return ret ; +} + +function Doc_OnDblClick() +{ + FCK.OnDoubleClick( FCK.EditorWindow.event.srcElement ) ; + FCK.EditorWindow.event.cancelBubble = true ; +} + +function Doc_OnSelectionChange() +{ + // Don't fire the event if no document is loaded. + if ( !FCK.IsSelectionChangeLocked && FCK.EditorDocument ) + FCK.Events.FireEvent( "OnSelectionChange" ) ; +} + +function Doc_OnDrop() +{ + if ( FCK.MouseDownFlag ) + { + FCK.MouseDownFlag = false ; + return ; + } + + if ( FCKConfig.ForcePasteAsPlainText ) + { + var evt = FCK.EditorWindow.event ; + + if ( FCK._CheckIsPastingEnabled() || FCKConfig.ShowDropDialog ) + FCK.PasteAsPlainText( evt.dataTransfer.getData( 'Text' ) ) ; + + evt.returnValue = false ; + evt.cancelBubble = true ; + } +} + +FCK.InitializeBehaviors = function( dontReturn ) +{ + // Set the focus to the editable area when clicking in the document area. + // TODO: The cursor must be positioned at the end. + this.EditorDocument.attachEvent( 'onmouseup', Doc_OnMouseUp ) ; + + // Intercept pasting operations + this.EditorDocument.body.attachEvent( 'onpaste', Doc_OnPaste ) ; + + // Intercept drop operations + this.EditorDocument.body.attachEvent( 'ondrop', Doc_OnDrop ) ; + + // Reset the context menu. + FCK.ContextMenu._InnerContextMenu.AttachToElement( FCK.EditorDocument.body ) ; + + this.EditorDocument.attachEvent("onkeydown", FCK._KeyDownListener ) ; + + this.EditorDocument.attachEvent("ondblclick", Doc_OnDblClick ) ; + + this.EditorDocument.attachEvent("onbeforedeactivate", function(){ FCKSelection.Save( true ) ; } ) ; + + // Catch cursor selection changes. + this.EditorDocument.attachEvent("onselectionchange", Doc_OnSelectionChange ) ; + + FCKTools.AddEventListener( FCK.EditorDocument, 'mousedown', Doc_OnMouseDown ) ; +} + +FCK.InsertHtml = function( html ) +{ + html = FCKConfig.ProtectedSource.Protect( html ) ; + html = FCK.ProtectEvents( html ) ; + html = FCK.ProtectUrls( html ) ; + html = FCK.ProtectTags( html ) ; + +// FCK.Focus() ; + FCKSelection.Restore() ; + FCK.EditorWindow.focus() ; + + FCKUndo.SaveUndoStep() ; + + // Gets the actual selection. + var oSel = FCKSelection.GetSelection() ; + + // Deletes the actual selection contents. + if ( oSel.type.toLowerCase() == 'control' ) + oSel.clear() ; + + // Using the following trick, any comment in the beginning of the HTML will + // be preserved. + html = '' + html ; + + // Insert the HTML. + oSel.createRange().pasteHTML( html ) ; + + // Remove the fake node + FCK.EditorDocument.getElementById('__fakeFCKRemove__').removeNode( true ) ; + + FCKDocumentProcessor.Process( FCK.EditorDocument ) ; + + // For some strange reason the SaveUndoStep() call doesn't activate the undo button at the first InsertHtml() call. + this.Events.FireEvent( "OnSelectionChange" ) ; +} + +FCK.SetInnerHtml = function( html ) // IE Only +{ + var oDoc = FCK.EditorDocument ; + // Using the following trick, any comment in the beginning of the HTML will + // be preserved. + oDoc.body.innerHTML = '
       
      ' + html ; + oDoc.getElementById('__fakeFCKRemove__').removeNode( true ) ; +} + +function FCK_PreloadImages() +{ + var oPreloader = new FCKImagePreloader() ; + + // Add the configured images. + oPreloader.AddImages( FCKConfig.PreloadImages ) ; + + // Add the skin icons strip. + oPreloader.AddImages( FCKConfig.SkinPath + 'fck_strip.gif' ) ; + + oPreloader.OnComplete = LoadToolbarSetup ; + oPreloader.Start() ; +} + +// Disable the context menu in the editor (outside the editing area). +function Document_OnContextMenu() +{ + return ( event.srcElement._FCKShowContextMenu == true ) ; +} +document.oncontextmenu = Document_OnContextMenu ; + +function FCK_Cleanup() +{ + this.LinkedField = null ; + this.EditorWindow = null ; + this.EditorDocument = null ; +} + +FCK._ExecPaste = function() +{ + // As we call ExecuteNamedCommand('Paste'), it would enter in a loop. So, let's use a semaphore. + if ( FCK._PasteIsRunning ) + return true ; + + if ( FCKConfig.ForcePasteAsPlainText ) + { + FCK.PasteAsPlainText() ; + return false ; + } + + var sHTML = FCK._CheckIsPastingEnabled( true ) ; + + if ( sHTML === false ) + FCKTools.RunFunction( FCKDialog.OpenDialog, FCKDialog, ['FCKDialog_Paste', FCKLang.Paste, 'dialog/fck_paste.html', 400, 330, 'Security'] ) ; + else + { + if ( FCKConfig.AutoDetectPasteFromWord && sHTML.length > 0 ) + { + var re = /<\w[^>]*(( class="?MsoNormal"?)|(="mso-))/gi ; + if ( re.test( sHTML ) ) + { + if ( confirm( FCKLang.PasteWordConfirm ) ) + { + FCK.PasteFromWord() ; + return false ; + } + } + } + + // Instead of inserting the retrieved HTML, let's leave the OS work for us, + // by calling FCK.ExecuteNamedCommand( 'Paste' ). It could give better results. + + // Enable the semaphore to avoid a loop. + FCK._PasteIsRunning = true ; + + FCK.ExecuteNamedCommand( 'Paste' ) ; + + // Removes the semaphore. + delete FCK._PasteIsRunning ; + } + + // Let's always make a custom implementation (return false), otherwise + // the new Keyboard Handler may conflict with this code, and the CTRL+V code + // could result in a simple "V" being pasted. + return false ; +} + +FCK.PasteAsPlainText = function( forceText ) +{ + if ( !FCK._CheckIsPastingEnabled() ) + { + FCKDialog.OpenDialog( 'FCKDialog_Paste', FCKLang.PasteAsText, 'dialog/fck_paste.html', 400, 330, 'PlainText' ) ; + return ; + } + + // Get the data available in the clipboard in text format. + var sText = null ; + if ( ! forceText ) + sText = clipboardData.getData("Text") ; + else + sText = forceText ; + + if ( sText && sText.length > 0 ) + { + // Replace the carriage returns with
      + sText = FCKTools.HTMLEncode( sText ) ; + sText = FCKTools.ProcessLineBreaks( window, FCKConfig, sText ) ; + + var closeTagIndex = sText.search( '

      ' ) ; + var startTagIndex = sText.search( '

      ' ) ; + + if ( ( closeTagIndex != -1 && startTagIndex != -1 && closeTagIndex < startTagIndex ) + || ( closeTagIndex != -1 && startTagIndex == -1 ) ) + { + var prefix = sText.substr( 0, closeTagIndex ) ; + sText = sText.substr( closeTagIndex + 4 ) ; + this.InsertHtml( prefix ) ; + } + + // Insert the resulting data in the editor. + FCKUndo.SaveLocked = true ; + this.InsertHtml( sText ) ; + FCKUndo.SaveLocked = false ; + } +} + +FCK._CheckIsPastingEnabled = function( returnContents ) +{ + // The following seams to be the only reliable way to check is script + // pasting operations are enabled in the security settings of IE6 and IE7. + // It adds a little bit of overhead to the check, but so far that's the + // only way, mainly because of IE7. + + FCK._PasteIsEnabled = false ; + + document.body.attachEvent( 'onpaste', FCK_CheckPasting_Listener ) ; + + // The execCommand in GetClipboardHTML will fire the "onpaste", only if the + // security settings are enabled. + var oReturn = FCK.GetClipboardHTML() ; + + document.body.detachEvent( 'onpaste', FCK_CheckPasting_Listener ) ; + + if ( FCK._PasteIsEnabled ) + { + if ( !returnContents ) + oReturn = true ; + } + else + oReturn = false ; + + delete FCK._PasteIsEnabled ; + + return oReturn ; +} + +function FCK_CheckPasting_Listener() +{ + FCK._PasteIsEnabled = true ; +} + +FCK.GetClipboardHTML = function() +{ + var oDiv = document.getElementById( '___FCKHiddenDiv' ) ; + + if ( !oDiv ) + { + oDiv = document.createElement( 'DIV' ) ; + oDiv.id = '___FCKHiddenDiv' ; + + var oDivStyle = oDiv.style ; + oDivStyle.position = 'absolute' ; + oDivStyle.visibility = oDivStyle.overflow = 'hidden' ; + oDivStyle.width = oDivStyle.height = 1 ; + + document.body.appendChild( oDiv ) ; + } + + oDiv.innerHTML = '' ; + + var oTextRange = document.body.createTextRange() ; + oTextRange.moveToElementText( oDiv ) ; + oTextRange.execCommand( 'Paste' ) ; + + var sData = oDiv.innerHTML ; + oDiv.innerHTML = '' ; + + return sData ; +} + +FCK.CreateLink = function( url, noUndo ) +{ + // Creates the array that will be returned. It contains one or more created links (see #220). + var aCreatedLinks = new Array() ; + + // Remove any existing link in the selection. + FCK.ExecuteNamedCommand( 'Unlink', null, false, !!noUndo ) ; + + if ( url.length > 0 ) + { + // If there are several images, and you try to link each one, all the images get inside the link: + // -> -> due to the call to 'CreateLink' (bug in IE) + if (FCKSelection.GetType() == 'Control') + { + // Create a link + var oLink = this.EditorDocument.createElement( 'A' ) ; + oLink.href = url ; + + // Get the selected object + var oControl = FCKSelection.GetSelectedElement() ; + // Put the link just before the object + oControl.parentNode.insertBefore(oLink, oControl) ; + // Move the object inside the link + oControl.parentNode.removeChild( oControl ) ; + oLink.appendChild( oControl ) ; + + return [ oLink ] ; + } + + // Generate a temporary name for the link. + var sTempUrl = 'javascript:void(0);/*' + ( new Date().getTime() ) + '*/' ; + + // Use the internal "CreateLink" command to create the link. + FCK.ExecuteNamedCommand( 'CreateLink', sTempUrl, false, !!noUndo ) ; + + // Look for the just create link. + var oLinks = this.EditorDocument.links ; + + for ( i = 0 ; i < oLinks.length ; i++ ) + { + var oLink = oLinks[i] ; + + // Check it this a newly created link. + // getAttribute must be used. oLink.url may cause problems with IE7 (#555). + if ( oLink.getAttribute( 'href', 2 ) == sTempUrl ) + { + var sInnerHtml = oLink.innerHTML ; // Save the innerHTML (IE changes it if it is like an URL). + oLink.href = url ; + oLink.innerHTML = sInnerHtml ; // Restore the innerHTML. + + // If the last child is a
      move it outside the link or it + // will be too easy to select this link again #388. + var oLastChild = oLink.lastChild ; + if ( oLastChild && oLastChild.nodeName == 'BR' ) + { + // Move the BR after the link. + FCKDomTools.InsertAfterNode( oLink, oLink.removeChild( oLastChild ) ) ; + } + + aCreatedLinks.push( oLink ) ; + } + } + } + + return aCreatedLinks ; +} + +function _FCK_RemoveDisabledAtt() +{ + this.removeAttribute( 'disabled' ) ; +} + +function Doc_OnMouseDown( evt ) +{ + var e = evt.srcElement ; + + // Radio buttons and checkboxes should not be allowed to be triggered in IE + // in editable mode. Otherwise the whole browser window may be locked by + // the buttons. (#1782) + if ( e.nodeName.IEquals( 'input' ) && e.type.IEquals( ['radio', 'checkbox'] ) && !e.disabled ) + { + e.disabled = true ; + FCKTools.SetTimeout( _FCK_RemoveDisabledAtt, 1, e ) ; + } +} diff -r 3791b2e8e471 -r f5c322ae1c7b wiki/htdocs/applets/FCKeditor/editor/_source/internals/fckbrowserinfo.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wiki/htdocs/applets/FCKeditor/editor/_source/internals/fckbrowserinfo.js Mon Aug 11 13:54:49 2008 +0900 @@ -0,0 +1,61 @@ +/* + * FCKeditor - The text editor for Internet - http://www.fckeditor.net + * Copyright (C) 2003-2008 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 == + * + * Contains browser detection information. + */ + +var s = navigator.userAgent.toLowerCase() ; + +var FCKBrowserInfo = +{ + IsIE : /*@cc_on!@*/false, + IsIE7 : /*@cc_on!@*/false && ( parseInt( s.match( /msie (\d+)/ )[1], 10 ) >= 7 ), + IsIE6 : /*@cc_on!@*/false && ( parseInt( s.match( /msie (\d+)/ )[1], 10 ) >= 6 ), + IsSafari : s.Contains(' applewebkit/'), // Read "IsWebKit" + IsOpera : !!window.opera, + IsAIR : s.Contains(' adobeair/'), + IsMac : s.Contains('macintosh') +} ; + +// Completes the browser info with further Gecko information. +(function( browserInfo ) +{ + browserInfo.IsGecko = ( navigator.product == 'Gecko' ) && !browserInfo.IsSafari && !browserInfo.IsOpera ; + browserInfo.IsGeckoLike = ( browserInfo.IsGecko || browserInfo.IsSafari || browserInfo.IsOpera ) ; + + if ( browserInfo.IsGecko ) + { + var geckoMatch = s.match( /rv:(\d+\.\d+)/ ) ; + var geckoVersion = geckoMatch && parseFloat( geckoMatch[1] ) ; + + // Actually "10" refers to Gecko versions before Firefox 1.5, when + // Gecko 1.8 (build 20051111) has been released. + + // Some browser (like Mozilla 1.7.13) may have a Gecko build greater + // than 20051111, so we must also check for the revision number not to + // be 1.7 (we are assuming that rv < 1.7 will not have build > 20051111). + + if ( geckoVersion ) + { + browserInfo.IsGecko10 = ( geckoVersion < 1.8 ) ; + browserInfo.IsGecko19 = ( geckoVersion > 1.8 ) ; + } + } +})(FCKBrowserInfo) ; diff -r 3791b2e8e471 -r f5c322ae1c7b wiki/htdocs/applets/FCKeditor/editor/_source/internals/fckcodeformatter.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wiki/htdocs/applets/FCKeditor/editor/_source/internals/fckcodeformatter.js Mon Aug 11 13:54:49 2008 +0900 @@ -0,0 +1,100 @@ +/* + * FCKeditor - The text editor for Internet - http://www.fckeditor.net + * Copyright (C) 2003-2008 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 == + * + * Format the HTML. + */ + +var FCKCodeFormatter = new Object() ; + +FCKCodeFormatter.Init = function() +{ + var oRegex = this.Regex = new Object() ; + + // Regex for line breaks. + oRegex.BlocksOpener = /\<(P|DIV|H1|H2|H3|H4|H5|H6|ADDRESS|PRE|OL|UL|LI|TITLE|META|LINK|BASE|SCRIPT|LINK|TD|TH|AREA|OPTION)[^\>]*\>/gi ; + oRegex.BlocksCloser = /\<\/(P|DIV|H1|H2|H3|H4|H5|H6|ADDRESS|PRE|OL|UL|LI|TITLE|META|LINK|BASE|SCRIPT|LINK|TD|TH|AREA|OPTION)[^\>]*\>/gi ; + + oRegex.NewLineTags = /\<(BR|HR)[^\>]*\>/gi ; + + oRegex.MainTags = /\<\/?(HTML|HEAD|BODY|FORM|TABLE|TBODY|THEAD|TR)[^\>]*\>/gi ; + + oRegex.LineSplitter = /\s*\n+\s*/g ; + + // Regex for indentation. + oRegex.IncreaseIndent = /^\<(HTML|HEAD|BODY|FORM|TABLE|TBODY|THEAD|TR|UL|OL)[ \/\>]/i ; + oRegex.DecreaseIndent = /^\<\/(HTML|HEAD|BODY|FORM|TABLE|TBODY|THEAD|TR|UL|OL)[ \>]/i ; + oRegex.FormatIndentatorRemove = new RegExp( '^' + FCKConfig.FormatIndentator ) ; + + oRegex.ProtectedTags = /(]*>)([\s\S]*?)(<\/PRE>)/gi ; +} + +FCKCodeFormatter._ProtectData = function( outer, opener, data, closer ) +{ + return opener + '___FCKpd___' + FCKCodeFormatter.ProtectedData.AddItem( data ) + closer ; +} + +FCKCodeFormatter.Format = function( html ) +{ + if ( !this.Regex ) + this.Init() ; + + // Protected content that remain untouched during the + // process go in the following array. + FCKCodeFormatter.ProtectedData = new Array() ; + + var sFormatted = html.replace( this.Regex.ProtectedTags, FCKCodeFormatter._ProtectData ) ; + + // Line breaks. + sFormatted = sFormatted.replace( this.Regex.BlocksOpener, '\n$&' ) ; + sFormatted = sFormatted.replace( this.Regex.BlocksCloser, '$&\n' ) ; + sFormatted = sFormatted.replace( this.Regex.NewLineTags, '$&\n' ) ; + sFormatted = sFormatted.replace( this.Regex.MainTags, '\n$&\n' ) ; + + // Indentation. + var sIndentation = '' ; + + var asLines = sFormatted.split( this.Regex.LineSplitter ) ; + sFormatted = '' ; + + for ( var i = 0 ; i < asLines.length ; i++ ) + { + var sLine = asLines[i] ; + + if ( sLine.length == 0 ) + continue ; + + if ( this.Regex.DecreaseIndent.test( sLine ) ) + sIndentation = sIndentation.replace( this.Regex.FormatIndentatorRemove, '' ) ; + + sFormatted += sIndentation + sLine + '\n' ; + + if ( this.Regex.IncreaseIndent.test( sLine ) ) + sIndentation += FCKConfig.FormatIndentator ; + } + + // Now we put back the protected data. + for ( var j = 0 ; j < FCKCodeFormatter.ProtectedData.length ; j++ ) + { + var oRegex = new RegExp( '___FCKpd___' + j ) ; + sFormatted = sFormatted.replace( oRegex, FCKCodeFormatter.ProtectedData[j].replace( /\$/g, '$$$$' ) ) ; + } + + return sFormatted.Trim() ; +} diff -r 3791b2e8e471 -r f5c322ae1c7b wiki/htdocs/applets/FCKeditor/editor/_source/internals/fckcommands.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wiki/htdocs/applets/FCKeditor/editor/_source/internals/fckcommands.js Mon Aug 11 13:54:49 2008 +0900 @@ -0,0 +1,172 @@ +/* + * FCKeditor - The text editor for Internet - http://www.fckeditor.net + * Copyright (C) 2003-2008 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 == + * + * Define all commands available in the editor. + */ + +var FCKCommands = FCK.Commands = new Object() ; +FCKCommands.LoadedCommands = new Object() ; + +FCKCommands.RegisterCommand = function( commandName, command ) +{ + this.LoadedCommands[ commandName ] = command ; +} + +FCKCommands.GetCommand = function( commandName ) +{ + var oCommand = FCKCommands.LoadedCommands[ commandName ] ; + + if ( oCommand ) + return oCommand ; + + switch ( commandName ) + { + case 'Bold' : + case 'Italic' : + case 'Underline' : + case 'StrikeThrough': + case 'Subscript' : + case 'Superscript' : oCommand = new FCKCoreStyleCommand( commandName ) ; break ; + + case 'RemoveFormat' : oCommand = new FCKRemoveFormatCommand() ; break ; + + case 'DocProps' : oCommand = new FCKDialogCommand( 'DocProps' , FCKLang.DocProps , 'dialog/fck_docprops.html' , 400, 380, FCKCommands.GetFullPageState ) ; break ; + case 'Templates' : oCommand = new FCKDialogCommand( 'Templates' , FCKLang.DlgTemplatesTitle , 'dialog/fck_template.html' , 380, 450 ) ; break ; + case 'Link' : oCommand = new FCKDialogCommand( 'Link' , FCKLang.DlgLnkWindowTitle , 'dialog/fck_link.html' , 400, 300 ) ; break ; + case 'Unlink' : oCommand = new FCKUnlinkCommand() ; break ; + case 'VisitLink' : oCommand = new FCKVisitLinkCommand() ; break ; + case 'Anchor' : oCommand = new FCKDialogCommand( 'Anchor' , FCKLang.DlgAnchorTitle , 'dialog/fck_anchor.html' , 370, 160 ) ; break ; + case 'AnchorDelete' : oCommand = new FCKAnchorDeleteCommand() ; break ; + case 'BulletedList' : oCommand = new FCKDialogCommand( 'BulletedList', FCKLang.BulletedListProp , 'dialog/fck_listprop.html?UL' , 370, 160 ) ; break ; + case 'NumberedList' : oCommand = new FCKDialogCommand( 'NumberedList', FCKLang.NumberedListProp , 'dialog/fck_listprop.html?OL' , 370, 160 ) ; break ; + case 'About' : oCommand = new FCKDialogCommand( 'About' , FCKLang.About , 'dialog/fck_about.html' , 420, 330, function(){ return FCK_TRISTATE_OFF ; } ) ; break ; + case 'Find' : oCommand = new FCKDialogCommand( 'Find' , FCKLang.DlgFindAndReplaceTitle, 'dialog/fck_replace.html' , 340, 230, null, null, 'Find' ) ; break ; + case 'Replace' : oCommand = new FCKDialogCommand( 'Replace' , FCKLang.DlgFindAndReplaceTitle, 'dialog/fck_replace.html' , 340, 230, null, null, 'Replace' ) ; break ; + + case 'Image' : oCommand = new FCKDialogCommand( 'Image' , FCKLang.DlgImgTitle , 'dialog/fck_image.html' , 450, 390 ) ; break ; + case 'Flash' : oCommand = new FCKDialogCommand( 'Flash' , FCKLang.DlgFlashTitle , 'dialog/fck_flash.html' , 450, 390 ) ; break ; + case 'SpecialChar' : oCommand = new FCKDialogCommand( 'SpecialChar', FCKLang.DlgSpecialCharTitle , 'dialog/fck_specialchar.html' , 400, 290 ) ; break ; + case 'Smiley' : oCommand = new FCKDialogCommand( 'Smiley' , FCKLang.DlgSmileyTitle , 'dialog/fck_smiley.html' , FCKConfig.SmileyWindowWidth, FCKConfig.SmileyWindowHeight ) ; break ; + case 'Table' : oCommand = new FCKDialogCommand( 'Table' , FCKLang.DlgTableTitle , 'dialog/fck_table.html' , 480, 250 ) ; break ; + case 'TableProp' : oCommand = new FCKDialogCommand( 'Table' , FCKLang.DlgTableTitle , 'dialog/fck_table.html?Parent', 480, 250 ) ; break ; + case 'TableCellProp': oCommand = new FCKDialogCommand( 'TableCell' , FCKLang.DlgCellTitle , 'dialog/fck_tablecell.html' , 550, 240 ) ; break ; + + case 'Style' : oCommand = new FCKStyleCommand() ; break ; + + case 'FontName' : oCommand = new FCKFontNameCommand() ; break ; + case 'FontSize' : oCommand = new FCKFontSizeCommand() ; break ; + case 'FontFormat' : oCommand = new FCKFormatBlockCommand() ; break ; + + case 'Source' : oCommand = new FCKSourceCommand() ; break ; + case 'Preview' : oCommand = new FCKPreviewCommand() ; break ; + case 'Save' : oCommand = new FCKSaveCommand() ; break ; + case 'NewPage' : oCommand = new FCKNewPageCommand() ; break ; + case 'PageBreak' : oCommand = new FCKPageBreakCommand() ; break ; + case 'Rule' : oCommand = new FCKRuleCommand() ; break ; + case 'Nbsp' : oCommand = new FCKNbsp() ; break ; + + case 'TextColor' : oCommand = new FCKTextColorCommand('ForeColor') ; break ; + case 'BGColor' : oCommand = new FCKTextColorCommand('BackColor') ; break ; + + case 'Paste' : oCommand = new FCKPasteCommand() ; break ; + case 'PasteText' : oCommand = new FCKPastePlainTextCommand() ; break ; + case 'PasteWord' : oCommand = new FCKPasteWordCommand() ; break ; + + case 'JustifyLeft' : oCommand = new FCKJustifyCommand( 'left' ) ; break ; + case 'JustifyCenter' : oCommand = new FCKJustifyCommand( 'center' ) ; break ; + case 'JustifyRight' : oCommand = new FCKJustifyCommand( 'right' ) ; break ; + case 'JustifyFull' : oCommand = new FCKJustifyCommand( 'justify' ) ; break ; + case 'Indent' : oCommand = new FCKIndentCommand( 'indent', FCKConfig.IndentLength ) ; break ; + case 'Outdent' : oCommand = new FCKIndentCommand( 'outdent', FCKConfig.IndentLength * -1 ) ; break ; + case 'Blockquote' : oCommand = new FCKBlockQuoteCommand() ; break ; + case 'CreateDiv' : oCommand = new FCKDialogCommand( 'CreateDiv', FCKLang.CreateDiv, 'dialog/fck_div.html', 380, 210, null, null, true ) ; break ; + case 'EditDiv' : oCommand = new FCKDialogCommand( 'EditDiv', FCKLang.EditDiv, 'dialog/fck_div.html', 380, 210, null, null, false ) ; break ; + case 'DeleteDiv' : oCommand = new FCKDeleteDivCommand() ; break ; + + case 'TableInsertRowAfter' : oCommand = new FCKTableCommand('TableInsertRowAfter') ; break ; + case 'TableInsertRowBefore' : oCommand = new FCKTableCommand('TableInsertRowBefore') ; break ; + case 'TableDeleteRows' : oCommand = new FCKTableCommand('TableDeleteRows') ; break ; + case 'TableInsertColumnAfter' : oCommand = new FCKTableCommand('TableInsertColumnAfter') ; break ; + case 'TableInsertColumnBefore' : oCommand = new FCKTableCommand('TableInsertColumnBefore') ; break ; + case 'TableDeleteColumns' : oCommand = new FCKTableCommand('TableDeleteColumns') ; break ; + case 'TableInsertCellAfter' : oCommand = new FCKTableCommand('TableInsertCellAfter') ; break ; + case 'TableInsertCellBefore' : oCommand = new FCKTableCommand('TableInsertCellBefore') ; break ; + case 'TableDeleteCells' : oCommand = new FCKTableCommand('TableDeleteCells') ; break ; + case 'TableMergeCells' : oCommand = new FCKTableCommand('TableMergeCells') ; break ; + case 'TableMergeRight' : oCommand = new FCKTableCommand('TableMergeRight') ; break ; + case 'TableMergeDown' : oCommand = new FCKTableCommand('TableMergeDown') ; break ; + case 'TableHorizontalSplitCell' : oCommand = new FCKTableCommand('TableHorizontalSplitCell') ; break ; + case 'TableVerticalSplitCell' : oCommand = new FCKTableCommand('TableVerticalSplitCell') ; break ; + case 'TableDelete' : oCommand = new FCKTableCommand('TableDelete') ; break ; + + case 'Form' : oCommand = new FCKDialogCommand( 'Form' , FCKLang.Form , 'dialog/fck_form.html' , 380, 210 ) ; break ; + case 'Checkbox' : oCommand = new FCKDialogCommand( 'Checkbox' , FCKLang.Checkbox , 'dialog/fck_checkbox.html' , 380, 200 ) ; break ; + case 'Radio' : oCommand = new FCKDialogCommand( 'Radio' , FCKLang.RadioButton , 'dialog/fck_radiobutton.html' , 380, 200 ) ; break ; + case 'TextField' : oCommand = new FCKDialogCommand( 'TextField' , FCKLang.TextField , 'dialog/fck_textfield.html' , 380, 210 ) ; break ; + case 'Textarea' : oCommand = new FCKDialogCommand( 'Textarea' , FCKLang.Textarea , 'dialog/fck_textarea.html' , 380, 210 ) ; break ; + case 'HiddenField' : oCommand = new FCKDialogCommand( 'HiddenField', FCKLang.HiddenField , 'dialog/fck_hiddenfield.html' , 380, 190 ) ; break ; + case 'Button' : oCommand = new FCKDialogCommand( 'Button' , FCKLang.Button , 'dialog/fck_button.html' , 380, 210 ) ; break ; + case 'Select' : oCommand = new FCKDialogCommand( 'Select' , FCKLang.SelectionField, 'dialog/fck_select.html' , 400, 340 ) ; break ; + case 'ImageButton' : oCommand = new FCKDialogCommand( 'ImageButton', FCKLang.ImageButton , 'dialog/fck_image.html?ImageButton', 450, 390 ) ; break ; + + case 'SpellCheck' : oCommand = new FCKSpellCheckCommand() ; break ; + case 'FitWindow' : oCommand = new FCKFitWindow() ; break ; + + case 'Undo' : oCommand = new FCKUndoCommand() ; break ; + case 'Redo' : oCommand = new FCKRedoCommand() ; break ; + case 'Copy' : oCommand = new FCKCutCopyCommand( false ) ; break ; + case 'Cut' : oCommand = new FCKCutCopyCommand( true ) ; break ; + + case 'SelectAll' : oCommand = new FCKSelectAllCommand() ; break ; + case 'InsertOrderedList' : oCommand = new FCKListCommand( 'insertorderedlist', 'ol' ) ; break ; + case 'InsertUnorderedList' : oCommand = new FCKListCommand( 'insertunorderedlist', 'ul' ) ; break ; + case 'ShowBlocks' : oCommand = new FCKShowBlockCommand( 'ShowBlocks', FCKConfig.StartupShowBlocks ? FCK_TRISTATE_ON : FCK_TRISTATE_OFF ) ; break ; + + // Generic Undefined command (usually used when a command is under development). + case 'Undefined' : oCommand = new FCKUndefinedCommand() ; break ; + + // By default we assume that it is a named command. + default: + if ( FCKRegexLib.NamedCommands.test( commandName ) ) + oCommand = new FCKNamedCommand( commandName ) ; + else + { + alert( FCKLang.UnknownCommand.replace( /%1/g, commandName ) ) ; + return null ; + } + } + + FCKCommands.LoadedCommands[ commandName ] = oCommand ; + + return oCommand ; +} + +// Gets the state of the "Document Properties" button. It must be enabled only +// when "Full Page" editing is available. +FCKCommands.GetFullPageState = function() +{ + return FCKConfig.FullPage ? FCK_TRISTATE_OFF : FCK_TRISTATE_DISABLED ; +} + + +FCKCommands.GetBooleanState = function( isDisabled ) +{ + return isDisabled ? FCK_TRISTATE_DISABLED : FCK_TRISTATE_OFF ; +} diff -r 3791b2e8e471 -r f5c322ae1c7b wiki/htdocs/applets/FCKeditor/editor/_source/internals/fckconfig.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wiki/htdocs/applets/FCKeditor/editor/_source/internals/fckconfig.js Mon Aug 11 13:54:49 2008 +0900 @@ -0,0 +1,237 @@ +/* + * FCKeditor - The text editor for Internet - http://www.fckeditor.net + * Copyright (C) 2003-2008 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 == + * + * Creates and initializes the FCKConfig object. + */ + +var FCKConfig = FCK.Config = new Object() ; + +/* + For the next major version (probably 3.0) we should move all this stuff to + another dedicated object and leave FCKConfig as a holder object for settings only). +*/ + +// Editor Base Path +if ( document.location.protocol == 'file:' ) +{ + FCKConfig.BasePath = decodeURIComponent( document.location.pathname.substr(1) ) ; + FCKConfig.BasePath = FCKConfig.BasePath.replace( /\\/gi, '/' ) ; + + // The way to address local files is different according to the OS. + // In Windows it is file:// but in MacOs it is file:/// so let's get it automatically + var sFullProtocol = document.location.href.match( /^(file\:\/{2,3})/ )[1] ; + // #945 Opera does strange things with files loaded from the disk, and it fails in Mac to load xml files + if ( FCKBrowserInfo.IsOpera ) + sFullProtocol += 'localhost/' ; + + FCKConfig.BasePath = sFullProtocol + FCKConfig.BasePath.substring( 0, FCKConfig.BasePath.lastIndexOf( '/' ) + 1) ; +} +else + FCKConfig.BasePath = document.location.protocol + '//' + document.location.host + + document.location.pathname.substring( 0, document.location.pathname.lastIndexOf( '/' ) + 1) ; + +FCKConfig.FullBasePath = FCKConfig.BasePath ; + +FCKConfig.EditorPath = FCKConfig.BasePath.replace( /editor\/$/, '' ) ; + +// There is a bug in Gecko. If the editor is hidden on startup, an error is +// thrown when trying to get the screen dimensions. +try +{ + FCKConfig.ScreenWidth = screen.width ; + FCKConfig.ScreenHeight = screen.height ; +} +catch (e) +{ + FCKConfig.ScreenWidth = 800 ; + FCKConfig.ScreenHeight = 600 ; +} + +// Override the actual configuration values with the values passed throw the +// hidden field "___Config". +FCKConfig.ProcessHiddenField = function() +{ + this.PageConfig = new Object() ; + + // Get the hidden field. + var oConfigField = window.parent.document.getElementById( FCK.Name + '___Config' ) ; + + // Do nothing if the config field was not defined. + if ( ! oConfigField ) return ; + + var aCouples = oConfigField.value.split('&') ; + + for ( var i = 0 ; i < aCouples.length ; i++ ) + { + if ( aCouples[i].length == 0 ) + continue ; + + var aConfig = aCouples[i].split( '=' ) ; + var sKey = decodeURIComponent( aConfig[0] ) ; + var sVal = decodeURIComponent( aConfig[1] ) ; + + if ( sKey == 'CustomConfigurationsPath' ) // The Custom Config File path must be loaded immediately. + FCKConfig[ sKey ] = sVal ; + + else if ( sVal.toLowerCase() == "true" ) // If it is a boolean TRUE. + this.PageConfig[ sKey ] = true ; + + else if ( sVal.toLowerCase() == "false" ) // If it is a boolean FALSE. + this.PageConfig[ sKey ] = false ; + + else if ( sVal.length > 0 && !isNaN( sVal ) ) // If it is a number. + this.PageConfig[ sKey ] = parseInt( sVal, 10 ) ; + + else // In any other case it is a string. + this.PageConfig[ sKey ] = sVal ; + } +} + +function FCKConfig_LoadPageConfig() +{ + var oPageConfig = FCKConfig.PageConfig ; + for ( var sKey in oPageConfig ) + FCKConfig[ sKey ] = oPageConfig[ sKey ] ; +} + +function FCKConfig_PreProcess() +{ + var oConfig = FCKConfig ; + + // Force debug mode if fckdebug=true in the QueryString (main page). + if ( oConfig.AllowQueryStringDebug ) + { + try + { + if ( (/fckdebug=true/i).test( window.top.location.search ) ) + oConfig.Debug = true ; + } + catch (e) { /* Ignore it. Much probably we are inside a FRAME where the "top" is in another domain (security error). */ } + } + + // Certifies that the "PluginsPath" configuration ends with a slash. + if ( !oConfig.PluginsPath.EndsWith('/') ) + oConfig.PluginsPath += '/' ; + + // If no ToolbarComboPreviewCSS, point it to EditorAreaCSS. + var sComboPreviewCSS = oConfig.ToolbarComboPreviewCSS ; + if ( !sComboPreviewCSS || sComboPreviewCSS.length == 0 ) + oConfig.ToolbarComboPreviewCSS = oConfig.EditorAreaCSS ; + + // Turn the attributes that will be removed in the RemoveFormat from a string to an array + oConfig.RemoveAttributesArray = (oConfig.RemoveAttributes || '').split( ',' ); + + if ( !FCKConfig.SkinEditorCSS || FCKConfig.SkinEditorCSS.length == 0 ) + FCKConfig.SkinEditorCSS = FCKConfig.SkinPath + 'fck_editor.css' ; + + if ( !FCKConfig.SkinDialogCSS || FCKConfig.SkinDialogCSS.length == 0 ) + FCKConfig.SkinDialogCSS = FCKConfig.SkinPath + 'fck_dialog.css' ; +} + +// Define toolbar sets collection. +FCKConfig.ToolbarSets = new Object() ; + +// Defines the plugins collection. +FCKConfig.Plugins = new Object() ; +FCKConfig.Plugins.Items = new Array() ; + +FCKConfig.Plugins.Add = function( name, langs, path ) +{ + FCKConfig.Plugins.Items.AddItem( [name, langs, path] ) ; +} + +// FCKConfig.ProtectedSource: object that holds a collection of Regular +// Expressions that defined parts of the raw HTML that must remain untouched +// like custom tags, scripts, server side code, etc... +FCKConfig.ProtectedSource = new Object() ; + +// Generates a string used to identify and locate the Protected Tags comments. +FCKConfig.ProtectedSource._CodeTag = (new Date()).valueOf() ; + +// Initialize the regex array with the default ones. +FCKConfig.ProtectedSource.RegexEntries = [ + // First of any other protection, we must protect all comments to avoid + // loosing them (of course, IE related). + //g , + + // Script tags will also be forced to be protected, otherwise IE will execute them. + //gi, + + //