Index: /FCKeditor/branches/developers/mjk/editor/plugins/fckplugin.js
===================================================================
--- /FCKeditor/branches/developers/mjk/editor/plugins/fckplugin.js	(revision 275)
+++ /FCKeditor/branches/developers/mjk/editor/plugins/fckplugin.js	(revision 275)
@@ -0,0 +1,209 @@
+﻿/*
+ * AutoStyle - automatic CSS handling
+ * (c) 2007 Martin Knowles
+ *
+ * == 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 ==
+ *
+ * AutoStyle replaces the built-in Style/Format dropdowns with a single
+ * dropdown that lets you choose both format and style. It's context-aware
+ * (i.e. global styles show as well as styles that only apply to the
+ * particular tag) and, as much as it can, lets you live-preview the
+ * style right in the dropdown, just like the built-in Style/Format
+ * comboboxes do.
+ */
+
+var FCKAutoStyleCommand = function()
+{
+}
+
+FCKAutoStyleCommand.prototype.Execute = function( strItemText, strItemLabel  )
+{
+	if ( strItemText.substr(0,1) == '.' )
+	{
+		var strClass = strItemText.substr(1);
+		if ( this.styledElem )
+			this.styledElem.className = strClass;
+		else
+		{
+			var oElem = FCK.Selection.GetParentElement();
+			if ( FCKSelection.GetType() != 'None' )
+			{
+				var strHTML = FCK.Selection.SelectedHTML();
+				FCK.Selection.Delete();
+				FCK.InsertHtml( '<SPAN CLASS="' + strClass + '">' + strHTML + '</SPAN>' );
+			}
+			else
+				oElem.className = strClass;
+		}
+	}
+	else
+	{
+		FCK.ExecuteNamedCommand( 'FormatBlock','<' + strItemText + '>' );
+		var oElem = FCK.Selection.GetParentElement();
+		if ( oElem )
+		{
+			oElem.className = "";
+			oElem.removeAttribute( "class" );
+		}
+	}
+	//force the control to update itself
+	FCK.Events.FireEvent( 'OnSelectionChange' );
+}
+
+FCKAutoStyleCommand.prototype.GetState = function()
+{
+	return;
+}
+
+FCKCommands.RegisterCommand(  'AutoStyleCommand' , new FCKAutoStyleCommand()  ) ; 
+
+var FCKAutoStyleToolbar = function(  tooltip, style  )
+{
+	this.CommandName = 'AutoStyleCommand' ;
+	this.Label = this.Tooltip = "Styles";
+	this.Style		= style ? style : FCK_TOOLBARITEM_ICONTEXT ;
+	this.NormalLabel = '( none )' ;	
+	this.PanelWidth = 190 ;
+	this.FieldWidth = 190;
+}
+
+FCKAutoStyleToolbar.prototype = new FCKToolbarSpecialCombo ;
+
+FCKAutoStyleToolbar.prototype.GetLabel = function()
+{
+	return;
+}
+
+
+// figure out what to put in the combobox text
+FCKAutoStyleToolbar.prototype._getLabelText = function()
+{
+	var strBF = FCK.GetBlockFormat();
+	if ( !strBF || strBF.search(/none/i) > -1 ) strBF = '';
+	var strStyle = this._getCurrentStyle();
+	if ( strBF && strStyle) return (strBF + " + " + strStyle );
+	if ( !strBF && strStyle ) return strStyle;
+	else return strBF;
+}
+
+FCKAutoStyleToolbar.prototype._getCurrentStyle = function()
+{
+	var strStyle;
+	var oElem = FCK.Selection.GetParentElement();
+	this.styledElem = null;
+	while ( !strStyle && oElem )
+	{
+		strStyle = oElem.className;
+		if ( strStyle.search(/FCK_/) > -1 ) strStyle = null;
+		oElem = oElem.parentElement;
+	}
+	this.styledElem = oElem;
+	return strStyle;
+}
+
+FCKAutoStyleToolbar.prototype.PopulateCombo = function(  targetSpecialCombo  )
+{
+	targetSpecialCombo.DeselectAll() ;
+	targetSpecialCombo.ClearItems();
+	var oTargetDoc = targetSpecialCombo._Panel.Document ;
+	var aCSSs = FCKConfig.EditorAreaCSS ;
+	for (  var i = 0 ; i < aCSSs.length ; i++  ){
+		FCKTools.AppendStyleSheet(  oTargetDoc, aCSSs[i]  ) ;
+	}
+	targetSpecialCombo.owner._addLocalStyles();
+	targetSpecialCombo.owner._addDefaultItems();
+}
+
+FCKAutoStyleToolbar.prototype.RefreshActiveItems = function(  targetSpecialCombo  )
+{
+	// Clear the actual selection. Only draw the label here -- the dropdown
+	// gets drawn on demand (for speed, and to keep us from hosing if we try
+	// to init the format item before the DOM is ready for us)
+	
+	targetSpecialCombo.DeselectAll() ;
+	targetSpecialCombo.ClearItems();
+		
+	targetSpecialCombo.SetLabel( this._getLabelText() );
+}
+
+//create default items. only create the defaults on startup because for large
+//documents in IE, the css might not be present -- so parse it on first use
+FCKAutoStyleToolbar.prototype.CreateItems = function(  targetSpecialCombo  )
+{
+	//populate the combobox only when the user asks for it
+	this._Combo.OnBeforeClick = this.PopulateCombo;
+	this._Combo.owner = this;
+
+}
+
+FCKAutoStyleToolbar.prototype._addLocalStyles = function()
+{
+	var oElem = FCK.Selection.GetParentElement();
+	var strStyle = this._getCurrentStyle();
+	var aTags = new Array();
+	var oEx = oElem;
+	while ( oEx )
+	{
+		aTags.push( oEx.tagName.toUpperCase() );
+		oEx = oEx.tagName.toUpperCase() == 'BODY' ? null : oEx.parentNode;
+	}
+	var oComboCSS = this._Combo._Panel.Document.styleSheets[0];
+	for ( var nss = 0; nss < FCK.EditorDocument.styleSheets.length; nss++ )
+	{
+		var aRules = (FCK.EditorDocument.styleSheets[nss].cssRules ?
+					  FCK.EditorDocument.styleSheets[nss].cssRules :
+					  FCK.EditorDocument.styleSheets[nss].rules)
+		for ( var nRule = 0; nRule < aRules.length; nRule++ )
+		{
+			var oRule = aRules[nRule];
+			var aSel = oRule.selectorText.split( ',' );
+			for ( var nSel = 0; nSel < aSel.length; nSel++ )
+			{
+				var strST = aSel[nSel];
+				//skip internal/hover/pseudoclasses
+				if ( strST.search(/:+|\[+|FCK__/) != -1 ) continue;
+				//allow descendent classes, but don't display the descendent tag
+				strST = strST.replace( / .*/,"" );
+				var aTagClass = strST.split( "." );
+				var strTag = aTagClass[0].Trim().toUpperCase( );
+				if ( !strTag ) strTag = aTags[0];
+				if ( !strTag || strTag == '' ) strTag = "SPAN";
+				var strClass = aTagClass[1];
+				if ( strClass && aTags.IndexOf(strTag) != -1 )
+				{
+					this._Combo.AddItem(  "." + strClass , '<'+strTag +' class="' + strClass + '">' + strClass + '</' + strTag + '>', "." + strClass  ) ;					
+					if ( strStyle == strClass )
+						this._Combo.SelectItem( "."+strClass );
+				}
+			}
+		}
+	}
+}
+
+FCKAutoStyleToolbar.prototype._addDefaultItems = function()
+{
+	this._Combo.AddItem(  'div', '<div>(None)</div>', '(none)'  ) ;
+	this._Combo.AddItem(  'h1', '<h1>Heading 1</h1>', 'Heading 1'  ) ;
+	this._Combo.AddItem(  'h2', '<h2>Heading 2</h2>', 'Heading 2'  ) ;
+	this._Combo.AddItem(  'h3', '<h3>Heading 3</h3>', 'Heading 3'  ) ;
+	this._Combo.AddItem(  'h4', '<h4>Heading 4</h4>', 'Heading 4'  ) ;
+	this._Combo.AddItem(  'h5', '<h5>Heading 5</h5>', 'Heading 5'  ) ;
+	this._Combo.AddItem(  'h6', '<h6>Heading 6</h6>', 'Heading 6'  ) ;
+	this._Combo.AddItem(  'p', '<p>Paragraph</p>', 'Paragraph'  ) ;
+}
+
+FCKToolbarItems.RegisterItem(  'AutoStyle'	, new FCKAutoStyleToolbar()  ) ;
