Index: /FCKeditor/trunk/editor/_source/commandclasses/fckjustifycommands.js
===================================================================
--- /FCKeditor/trunk/editor/_source/commandclasses/fckjustifycommands.js	(revision 828)
+++ /FCKeditor/trunk/editor/_source/commandclasses/fckjustifycommands.js	(revision 829)
@@ -25,10 +25,58 @@
 {
 	this.AlignValue = alignValue ;
-	this.CurrentState = FCK_TRISTATE_DISABLED ;
-	this.DefaultAlign = ( alignValue == 'left' && FCKConfig.ContentLangDirection.IEquals( 'ltr' ) ) ||
-			( alignValue == 'right' && FCKConfig.ContentLangDirection.IEquals( 'rtl' ) ) ;
+
+	// Detect whether this is the instance for the default alignment.
+	var contentDir = FCKConfig.ContentLangDirection.toLowerCase() ;
+	this.IsDefaultAlign = ( alignValue == 'left' && contentDir == 'ltr' ) ||
+						  ( alignValue == 'right' && contentDir == 'rtl' ) ;
+
+	// Get the class name to be used by this instance.
+	var cssClassName = this._CssClassName = ( function()
+	{
+		switch ( alignValue )
+		{
+			case 'left' :
+				return FCKConfig.JustifyLeftClass ;
+			case 'right' :
+				return FCKConfig.JustifyRightClass ;
+			case 'center' :
+				return FCKConfig.JustifyCenterClass ;
+			case 'justify' :
+				return FCKConfig.JustifyFullClass ;
+		}
+	} )() ;
+
+	if ( cssClassName && cssClassName.length > 0 )
+		this._CssClassRegex = new RegExp( '(?:^|\s+)' + cssClassName + '(?=$|\s)' ) ;
 }
 
-FCKJustifyCommand.prototype = 
+FCKJustifyCommand._GetClassNameRegex = function()
+{
+	var regex = FCKJustifyCommand._ClassRegex ;
+	if ( regex != undefined )
+		return regex ;
+
+	var names = [] ;
+
+	var appendName = function( name )
+	{
+		if ( name && name.length > 0 )
+			names.push( name ) ;
+	}
+
+	appendName( FCKConfig.JustifyLeftClass ) ;
+	appendName( FCKConfig.JustifyRightClass ) ;
+	appendName( FCKConfig.JustifyCenterClass ) ;
+	appendName( FCKConfig.JustifyFullClass ) ;
+
+	if ( names.length > 0 )
+		regex = new RegExp( '(?:^|\s+)(?:' + names.join( '|' ) + ')(?=$|\s)' ) ;
+	else
+		regex = null ;
+
+	return FCKJustifyCommand._ClassRegex = regex ;
+}
+
+FCKJustifyCommand.prototype =
 {
 	Execute : function()
@@ -37,11 +85,17 @@
 		range.MoveToSelection() ;
 
-		// Store a bookmark of the selection since the paragraph iterator might change the DOM tree and break selections.
+		var currentState = this.GetState() ;
+		if ( currentState == FCK_TRISTATE_DISABLED )
+			return ;
+
+		// Store a bookmark of the selection since the paragraph iterator might
+		// change the DOM tree and break selections.
 		var bookmark = range.CreateBookmark() ;
-		var iterator = new FCKDomRangeIterator( range ) ;
-		var block = null ;
-		var cssClassName = this._GetCSSClassName() ;
+
+		var cssClassName = this._CssClassName ;
 
 		// Apply alignment setting for each paragraph.
+		var iterator = new FCKDomRangeIterator( range ) ;
+		var block ;
 		while ( ( block = iterator.GetNextParagraph() ) )
 		{
@@ -50,16 +104,28 @@
 			if ( cssClassName )
 			{
-				block.className = block.className.replace( FCKConfig.JustifyClassPattern, ' ' ) ;
-				if ( block.className.length && block.className.charAt( block.className.length - 1 ) != ' ' )
-					block.className += ' ' + cssClassName ;
-				else
-					block.className += cssClassName ;
+				// Remove the any of the alignment classes from the className.
+				var className = block.className.replace( FCKJustifyCommand._GetClassNameRegex(), '' ) ;
+
+				// Append the desired class name.
+				if ( currentState == FCK_TRISTATE_OFF )
+				{
+					if ( className.length > 0 )
+						className += ' ' ;
+					block.className = className + cssClassName ;
+				}
+				else if ( className.length == 0 )
+					FCKDomTools.RemoveAttribute( block, 'class' ) ;
 			}
 			else
 			{
-				if ( this.CurrentState == FCK_TRISTATE_OFF)
-					block.style.textAlign = this.AlignValue ;
-				else if ( this.CurrentState == FCK_TRISTATE_ON )
-					block.style.textAlign = '' ;
+				var style = block.style ;
+				if ( currentState == FCK_TRISTATE_OFF )
+					style.textAlign = this.AlignValue ;
+				else
+				{
+					style.textAlign = '' ;
+					if ( style.cssText.length == 0 )
+						block.removeAttribute( 'style' ) ;
+				}
 			}
 		}
@@ -68,4 +134,5 @@
 		range.MoveToBookmark( bookmark ) ;
 		range.Select() ;
+
 		FCK.Events.FireEvent( 'OnSelectionChange' ) ;
 	},
@@ -73,75 +140,34 @@
 	GetState : function()
 	{
+		// Disabled if not WYSIWYG.
 		if ( FCK.EditMode != FCK_EDITMODE_WYSIWYG || ! FCK.EditorWindow )
-		{
-			this.CurrentState = FCK_TRISTATE_DISABLED ;
-			return this.CurrentState ;
-		}
+			return FCK_TRISTATE_DISABLED ;
 
 		// Retrieve the first selected block.
-		var firstBlock = null ;
-		if ( FCKBrowserInfo.IsIE )
+		var path = new FCKElementPath( FCKSelection.GetBoundaryParentElement( true ) ) ;
+		var firstBlock = path.Block || path.BlockLimit ;
+
+		if ( !firstBlock || firstBlock.nodeName.toLowerCase() == 'body' )
+			return FCK_TRISTATE_OFF ;
+
+		// Check if the desired style is already applied to the block.
+		var cssClassRegex = this._CssClassRegex ;
+		if ( !cssClassRegex )
 		{
-			var range = FCK.EditorDocument.selection.createRange() ;
-			range.collapse( true ) ;
-			firstBlock = ( new FCKElementPath( range.parentElement() ) ).Block ;
+			// Definitions in the "style" override the "align" attribute, so it
+			// gets precedence.
+			var currentAlign = firstBlock.style.textAlign || firstBlock.align ;
+
+			if ( ( !currentAlign && this.IsDefaultAlign ) || currentAlign == this.AlignValue )
+				return FCK_TRISTATE_ON ;
 		}
 		else
 		{
-			var sel = FCK.EditorWindow.getSelection() ;
-			if ( ! sel || sel.rangeCount < 0 )
-			{
-				this.CurrentState = FCK_TRISTATE_DISABLED ;
-				return this.CurrentState ;
-			}
-			var range = sel.getRangeAt( 0 ) ;
-			firstBlock = ( new FCKElementPath( range.startContainer ) ).Block ;
+			if ( ( this.IsDefaultAlign && !FCKJustifyCommand._GetClassNameRegex().test( firstBlock.className ) )
+					|| cssClassRegex.test( firstBlock.className ) )
+				return FCK_TRISTATE_ON ;
 		}
 
-		if ( ! firstBlock || firstBlock.nodeName.IEquals( 'body' ) )
-		{
-			this.CurrentState = FCK_TRISTATE_OFF ;
-			return this.CurrentState ;
-		}
-
-		// See if the desired style is already applied to the first block.
-		var cssClassName = this._GetCSSClassName() ;
-		if ( ! cssClassName )
-		{
-			if ( ! firstBlock.align && ! firstBlock.style.textAlign && this.DefaultAlign )
-				return FCK_TRISTATE_ON ;
-			this.CurrentState = ( firstBlock.align == this.AlignValue || firstBlock.style.textAlign == this.AlignValue ?
-					FCK_TRISTATE_ON : FCK_TRISTATE_OFF ) ;
-		}
-		else
-		{
-			if ( firstBlock.className.search( FCKConfig.JustifyClassPattern ) == -1 && this.DefaultAlign )
-				return FCK_TRISTATE_ON ;
-			this.CurrentState = ( firstBlock.className.search( new RegExp( '(^|\\s+)' + cssClassName + '($|\\s+)' ) ) == -1 ? 
-						FCK_TRISTATE_OFF : FCK_TRISTATE_ON ) ;
-		}
-
-		return this.CurrentState ;
-	},
-
-	_GetCSSClassName : function()
-	{
-		var cssClassName = null ;
-		switch ( this.AlignValue )
-		{
-			case 'left' :
-				cssClassName = FCKConfig.LeftJustifyClass ;
-				break ;
-			case 'right' :
-				cssClassName = FCKConfig.RightJustifyClass ;
-				break ;
-			case 'center' :
-				cssClassName = FCKConfig.CenterJustifyClass ;
-				break ;
-			case 'justify' :
-				cssClassName = FCKConfig.FullJustifyClass ;
-				break ;
-		}
-		return cssClassName ;
+		return FCK_TRISTATE_OFF ;
 	}
 } ;
Index: /FCKeditor/trunk/fckconfig.js
===================================================================
--- /FCKeditor/trunk/fckconfig.js	(revision 828)
+++ /FCKeditor/trunk/fckconfig.js	(revision 829)
@@ -245,4 +245,9 @@
 };
 
+FCKConfig.JustifyLeftClass		= '' ;
+FCKConfig.JustifyRightClass		= '' ;
+FCKConfig.JustifyCenterClass	= '' ;
+FCKConfig.JustifyFullClass		= '' ;
+
 // The following value defines which File Browser connector and Quick Upload
 // "uploader" to use. It is valid for the default implementaion and it is here
@@ -295,10 +300,2 @@
 FCKConfig.SmileyWindowHeight	= 240 ;
 
-// XHTML 1.1 compliant options example
-/*
-FCKConfig.JustifyClassPattern = /(^|\s+)Justify(Left|Right|Center|Full)($|\s+)/ ;
-FCKConfig.LeftJustifyClass = 'JustifyLeft' ;
-FCKConfig.RightJustifyClass = 'JustifyRight' ;
-FCKConfig.CenterJustifyClass = 'JustifyCenter' ;
-FCKConfig.FullJustifyClass = 'JustifyFull' ;
-*/
