text: ﻿/*
   * 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 the FCKToolbarSet object that is used to load and draw the
   * toolbar.
   */
  
  function FCKToolbarSet_Create( overhideLocation )
  {
  	var oToolbarSet ;
  
  	var sLocation = overhideLocation || FCKConfig.ToolbarLocation ;
  	switch ( sLocation )
  	{
  		case 'In' :
  			document.getElementById( 'xToolbarRow' ).style.display = '' ;
  			oToolbarSet = new FCKToolbarSet( document ) ;
  			break ;
  		case 'None' :
  			oToolbarSet = new FCKToolbarSet( document ) ;
  			break ;
  
  //		case 'OutTop' :
  			// Not supported.
  
  		default :
  			FCK.Events.AttachEvent( 'OnBlur', FCK_OnBlur ) ;
  			FCK.Events.AttachEvent( 'OnFocus', FCK_OnFocus ) ;
  
  			var eToolbarTarget ;
  
  			// Out:[TargetWindow]([TargetId])
  			var oOutMatch = sLocation.match( /^Out:(.+)\((\w+)\)$/ ) ;
  			if ( oOutMatch )
  			{
  				if ( FCKBrowserInfo.IsAIR )
  					FCKAdobeAIR.ToolbarSet_GetOutElement( window, oOutMatch ) ;
  				else
  					eToolbarTarget = eval( 'parent.' + oOutMatch[1] ).document.getElementById( oOutMatch[2] ) ;
  			}
  			else
  			{
  				// Out:[TargetId]
  				oOutMatch = sLocation.match( /^Out:(\w+)$/ ) ;
  				if ( oOutMatch )
  					eToolbarTarget = parent.document.getElementById( oOutMatch[1] ) ;
  			}
  
  			if ( !eToolbarTarget )
  			{
  				alert( 'Invalid value for "ToolbarLocation"' ) ;
  				return arguments.callee( 'In' );
  			}
  
  			// If it is a shared toolbar, it may be already available in the target element.
  			oToolbarSet = eToolbarTarget.__FCKToolbarSet ;
  			if ( oToolbarSet )
  				break ;
  
  			// Create the IFRAME that will hold the toolbar inside the target element.
  			var eToolbarIFrame = FCKTools.GetElementDocument( eToolbarTarget ).createElement( 'iframe' ) ;
  			eToolbarIFrame.src = 'javascript:void(0)' ;
  			eToolbarIFrame.frameBorder = 0 ;
  			eToolbarIFrame.width = '100%' ;
  			eToolbarIFrame.height = '10' ;
  			eToolbarTarget.appendChild( eToolbarIFrame ) ;
  			eToolbarIFrame.unselectable = 'on' ;
  
  			// Write the basic HTML for the toolbar (copy from the editor main page).
  			var eTargetDocument = eToolbarIFrame.contentWindow.document ;
  
  			// Workaround for Safari 12256. Ticket #63
  			var sBase = '' ;
  			if ( FCKBrowserInfo.IsSafari )
  				sBase = '<base href="' + window.document.location + '">' ;
  
  			// Initialize the IFRAME document body.
  			eTargetDocument.open() ;
  			eTargetDocument.write( '<html><head>' + sBase + '<script type="text/javascript"> var adjust = function() { window.frameElement.height = document.body.scrollHeight ; }; '
  					+ 'window.onresize = window.onload = '
  					+ 'function(){'		// poll scrollHeight until it no longer changes for 1 sec.
  					+ 'var timer = null;'
  					+ 'var lastHeight = -1;'
  					+ 'var lastChange = 0;'
  					+ 'var poller = function(){'
  					+ 'var currentHeight = document.body.scrollHeight || 0;'
  					+ 'var currentTime = (new Date()).getTime();'
  					+ 'if (currentHeight != lastHeight){'
  					+ 'lastChange = currentTime;'
  					+ 'adjust();'
  					+ 'lastHeight = document.body.scrollHeight;'
  					+ '}'
  					+ 'if (lastChange < currentTime - 1000) clearInterval(timer);'
  					+ '};'
  					+ 'timer = setInterval(poller, 100);'
  					+ '}'
  					+ '</script></head><body style="overflow: hidden">' + document.getElementById( 'xToolbarSpace' ).innerHTML + '</body></html>' ) ;
  			eTargetDocument.close() ;
  
  			if( FCKBrowserInfo.IsAIR )
  				FCKAdobeAIR.ToolbarSet_InitOutFrame( eTargetDocument ) ;
  
  			FCKTools.AddEventListener( eTargetDocument, 'contextmenu', FCKTools.CancelEvent ) ;
  
  			// Load external resources (must be done here, otherwise Firefox will not
  			// have the document DOM ready to be used right away.
  			FCKTools.AppendStyleSheet( eTargetDocument, FCKConfig.SkinEditorCSS ) ;
  
  			oToolbarSet = eToolbarTarget.__FCKToolbarSet = new FCKToolbarSet( eTargetDocument ) ;
  			oToolbarSet._IFrame = eToolbarIFrame ;
  
  			if ( FCK.IECleanup )
  				FCK.IECleanup.AddItem( eToolbarTarget, FCKToolbarSet_Target_Cleanup ) ;
  	}
  
  	oToolbarSet.CurrentInstance = FCK ;
  	if ( !oToolbarSet.ToolbarItems )
  		oToolbarSet.ToolbarItems = FCKToolbarItems ;
  
  	FCK.AttachToOnSelectionChange( oToolbarSet.RefreshItemsState ) ;
  
  	return oToolbarSet ;
  }
  
  function FCK_OnBlur( editorInstance )
  {
  	var eToolbarSet = editorInstance.ToolbarSet ;
  
  	if ( eToolbarSet.CurrentInstance == editorInstance )
  		eToolbarSet.Disable() ;
  }
  
  function FCK_OnFocus( editorInstance )
  {
  	var oToolbarset = editorInstance.ToolbarSet ;
  	var oInstance = editorInstance || FCK ;
  
  	// Unregister the toolbar window from the current instance.
  	oToolbarset.CurrentInstance.FocusManager.RemoveWindow( oToolbarset._IFrame.contentWindow ) ;
  
  	// Set the new current instance.
  	oToolbarset.CurrentInstance = oInstance ;
  
  	// Register the toolbar window in the current instance.
  	oInstance.FocusManager.AddWindow( oToolbarset._IFrame.contentWindow, true ) ;
  
  	oToolbarset.Enable() ;
  }
  
  function FCKToolbarSet_Cleanup()
  {
  	this._TargetElement = null ;
  	this._IFrame = null ;
  }
  
  function FCKToolbarSet_Target_Cleanup()
  {
  	this.__FCKToolbarSet = null ;
  }
  
  var FCKToolbarSet = function( targetDocument )
  {
  	this._Document = targetDocument ;
  
  	// Get the element that will hold the elements structure.
  	this._TargetElement	= targetDocument.getElementById( 'xToolbar' ) ;
  
  	// Setup the expand and collapse handlers.
  	var eExpandHandle	= targetDocument.getElementById( 'xExpandHandle' ) ;
  	var eCollapseHandle	= targetDocument.getElementById( 'xCollapseHandle' ) ;
  
  	eExpandHandle.title		= FCKLang.ToolbarExpand ;
  	FCKTools.AddEventListener( eExpandHandle, 'click', FCKToolbarSet_Expand_OnClick ) ;
  
  	eCollapseHandle.title	= FCKLang.ToolbarCollapse ;
  	FCKTools.AddEventListener( eCollapseHandle, 'click', FCKToolbarSet_Collapse_OnClick ) ;
  
  	// Set the toolbar state at startup.
  	if ( !FCKConfig.ToolbarCanCollapse || FCKConfig.ToolbarStartExpanded )
  		this.Expand() ;
  	else
  		this.Collapse() ;
  
  	// Enable/disable the collapse handler
  	eCollapseHandle.style.display = FCKConfig.ToolbarCanCollapse ? '' : 'none' ;
  
  	if ( FCKConfig.ToolbarCanCollapse )
  		eCollapseHandle.style.display = '' ;
  	else
  		targetDocument.getElementById( 'xTBLeftBorder' ).style.display = '' ;
  
  	// Set the default properties.
  	this.Toolbars = new Array() ;
  	this.IsLoaded = false ;
  
  	if ( FCK.IECleanup )
  		FCK.IECleanup.AddItem( this, FCKToolbarSet_Cleanup ) ;
  }
  
  function FCKToolbarSet_Expand_OnClick()
  {
  	FCK.ToolbarSet.Expand() ;
  }
  
  function FCKToolbarSet_Collapse_OnClick()
  {
  	FCK.ToolbarSet.Collapse() ;
  }
  
  FCKToolbarSet.prototype.Expand = function()
  {
  	this._ChangeVisibility( false ) ;
  }
  
  FCKToolbarSet.prototype.Collapse = function()
  {
  	this._ChangeVisibility( true ) ;
  }
  
  FCKToolbarSet.prototype._ChangeVisibility = function( collapse )
  {
  	this._Document.getElementById( 'xCollapsed' ).style.display = collapse ? '' : 'none' ;
  	this._Document.getElementById( 'xExpanded' ).style.display = collapse ? 'none' : '' ;
  
  	if ( FCKBrowserInfo.IsGecko )
  	{
  		// I had to use "setTimeout" because Gecko was not responding in a right
  		// way when calling window.onresize() directly.
  		FCKTools.RunFunction( window.onresize ) ;
  	}
  }
  
  FCKToolbarSet.prototype.Load = function( toolbarSetName )
  {
  	this.Name = toolbarSetName ;
  
  	this.Items = new Array() ;
  
  	// Reset the array of toolbar items that are active only on WYSIWYG mode.
  	this.ItemsWysiwygOnly = new Array() ;
  
  	// Reset the array of toolbar items that are sensitive to the cursor position.
  	this.ItemsContextSensitive = new Array() ;
  
  	// Cleanup the target element.
  	this._TargetElement.innerHTML = '' ;
  
  	var ToolbarSet = FCKConfig.ToolbarSets[toolbarSetName] ;
  
  	if ( !ToolbarSet )
  	{
  		alert( FCKLang.UnknownToolbarSet.replace( /%1/g, toolbarSetName ) ) ;
  		return ;
  	}
  
  	this.Toolbars = new Array() ;
  
  	for ( var x = 0 ; x < ToolbarSet.length ; x++ )
  	{
  		var oToolbarItems = ToolbarSet[x] ;
  
  		// If the configuration for the toolbar is missing some element or has any extra comma
  		// this item won't be valid, so skip it and keep on processing.
  		if ( !oToolbarItems )
  			continue ;
  
  		var oToolbar ;
  
  		if ( typeof( oToolbarItems ) == 'string' )
  		{
  			if ( oToolbarItems == '/' )
  				oToolbar = new FCKToolbarBreak() ;
  		}
  		else
  		{
  			oToolbar = new FCKToolbar() ;
  
  			for ( var j = 0 ; j < oToolbarItems.length ; j++ )
  			{
  				var sItem = oToolbarItems[j] ;
  
  				if ( sItem == '-')
  					oToolbar.AddSeparator() ;
  				else
  				{
  					var oItem = FCKToolbarItems.GetItem( sItem ) ;
  					if ( oItem )
  					{
  						oToolbar.AddItem( oItem ) ;
  
  						this.Items.push( oItem ) ;
  
  						if ( !oItem.SourceView )
  							this.ItemsWysiwygOnly.push( oItem ) ;
  
  						if ( oItem.ContextSensitive )
  							this.ItemsContextSensitive.push( oItem ) ;
  					}
  				}
  			}
  
  			// oToolbar.AddTerminator() ;
  		}
  
  		oToolbar.Create( this._TargetElement ) ;
  
  		this.Toolbars[ this.Toolbars.length ] = oToolbar ;
  	}
  
  	FCKTools.DisableSelection( this._Document.getElementById( 'xCollapseHandle' ).parentNode ) ;
  
  	if ( FCK.Status != FCK_STATUS_COMPLETE )
  		FCK.Events.AttachEvent( 'OnStatusChange', this.RefreshModeState ) ;
  	else
  		this.RefreshModeState() ;
  
  	this.IsLoaded = true ;
  	this.IsEnabled = true ;
  
  	FCKTools.RunFunction( this.OnLoad ) ;
  }
  
  FCKToolbarSet.prototype.Enable = function()
  {
  	if ( this.IsEnabled )
  		return ;
  
  	this.IsEnabled = true ;
  
  	var aItems = this.Items ;
  	for ( var i = 0 ; i < aItems.length ; i++ )
  		aItems[i].RefreshState() ;
  }
  
  FCKToolbarSet.prototype.Disable = function()
  {
  	if ( !this.IsEnabled )
  		return ;
  
  	this.IsEnabled = false ;
  
  	var aItems = this.Items ;
  	for ( var i = 0 ; i < aItems.length ; i++ )
  		aItems[i].Disable() ;
  }
  
  FCKToolbarSet.prototype.RefreshModeState = function( editorInstance )
  {
  	if ( FCK.Status != FCK_STATUS_COMPLETE )
  		return ;
  
  	var oToolbarSet = editorInstance ? editorInstance.ToolbarSet : this ;
  	var aItems = oToolbarSet.ItemsWysiwygOnly ;
  
  	if ( FCK.EditMode == FCK_EDITMODE_WYSIWYG )
  	{
  		// Enable all buttons that are available on WYSIWYG mode only.
  		for ( var i = 0 ; i < aItems.length ; i++ )
  			aItems[i].Enable() ;
  
  		// Refresh the buttons state.
  		oToolbarSet.RefreshItemsState( editorInstance ) ;
  	}
  	else
  	{
  		// Refresh the buttons state.
  		oToolbarSet.RefreshItemsState( editorInstance ) ;
  
  		// Disable all buttons that are available on WYSIWYG mode only.
  		for ( var j = 0 ; j < aItems.length ; j++ )
  			aItems[j].Disable() ;
  	}
  }
  
  FCKToolbarSet.prototype.RefreshItemsState = function( editorInstance )
  {
  
  	var aItems = ( editorInstance ? editorInstance.ToolbarSet : this ).ItemsContextSensitive ;
  
  	for ( var i = 0 ; i < aItems.length ; i++ )
  		aItems[i].RefreshState() ;
  }
  