Index: /CKEditor/trunk/CHANGES.html
===================================================================
--- /CKEditor/trunk/CHANGES.html	(revision 4684)
+++ /CKEditor/trunk/CHANGES.html	(revision 4685)
@@ -94,4 +94,5 @@
 		<li><a href="http://dev.fckeditor.net/ticket/4498">#4498</a> : Fixed toolbar collapse button missing tooltip.</li>
 		<li><a href="http://dev.fckeditor.net/ticket/4738">#4738</a> : Fixed inserting table inside bold/italic/underline generates error on ENTER_BR mode.</li>
+		<li><a href="http://dev.fckeditor.net/ticket/4246">#4246</a> : Fixed avoid XHTML deprecated attributes for image styling.</li>
 		<li>Updated the following language files:<ul>
 			<li><a href="http://dev.fckeditor.net/ticket/4346">#4346</a> : Dutch;</li>
Index: /CKEditor/trunk/_source/core/dom/element.js
===================================================================
--- /CKEditor/trunk/_source/core/dom/element.js	(revision 4684)
+++ /CKEditor/trunk/_source/core/dom/element.js	(revision 4685)
@@ -434,4 +434,7 @@
 						}
 
+						case 'hspace':
+							return this.$.hspace;
+
 						case 'style':
 							// IE does not return inline styles via getAttribute(). See #2947.
@@ -999,8 +1002,7 @@
 		removeStyle : function( name )
 		{
+			this.setStyle( name, '' );
 			if ( this.$.style.removeAttribute )
 				this.$.style.removeAttribute( CKEDITOR.tools.cssStyleToDomStyle( name ) );
-			else
-				this.setStyle( name, '' );
 
 			if ( !this.$.style.cssText )
Index: /CKEditor/trunk/_source/lang/en.js
===================================================================
--- /CKEditor/trunk/_source/lang/en.js	(revision 4684)
+++ /CKEditor/trunk/_source/lang/en.js	(revision 4685)
@@ -386,12 +386,5 @@
 		align		: 'Align',
 		alignLeft	: 'Left',
-		alignAbsBottom: 'Abs Bottom',
-		alignAbsMiddle: 'Abs Middle',
-		alignBaseline	: 'Baseline',
-		alignBottom	: 'Bottom',
-		alignMiddle	: 'Middle',
 		alignRight	: 'Right',
-		alignTextTop	: 'Text Top',
-		alignTop	: 'Top',
 		preview	: 'Preview',
 		alertUrl	: 'Please type the image URL',
Index: /CKEditor/trunk/_source/plugins/image/dialogs/image.js
===================================================================
--- /CKEditor/trunk/_source/plugins/image/dialogs/image.js	(revision 4684)
+++ /CKEditor/trunk/_source/plugins/image/dialogs/image.js	(revision 4685)
@@ -12,5 +12,6 @@
 		CLEANUP = 8,
 		regexGetSize = /^\s*(\d+)((px)|\%)?\s*$/i,
-		regexGetSizeOrEmpty = /(^\s*(\d+)((px)|\%)?\s*$)|^$/i;
+		regexGetSizeOrEmpty = /(^\s*(\d+)((px)|\%)?\s*$)|^$/i,
+		pxLengthRegex = /^\d+px$/;
 
 	var onSizeChange = function()
@@ -62,4 +63,53 @@
 	};
 
+	// Custom commit dialog logic, where we're intended to give inline style
+	// field (txtdlgGenStyle) higher priority to avoid overwriting styles contribute
+	// by other fields.
+	function commitContent()
+	{
+		var args = arguments;
+		var inlineStyleField = this.getContentElement( 'advanced', 'txtdlgGenStyle' );
+		inlineStyleField && inlineStyleField.commit.apply( inlineStyleField, args );
+
+		this.foreach( function( widget )
+		{
+			if ( widget.commit &&  widget.id != 'txtdlgGenStyle' )
+				widget.commit.apply( widget, args );
+		});
+	};
+
+	// Avoid recursions.
+	var incommit;
+
+	// Synchronous field values to other impacted fields is required, e.g. border
+	// size change should alter inline-style text as well.  
+	function commitInternally( targetFields )
+	{
+		if( incommit )
+			return;
+
+		incommit = 1;
+		
+		var dialog = this.getDialog(),
+			element = dialog.imageElement;
+		if( element )
+		{
+			// Commit this field and broadcast to target fields.
+			this.commit( IMAGE, element );
+
+			targetFields = [].concat( targetFields );
+			var length = targetFields.length,
+				field;
+			for ( var i = 0; i < length; i++ )
+			{
+				field = dialog.getContentElement.apply( dialog, targetFields[ i ].split( ':' ) );
+				// May cause recursion.
+				field && field.setup( IMAGE, element );
+			}
+		}
+		
+		incommit = 0;
+	}
+
 	var switchLockRatio = function( dialog, value )
 	{
@@ -139,5 +189,5 @@
 		if ( size )
 			value = checkDimension( size, value );
-		value = checkDimension( element.$.style[ dimension ], value );
+		value = checkDimension( element.getStyle( dimension ), value );
 
 		this.setValue( value );
@@ -243,13 +293,17 @@
 				}
 
-				if ( element && element.getName() == 'img' && !element.getAttribute( '_cke_realelement' ) )
-					this.imageEditMode = 'img';
-				else if ( element && element.getName() == 'input' && element.getAttribute( 'type' ) && element.getAttribute( 'type' ) == 'image' )
-					this.imageEditMode = 'input';
-
-				if ( this.imageEditMode || this.imageElement )
-				{
-					if ( !this.imageElement )
-						this.imageElement = element;
+				if ( element && element.getName() == 'img' && !element.getAttribute( '_cke_realelement' )
+					|| element && element.getName() == 'input' && element.getAttribute( 'type' ) == 'image' )
+				{
+					this.imageEditMode = element.getName();
+					this.imageElement = element;
+				}
+
+				if ( this.imageEditMode )
+				{
+					// Use the original element as a buffer from  since we don't want
+					// temporary changes to be committed, e.g. if the dialog is canceled.
+					this.cleanImageElement = this.imageElement;
+					this.imageElement = this.cleanImageElement.clone( true, true );
 
 					// Fill out all fields.
@@ -259,4 +313,6 @@
 					switchLockRatio ( this, true );
 				}
+				else
+					this.imageElement =  editor.document.createElement( 'img' );
 
 				// Dont show preview if no URL given.
@@ -297,4 +353,10 @@
 						editor.insertElement( this.imageElement );
 					}
+					else
+					{
+						// Restore the original element before all commits.
+						this.imageElement = this.cleanImageElement;
+						delete this.cleanImageElement;
+					}
 				}
 				else	// Create a new image.
@@ -318,4 +380,8 @@
 				this.commitContent( IMAGE, this.imageElement );
 				this.commitContent( LINK, this.linkElement );
+
+				// Remove empty style attribute.
+				if( !this.imageElement.getAttribute( 'style' ) )
+					this.imageElement.removeAttribute( 'style' );
 
 				// Insert a new Image.
@@ -359,4 +425,6 @@
 				this.addFocusable( doc.getById( 'btnResetSize' ), 5 );
 				this.addFocusable( doc.getById( 'btnLockSizes' ), 5 );
+
+				this.commitContent = commitContent;
 			},
 			onHide : function()
@@ -373,4 +441,6 @@
 					this.originalElement = false;		// Dialog is closed.
 				}
+
+				delete this.imageElement;
 			},
 			contents : [
@@ -535,4 +605,8 @@
 															label : editor.lang.image.width,
 															onKeyUp : onSizeChange,
+															onChange : function()
+															{
+																commitInternally.call( this, 'advanced:txtdlgGenStyle' );
+															},
 															validate: function()
 															{
@@ -543,17 +617,18 @@
 															},
 															setup : setupDimension,
-															commit : function( type, element )
+															commit : function( type, element, internalCommit )
 															{
+																var value = this.getValue();
 																if ( type == IMAGE )
 																{
-																	var value = this.getValue();
 																	if ( value )
-																		element.setAttribute( 'width', value );
-																	else if ( !value && this.isChanged() )
-																		element.removeAttribute( 'width' );
+																		element.setStyle( 'width', CKEDITOR.tools.cssLength( value ) );
+																	else if ( !value && this.isChanged( ) )
+																		element.removeStyle( 'width' );
+
+																	!internalCommit && element.removeAttribute( 'width' );
 																}
 																else if ( type == PREVIEW )
 																{
-																	value = this.getValue();
 																	var aMatch = value.match( regexGetSize );
 																	if ( !aMatch )
@@ -568,5 +643,4 @@
 																else if ( type == CLEANUP )
 																{
-																	element.setStyle( 'width', '0px' );	// If removeAttribute doesn't work.
 																	element.removeAttribute( 'width' );
 																	element.removeStyle( 'width' );
@@ -581,4 +655,8 @@
 															label : editor.lang.image.height,
 															onKeyUp : onSizeChange,
+															onChange : function()
+															{
+																commitInternally.call( this, 'advanced:txtdlgGenStyle' );
+															},
 															validate: function()
 															{
@@ -589,17 +667,19 @@
 															},
 															setup : setupDimension,
-															commit : function( type, element )
+															commit : function( type, element, internalCommit )
 															{
+																var value = this.getValue();
 																if ( type == IMAGE )
 																{
-																	var value = this.getValue();
 																	if ( value )
-																		element.setAttribute( 'height', value );
-																	else if ( !value && this.isChanged() )
+																		element.setStyle( 'height', CKEDITOR.tools.cssLength( value ) );
+																	else if ( !value && this.isChanged( ) )
+																		element.removeStyle( 'height' );
+																	
+																	if( !internalCommit && type == IMAGE )
 																		element.removeAttribute( 'height' );
 																}
 																else if ( type == PREVIEW )
 																{
-																	value = this.getValue();
 																	var aMatch = value.match( regexGetSize );
 																	if ( !aMatch )
@@ -607,12 +687,11 @@
 																		var oImageOriginal = this.getDialog().originalElement;
 																		if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )
-																			element.setStyle( 'height',  oImageOriginal.$.height + 'px');
+																			element.setStyle( 'height', oImageOriginal.$.height + 'px' );
 																	}
 																	else
-																		element.setStyle( 'height', value + 'px');
+																		element.setStyle( 'height', value + 'px' );
 																}
 																else if ( type == CLEANUP )
 																{
-																	element.setStyle( 'height', '0px' );	// If removeAttribute doesn't work.
 																	element.removeAttribute( 'height' );
 																	element.removeStyle( 'height' );
@@ -699,4 +778,8 @@
 														updatePreview( this.getDialog() );
 													},
+													onChange : function()
+													{
+														commitInternally.call( this, 'advanced:txtdlgGenStyle' );
+													},
 													validate: function()
 													{
@@ -707,19 +790,36 @@
 													{
 														if ( type == IMAGE )
-															this.setValue( element.getAttribute( 'border' ) );
-													},
-													commit : function( type, element )
-													{
-														if ( type == IMAGE )
-														{
-															if ( this.getValue() || this.isChanged() )
-																element.setAttribute( 'border', this.getValue() );
+														{
+															var value,
+																borderStyle = element.getStyle( 'border-width' );
+
+															borderStyle = borderStyle && borderStyle.match( /^(\d+px)(?: \1 \1 \1)?$/ );
+															value = borderStyle && parseInt( borderStyle[ 1 ] );
+															!value && ( value = element.getAttribute( 'border' ) );
+
+															this.setValue( value );
 														}
-														else if ( type == PREVIEW )
-														{
-															var value = parseInt( this.getValue(), 10 );
-															value = isNaN( value ) ? 0 : value;
-															element.setAttribute( 'border', value );
-															element.setStyle( 'border', value + 'px solid black' );
+													},
+													commit : function( type, element, internalCommit )
+													{
+														var value = parseInt( this.getValue() );
+														if ( type == IMAGE || type == PREVIEW )
+														{
+															if ( value )
+																element.setStyle( 'border', CKEDITOR.tools.cssLength( value ) + ' solid' );
+															else if ( !value && this.isChanged() )
+															{
+																if( CKEDITOR.env.ie )
+																{
+																	element.removeStyle( 'border-width' );
+																	element.removeStyle( 'border-style' );
+																	element.removeStyle( 'border-color' );
+																}
+																else
+																	element.removeStyle( 'border' );
+															}
+
+															if( !internalCommit && type == IMAGE )
+																element.removeAttribute( 'border' );
 														}
 														else if ( type == CLEANUP )
@@ -741,4 +841,8 @@
 														updatePreview( this.getDialog() );
 													},
+													onChange : function()
+													{
+														commitInternally.call( this, 'advanced:txtdlgGenStyle' );
+													},
 													validate: function()
 													{
@@ -750,23 +854,39 @@
 														if ( type == IMAGE )
 														{
-															var value = element.getAttribute( 'hspace' );
-															if ( value != -1 )				// In IE empty = -1.
-																this.setValue( value );
+															var value,
+																marginLeftPx,
+																marginRightPx,
+																marginLeftStyle = element.getStyle( 'margin-left' ),
+																marginRightStyle = element.getStyle( 'margin-right' );
+
+															marginLeftStyle = marginLeftStyle && marginLeftStyle.match( pxLengthRegex );
+															marginRightStyle = marginRightStyle && marginRightStyle.match( pxLengthRegex );
+															marginLeftPx = parseInt( marginLeftStyle );
+															marginRightPx = parseInt( marginRightStyle );
+
+															value = ( marginLeftPx == marginRightPx ) && marginLeftPx;
+															!value && ( value = element.getAttribute( 'hspace' ) );
+
+															this.setValue( value );
 														}
 													},
-													commit : function( type, element )
-													{
-														if ( type == IMAGE )
-														{
-															if ( this.getValue() || this.isChanged() )
-																element.setAttribute( 'hspace', this.getValue() );
-														}
-														else if ( type == PREVIEW )
-														{
-															var value = parseInt( this.getValue(), 10 );
-															value = isNaN( value ) ? 0 : value;
-															element.setAttribute( 'hspace', value );
-															element.setStyle( 'margin-left', value + 'px' );
-															element.setStyle( 'margin-right', value + 'px' );
+													commit : function( type, element, internalCommit )
+													{
+														var value = parseInt( this.getValue() );
+														if ( type == IMAGE || type == PREVIEW )
+														{
+															if ( value )
+															{
+																element.setStyle( 'margin-left', CKEDITOR.tools.cssLength( value ) );
+																element.setStyle( 'margin-right', CKEDITOR.tools.cssLength( value ) );
+															}
+															else if ( !value && this.isChanged( ) )
+															{
+																element.removeStyle( 'margin-left' );
+																element.removeStyle( 'margin-right' );
+															}
+
+															if( !internalCommit && type == IMAGE )
+																element.removeAttribute( 'hspace' );
 														}
 														else if ( type == CLEANUP )
@@ -789,4 +909,8 @@
 														updatePreview( this.getDialog() );
 													},
+													onChange : function()
+													{
+														commitInternally.call( this, 'advanced:txtdlgGenStyle' );
+													},
 													validate: function()
 													{
@@ -797,20 +921,39 @@
 													{
 														if ( type == IMAGE )
-															this.setValue( element.getAttribute( 'vspace' ) );
-													},
-													commit : function( type, element )
-													{
-														if ( type == IMAGE )
-														{
-															if ( this.getValue() || this.isChanged() )
-																element.setAttribute( 'vspace', this.getValue() );
+														{
+															var value,
+																marginTopPx,
+																marginBottomPx,
+																marginTopStyle = element.getStyle( 'margin-top' ),
+																marginBottomStyle = element.getStyle( 'margin-bottom' );
+
+															marginTopStyle = marginTopStyle && marginTopStyle.match( pxLengthRegex );
+															marginBottomStyle = marginBottomStyle && marginBottomStyle.match( pxLengthRegex );
+															marginTopPx = parseInt( marginTopStyle );
+															marginBottomPx = parseInt( marginBottomStyle );
+
+															value = ( marginTopPx == marginBottomPx ) && marginTopPx;
+															!value && ( value = element.getAttribute( 'vspace' ) );
+															this.setValue( value );
 														}
-														else if ( type == PREVIEW )
-														{
-															var value = parseInt( this.getValue(), 10 );
-															value = isNaN( value ) ? 0 : value;
-															element.setAttribute( 'vspace', this.getValue() );
-															element.setStyle( 'margin-top', value + 'px' );
-															element.setStyle( 'margin-bottom', value + 'px' );
+													},
+													commit : function( type, element, internalCommit )
+													{
+														var value = parseInt( this.getValue() );
+														if ( type == IMAGE || type == PREVIEW )
+														{
+															if ( value )
+															{
+																element.setStyle( 'margin-top', CKEDITOR.tools.cssLength( value ) );
+																element.setStyle( 'margin-bottom', CKEDITOR.tools.cssLength( value ) );
+															}
+															else if ( !value && this.isChanged( ) )
+															{
+																element.removeStyle( 'margin-top' );
+																element.removeStyle( 'margin-bottom' );
+															}
+
+															if( !internalCommit && type == IMAGE )
+																element.removeAttribute( 'vspace' );
 														}
 														else if ( type == CLEANUP )
@@ -834,51 +977,63 @@
 														[ editor.lang.common.notSet , ''],
 														[ editor.lang.image.alignLeft , 'left'],
-														[ editor.lang.image.alignAbsBottom , 'absBottom'],
-														[ editor.lang.image.alignAbsMiddle , 'absMiddle'],
-														[ editor.lang.image.alignBaseline , 'baseline'],
-														[ editor.lang.image.alignBottom , 'bottom'],
-														[ editor.lang.image.alignMiddle , 'middle'],
 														[ editor.lang.image.alignRight , 'right'],
-														[ editor.lang.image.alignTextTop , 'textTop'],
-														[ editor.lang.image.alignTop , 'top']
+														// Backward compatible with v2 on setup when specified as attribute value,
+														// while these values are no more available as select options.
+														//	[ editor.lang.image.alignAbsBottom , 'absBottom'],
+														//	[ editor.lang.image.alignAbsMiddle , 'absMiddle'],
+														//  [ editor.lang.image.alignBaseline , 'baseline'],
+														//  [ editor.lang.image.alignTextTop , 'text-top'],
+														//  [ editor.lang.image.alignBottom , 'bottom'],
+														//  [ editor.lang.image.alignMiddle , 'middle'],
+														//  [ editor.lang.image.alignTop , 'top']
 													],
 													onChange : function()
 													{
 														updatePreview( this.getDialog() );
+														commitInternally.call( this, 'advanced:txtdlgGenStyle' );
 													},
 													setup : function( type, element )
 													{
 														if ( type == IMAGE )
-															this.setValue( element.getAttribute( 'align' ) );
-													},
-													commit : function( type, element )
+														{
+															var value = element.getStyle( 'float' );
+															switch( value )
+															{
+																// Ignore those unrelated values.
+																case 'inherit':
+																case 'none':
+																	value = '';
+															}
+
+															!value && ( value = ( element.getAttribute( 'align' ) || '' ).toLowerCase() );
+															this.setValue( value );
+														}
+													},
+													commit : function( type, element, internalCommit )
 													{
 														var value = this.getValue();
-														if ( type == IMAGE )
-														{
-															if ( value || this.isChanged() )
-																element.setAttribute( 'align', value );
-														}
-														else if ( type == PREVIEW )
-														{
-															element.setAttribute( 'align', this.getValue() );
-
-															if ( value == 'absMiddle' || value == 'middle' )
-																element.setStyle( 'vertical-align', 'middle' );
-															else if ( value == 'top' || value == 'textTop' )
-																element.setStyle( 'vertical-align', 'top' );
-															else
-																element.removeStyle( 'vertical-align' );
-
-															if ( value == 'right' || value == 'left' )
-																element.setStyle( 'styleFloat', value );
-															else
-																element.removeStyle( 'styleFloat' );
-
+														if ( type == IMAGE || type == PREVIEW )
+														{
+															if ( value )
+																element.setStyle( 'float', value );
+															else if ( !value && this.isChanged( ) )
+																element.removeStyle( 'float' );
+
+															if( !internalCommit && type == IMAGE )
+															{
+																value = ( element.getAttribute( 'align' ) || '' ).toLowerCase();
+																switch( value )
+																{
+																	// we should remove it only if it matches "left" or "right",
+																	// otherwise leave it intact.
+																	case 'left':
+																	case 'right':
+																		element.removeAttribute( 'align' );
+																}
+															}
 														}
 														else if ( type == CLEANUP )
-														{
-															element.removeAttribute( 'align' );
-														}
+															element.removeStyle( 'float' );
+
 													}
 												}
@@ -1184,4 +1339,13 @@
 								}
 							},
+							onChange : function ()
+							{
+								commitInternally.call( this,
+									[ 'info:cmbFloat', 'info:cmbAlign',
+									  'info:txtVSpace', 'info:txtHSpace',
+									  'info:txtBorder',
+									  'info:txtWidth', 'info:txtHeight' ] );
+								updatePreview( this );
+							},
 							commit : function( type, element )
 							{
@@ -1189,33 +1353,4 @@
 								{
 									element.setAttribute( 'style', this.getValue() );
-
-									// Set STYLE dimensions.
-									var height = element.getAttribute( 'height' ),
-										width = element.getAttribute( 'width' );
-
-									if ( this.attributesInStyle && this.attributesInStyle.height )
-									{
-										if ( height )
-										{
-											if ( height.match( regexGetSize )[2] == '%' )			// % is allowed
-												element.setStyle( 'height', height + '%' );
-											else
-												element.setStyle( 'height', height + 'px' );
-										}
-										else
-											element.removeStyle( 'height' );
-									}
-									if ( this.attributesInStyle && this.attributesInStyle.width )
-									{
-										if ( width )
-										{
-											if ( width.match( regexGetSize )[2] == '%' )			// % is allowed
-												element.setStyle( 'width', width + '%' );
-											else
-												element.setStyle( 'width', width + 'px' );
-										}
-										else
-											element.removeStyle( 'width' );
-									}
 								}
 							}
