Index: /CKEditor/branches/prototype/_source/core/config.js
===================================================================
--- /CKEditor/branches/prototype/_source/core/config.js	(revision 2601)
+++ /CKEditor/branches/prototype/_source/core/config.js	(revision 2602)
@@ -159,5 +159,5 @@
 	 * config.plugins = 'elementspath,toolbar,wysiwygarea';
 	 */
-	plugins : 'basicstyles,button,dialog,elementspath,htmldataprocessor,keystrokes,sourcearea,tab,toolbar,wysiwygarea',
+	plugins : 'basicstyles,button,dialog,elementspath,htmldataprocessor,keystrokes,smiley,sourcearea,tab,toolbar,wysiwygarea',
 
 	/**
@@ -222,4 +222,21 @@
 	 * config.magnetic = 30;
 	 */
-	magnetDistance : 20
+	magnetDistance : 20,
+
+	/**
+	 * List of smiley images displayed in the Smiley dialog.
+	 * @type Array
+	 * @default ['regular_smile.gif','sad_smile.gif','wink_smile.gif','teeth_smile.gif','confused_smile.gif','tounge_smile.gif','embaressed_smile.gif','omg_smile.gif','whatchutalkingabout_smile.gif','angry_smile.gif','angel_smile.gif','shades_smile.gif','devil_smile.gif','cry_smile.gif','lightbulb.gif','thumbs_down.gif','thumbs_up.gif','heart.gif','broken_heart.gif','kiss.gif','envelope.gif']
+	 * @example
+	 * config.smileyImages = [ 'tounge.gif', 'smile.gif', 'laugh.gif' ]; 
+	 */
+	smileyImages : ['regular_smile.gif','sad_smile.gif','wink_smile.gif','teeth_smile.gif','confused_smile.gif','tounge_smile.gif','embaressed_smile.gif','omg_smile.gif','whatchutalkingabout_smile.gif','angry_smile.gif','angel_smile.gif','shades_smile.gif','devil_smile.gif','cry_smile.gif','lightbulb.gif','thumbs_down.gif','thumbs_up.gif','heart.gif','broken_heart.gif','kiss.gif','envelope.gif'],
+
+	smileyPath : CKEDITOR.basePath +  '_source/plugins/smiley/images/',
+
+	smileyWindowWidth : 320,
+
+	smileyWindowHeight : 210,
+
+	smileyColumns : 8
 };
Index: /CKEditor/branches/prototype/_source/plugins/dialog/plugin.js
===================================================================
--- /CKEditor/branches/prototype/_source/plugins/dialog/plugin.js	(revision 2601)
+++ /CKEditor/branches/prototype/_source/plugins/dialog/plugin.js	(revision 2602)
@@ -1,3 +1,3 @@
-﻿/*
+/*
  * CKEditor - The text editor for Internet - http://ckeditor.com
  * Copyright (C) 2003-2008 Frederico Caldeira Knabben
@@ -131,5 +131,10 @@
 
 	// Initialize the tab and page map.
-	this._.tabs = {};
+	CKEDITOR.tools.extend (this._,
+		{
+			tabs : {},
+			pageCount : 0,
+			lastTab : null
+		}, true);
 
 	// Make the dialog an event hub.
@@ -452,5 +457,6 @@
 						type : 'vbox',
 						className : 'cke_dialog_page_contents',
-						children : contents.elements
+						children : contents.elements,
+						totalHeight : '100%'
 					}, pageHtml );
 
@@ -467,6 +473,19 @@
 			].join( '' ) );
 
+		// First and last tab styles classes.
+		if ( this._.lastTab )
+			this._.lastTab.removeClass( 'last' );
+		tab.addClass( this._.pageCount > 0 ? 'last' : 'first' );
+
+		// If only a single page exist, a different style is used in the central pane.
+		if ( this._.pageCount == 0 )
+			this._.parts.c.addClass( 'single_page' );
+		else
+			this._.parts.c.removeClass( 'single_page' );
+
 		// Take records for the tabs and elements created.
 		this._.tabs[ contents.id ] = [ tab, page ];
+		this._.pageCount++;
+		this._.lastTab = tab;
 		var contentMap = this._.contents[ contents.id ] = {},
 			cursor,
@@ -1261,163 +1280,179 @@
 };
 
-CKEDITOR.ui.dialog = 
+(function()
 {
-	/**
-	 * The base class of all dialog UI elements.
-	 * @constructor
-	 * @example
-	 */
-	uiElement : function( dialog, elementDefinition, htmlList, nodeNameArg, stylesArg, attributesArg, contentsArg )
-	{
-		if (arguments.length < 4 )
-			return;
-
-		var nodeName = ( nodeNameArg.call ? nodeNameArg( elementDefinition ) : nodeNameArg ) || 'div',
-			html = [ '<', nodeName, ' ' ],
-			styles = ( stylesArg && stylesArg.call ? stylesArg( elementDefinition ) : stylesArg ) || {},
-			attributes = ( attributesArg && attributesArg.call ? attributesArg( elementDefinition ) : attributesArg ) || {},
-			innerHTML = ( contentsArg && contentsArg.call ? contentsArg( dialog, elementDefinition ) : contentsArg ) || '',
-			id = this.id = attributes.id || elementDefinition.id || CKEDITOR.tools.getNextNumber() + '_uiElement',
-			i;
-
-		// Set the id, a unique id is required for getElement() to work.
-		attributes.id = id;
-
-		// Set the type and definition CSS class names.
-		var classes = {};
-		if ( elementDefinition.type )
-			classes[ 'cke_dialog_ui_' + elementDefinition.type ] = 1;
-		if ( elementDefinition.className )
-			classes[ elementDefinition.className ] = 1;
-		var attributeClasses = ( attributes['class'] && attributes['class'].split ) ? attributes['class'].split( ' ' ) : [];
-		for ( i = 0 ; i < attributeClasses.length ; i++ )
-		{
-			if ( attributeClasses[i] )
-				classes[ attributeClasses[i] ] = 1;
-		}
-		var finalClasses = [];
-		for ( i in classes )
-			finalClasses.push( i );
-		attributes['class'] = finalClasses.join( ' ' );
-
-		// Set the popup tooltop.
-		if ( elementDefinition.title )
-			attributes.title = elementDefinition.title;
-
-		// Write the inline CSS styles.
-		var styleStr = ( elementDefinition.style || '' ).split( ';' );
-		for ( i in styles )
-			styleStr.push( i + ':' + styles[i] );
-		for ( i = styleStr.length - 1 ; i >= 0 ; i-- )
-		{
-			if ( styleStr[i] === '' )
-				styleStr.splice( i, 1 );
-		}
-		if ( styleStr.length > 0 )
-			attributes.style = ( attributes.style || '' ) + styleStr.join( '; ' );
-
-		// Write the attributes.
-		for ( i in attributes )
-			html.push( i + '="' + CKEDITOR.tools.htmlEncode( attributes[i] ) + '" ');
-
-		// Write the content HTML.
-		html.push( '>', innerHTML, '</', nodeName, '>' );
-
-		// Add contents to the parent HTML array.
-		htmlList.push( html.join( '' ) );
-
-		// Add the onLoad event to dialog.
-		if ( elementDefinition.onLoad )
-			dialog.on( 'load', elementDefinition.onLoad, this, null, CKEDITOR.tools.getNextNumber() );
-
-		( this._ || ( this._ = {} ) ).dialog = dialog;
-	},
-
-	/**
-	 * Horizontal layout box for dialog UI elements, auto-expends to available width of container.
-	 * @constructor
-	 * @extends CKEDITOR.ui.dialog.uiElement
-	 * @example
-	 */
-	hbox : function( dialog, childObjList, childHtmlList, htmlList, elementDefinition )
-	{
-		if ( arguments.length < 4 )
-			return;
-
-		this._ || ( this._ = {} );
-
-		var children = this._.children = childObjList,
-			widths = elementDefinition && elementDefinition.widths || null,
-			height = elementDefinition && elementDefinition.height || null,
-			i;
-		/** @ignore */
-		var innerHTML = function()
-		{
-			var html = [ '<tbody><tr class="cke_dialog_ui_hbox">' ];
-			for ( i = 0 ; i < childHtmlList.length ; i++ )
-			{
-				var className = 'cke_dialog_ui_hbox_child',
-					styles = [];
-				if ( i === 0 )
-					className = 'cke_dialog_ui_hbox_first';
-				if ( i == childHtmlList.length - 1 )
-					className = 'cke_dialog_ui_hbox_last';
-				html.push( '<td class="', className, '" ' );
-				if ( widths )
+	var decimalRegex = /^\d+(?:\.\d+)?$/,
+		fixLength = function( length )
+		{
+			return length + ( decimalRegex.test( length ) ? 'px' : '' );
+		}
+
+	CKEDITOR.ui.dialog = 
+	{
+		/**
+		 * The base class of all dialog UI elements.
+		 * @constructor
+		 * @example
+		 */
+		uiElement : function( dialog, elementDefinition, htmlList, nodeNameArg, stylesArg, attributesArg, contentsArg )
+		{
+			if (arguments.length < 4 )
+				return;
+
+			var nodeName = ( nodeNameArg.call ? nodeNameArg( elementDefinition ) : nodeNameArg ) || 'div',
+				html = [ '<', nodeName, ' ' ],
+				styles = ( stylesArg && stylesArg.call ? stylesArg( elementDefinition ) : stylesArg ) || {},
+				attributes = ( attributesArg && attributesArg.call ? attributesArg( elementDefinition ) : attributesArg ) || {},
+				innerHTML = ( contentsArg && contentsArg.call ? contentsArg( dialog, elementDefinition ) : contentsArg ) || '',
+				id = this.id = attributes.id || elementDefinition.id || CKEDITOR.tools.getNextNumber() + '_uiElement',
+				i;
+
+			// Set the id, a unique id is required for getElement() to work.
+			attributes.id = id;
+
+			// Set the type and definition CSS class names.
+			var classes = {};
+			if ( elementDefinition.type )
+				classes[ 'cke_dialog_ui_' + elementDefinition.type ] = 1;
+			if ( elementDefinition.className )
+				classes[ elementDefinition.className ] = 1;
+			var attributeClasses = ( attributes['class'] && attributes['class'].split ) ? attributes['class'].split( ' ' ) : [];
+			for ( i = 0 ; i < attributeClasses.length ; i++ )
+			{
+				if ( attributeClasses[i] )
+					classes[ attributeClasses[i] ] = 1;
+			}
+			var finalClasses = [];
+			for ( i in classes )
+				finalClasses.push( i );
+			attributes['class'] = finalClasses.join( ' ' );
+
+			// Set the popup tooltop.
+			if ( elementDefinition.title )
+				attributes.title = elementDefinition.title;
+
+			// Write the inline CSS styles.
+			var styleStr = ( elementDefinition.style || '' ).split( ';' );
+			for ( i in styles )
+				styleStr.push( i + ':' + styles[i] );
+			for ( i = styleStr.length - 1 ; i >= 0 ; i-- )
+			{
+				if ( styleStr[i] === '' )
+					styleStr.splice( i, 1 );
+			}
+			if ( styleStr.length > 0 )
+				attributes.style = ( attributes.style || '' ) + styleStr.join( '; ' );
+
+			// Write the attributes.
+			for ( i in attributes )
+				html.push( i + '="' + CKEDITOR.tools.htmlEncode( attributes[i] ) + '" ');
+
+			// Write the content HTML.
+			html.push( '>', innerHTML, '</', nodeName, '>' );
+
+			// Add contents to the parent HTML array.
+			htmlList.push( html.join( '' ) );
+
+			( this._ || ( this._ = {} ) ).dialog = dialog;
+			
+			// Add events.
+			this.registerEvents( elementDefinition );
+		},
+
+		/**
+		 * Horizontal layout box for dialog UI elements, auto-expends to available width of container.
+		 * @constructor
+		 * @extends CKEDITOR.ui.dialog.uiElement
+		 * @example
+		 */
+		hbox : function( dialog, childObjList, childHtmlList, htmlList, elementDefinition )
+		{
+			if ( arguments.length < 4 )
+				return;
+
+			this._ || ( this._ = {} );
+
+			var children = this._.children = childObjList,
+				widths = elementDefinition && elementDefinition.widths || null,
+				height = elementDefinition && elementDefinition.height || null,
+				i;
+			/** @ignore */
+			var innerHTML = function()
+			{
+				var html = [ '<tbody><tr class="cke_dialog_ui_hbox">' ];
+				for ( i = 0 ; i < childHtmlList.length ; i++ )
 				{
-					if ( widths[i] && isFinite( parseFloat( widths[i] ) ) )
-						styles.push( 'width:' + widths[i] + 'px' );
+					var className = 'cke_dialog_ui_hbox_child',
+						styles = [];
+					if ( i === 0 )
+						className = 'cke_dialog_ui_hbox_first';
+					if ( i == childHtmlList.length - 1 )
+						className = 'cke_dialog_ui_hbox_last';
+					html.push( '<td class="', className, '" ' );
+					if ( widths )
+					{
+						if ( widths[i] )
+							styles.push( 'width:' + fixLength( widths[i] ) );
+					}
+					else
+						styles.push( 'width:' + Math.floor( 100 / childHtmlList.length ) + '%' );
+					if ( height )
+						styles.push( 'height:' + fixLength( height ) );
+					if ( styles.length > 0 )
+						html.push( 'style="' + styles.join('; ') + '" ' );
+					html.push( '>', childHtmlList[i], '</td>' );
 				}
-				else
-					styles.push( 'width:' + Math.floor( 100 / childHtmlList.length ) + '%' );
-				if ( height && isFinite( parseFloat( height ) ) )
-					styles.push( 'height:' + height + 'px' );
-				if ( styles.length > 0 )
-					html.push( 'style="' + styles.join('; ') + '" ' );
-				html.push( '>', childHtmlList[i], '</td>' );
-			}
-			html.push( '</tr></tbody>' );
-			return html.join( '' );
-		};
-		CKEDITOR.ui.dialog.uiElement.call( this, dialog, elementDefinition || { type : 'hbox' }, htmlList, 'table', null, null, innerHTML );
-	},
-
-	/**
-	 * Vertical layout box for dialog UI elements.
-	 * @constructor
-	 * @extends CKEDITOR.ui.dialog.hbox
-	 * @example
-	 */
-	vbox : function( dialog, childObjList, childHtmlList, htmlList, elementDefinition )
-	{
-		if (arguments.length < 3 )
-			return;
-
-		this._ || ( this._ = {} );
-
-		var children = this._.children = childObjList,
-			width = elementDefinition && elementDefinition.width || null,
-			heights = elementDefinition && elementDefinition.heights || null;
-		/** @ignore */
-		var innerHTML = function()
-		{
-			var html = [];
-			for ( var i = 0 ; i < childHtmlList.length ; i++ )
-			{
-				var styles = [];
-				html.push( '<div ' );
-				if ( width && isFinite( parseFloat( width ) ) )
-					styles.push( 'width:' + width + 'px' );
-				if ( heights && isFinite( parseFloat( heights[i] ) ) )
-					styles.push( 'height:' + heights[i] + 'px' );
-				if ( styles.length > 0 )
-					html.push( 'style="', styles.join( '; ' ), '" ' );
-				html.push( ' class="cke_dialog_ui_vbox_child">', childHtmlList[i], '</div>' );
-			}
-			return html.join( '' );
-		};
-		CKEDITOR.ui.dialog.uiElement.call( this, dialog, elementDefinition || { type : 'vbox' }, htmlList, 'div', null, null, innerHTML );
-	}
-};
+				html.push( '</tr></tbody>' );
+				return html.join( '' );
+			};
+			CKEDITOR.ui.dialog.uiElement.call( this, dialog, elementDefinition || { type : 'hbox' }, htmlList, 'table', null, null, innerHTML );
+		},
+
+		/**
+		 * Vertical layout box for dialog UI elements.
+		 * @constructor
+		 * @extends CKEDITOR.ui.dialog.hbox
+		 * @example
+		 */
+		vbox : function( dialog, childObjList, childHtmlList, htmlList, elementDefinition )
+		{
+			if (arguments.length < 3 )
+				return;
+
+			this._ || ( this._ = {} );
+
+			var children = this._.children = childObjList,
+				width = elementDefinition && elementDefinition.width || null,
+				heights = elementDefinition && elementDefinition.heights || null;
+			/** @ignore */
+			var innerHTML = function()
+			{
+				var html = [ '<table cellspacing="0" border="0" ' ];
+				html.push( 'style="' );
+				if ( elementDefinition.totalHeight )
+					html.push( 'height:' + fixLength( elementDefinition.totalHeight ), ';' );
+				html.push( 'width:' + fixLength( elementDefinition.width || '100%' ), ';' );
+				html.push( '"' );
+
+				html.push( '><tbody>' );
+				for ( var i = 0 ; i < childHtmlList.length ; i++ )
+				{
+					var styles = [];
+					html.push( '<tr><td ' );
+					if ( width )
+						styles.push( 'width:' + fixLength( width || '100%' ) );
+					if ( heights )
+						styles.push( 'height:' + fixLength( heights[i] ) );
+					if ( styles.length > 0 )
+						html.push( 'style="', styles.join( '; ' ), '" ' );
+					html.push( ' class="cke_dialog_ui_vbox_child">', childHtmlList[i], '</td></tr>' );
+				}
+				html.push( '</tbody></table>' );
+				return html.join( '' );
+			};
+			CKEDITOR.ui.dialog.uiElement.call( this, dialog, elementDefinition || { type : 'vbox' }, htmlList, 'div', null, null, innerHTML );
+		}
+	};
+})();
 
 CKEDITOR.ui.dialog.uiElement.prototype = 
@@ -1484,4 +1519,35 @@
 		this._.dialog.selectPage( tabId );
 		element.focus();
+	},
+
+	registerEvents : function( definition )
+	{
+		var regex = /^on([A-Z]\w+)/,
+			match,
+			registerDomEvent = function( uiElement, dialog, eventName, func )
+			{
+				dialog.on( 'load', function()
+				{
+					uiElement.getElement().on( eventName, func, uiElement );
+				});
+			};
+
+		for ( var i in definition )
+		{
+			if ( !( match = i.match( regex ) ) )
+				continue;
+			if ( this.eventProcessors[i] )
+				this.eventProcessors[i].call( this, this._.dialog, definition[i] );
+			else
+				registerDomEvent( this, this._.dialog, match[1].toLowerCase(), definition[i] );
+		}
+	},
+
+	eventProcessors : 
+	{
+		onLoad : function( dialog, func )
+		{
+			dialog.on( 'load', func, this, null, CKEDITOR.tools.getNextNumber() );
+		}
 	}
 };
Index: /CKEditor/branches/prototype/_source/plugins/dialogui/plugin.js
===================================================================
--- /CKEditor/branches/prototype/_source/plugins/dialogui/plugin.js	(revision 2601)
+++ /CKEditor/branches/prototype/_source/plugins/dialogui/plugin.js	(revision 2602)
@@ -290,6 +290,4 @@
 				// Add OnClick event to this input.
 				CKEDITOR.event.implementOn( this );
-				if ( elementDefinition.onClick )
-					this.on( 'click', elementDefinition.onClick );
 
 				// Register an event handler for processing button clicks.
@@ -396,5 +394,13 @@
 					this._.disabled = true;
 					this.getElement().addClass( 'disabled' );
-				}
+				},
+
+				eventProcessors : CKEDITOR.tools.extend( {}, CKEDITOR.ui.dialog.uiElement.prototype.eventProcessors,
+					{
+						onClick : function( dialog, func )
+						{
+							this.on( 'click', func );
+						}
+					}, true )
 			}, true );
 
Index: /CKEditor/branches/prototype/_source/plugins/toolbar/plugin.js
===================================================================
--- /CKEditor/branches/prototype/_source/plugins/toolbar/plugin.js	(revision 2601)
+++ /CKEditor/branches/prototype/_source/plugins/toolbar/plugin.js	(revision 2602)
@@ -222,4 +222,4 @@
 CKEDITOR.config.toolbar =
 [
-	[ 'Source', '-', 'Bold', 'Italic' ]
+	[ 'Source', '-', 'Bold', 'Italic', '-', 'Smiley' ]
 ];
Index: /CKEditor/branches/prototype/_source/skins/default/dialog.css
===================================================================
--- /CKEditor/branches/prototype/_source/skins/default/dialog.css	(revision 2601)
+++ /CKEditor/branches/prototype/_source/skins/default/dialog.css	(revision 2602)
@@ -212,7 +212,13 @@
 	border: #d5d59d 1px solid;
 	#width: expression(this.offsetParent.offsetWidth - 34);		/* 16px left cell + 16px right cell + 1px left border + 1px right border */
-	#height: expression(this.offsetParent.offsetHeight - 107);	/* 16px top cell + 51px bottom cell + 1px top border + 1px bottom border */
+	#height: expression(this.offsetParent.offsetHeight - 107);	/* 54px top offset + 51px bottom cell + 1px top border + 1px bottom border */
 	#bottom: default;
 	#right: default;
+}
+
+.cke_skin_default .single_page .cke_dialog_contents
+{
+	top: 31px;
+	#height: expression(this.offsetParent.offsetHeight - 84);	/* 31px top offset + 51px bottom cell + 1px top border + 1px bottom border */
 }
 
@@ -293,4 +299,9 @@
 	z-index: 1;
 	overflow: hidden;
+}
+
+.cke_skin_default .single_page .cke_dialog_tabs_bridge
+{
+	display: none;
 }
 
@@ -518,2 +529,20 @@
 	cursor: ns-resize;
 }
+
+/*
+ * Some utility CSS classes for dialog authors.
+ */
+.cke_skin_default .cke_dialog .dark_background
+{
+	background-color: #eaead1;
+}
+
+.cke_skin_default .cke_dialog .hand
+{
+	cursor: pointer;
+}
+
+.cke_skin_default .cke_dialog .centered
+{
+	text-align: center;
+}
Index: /CKEditor/branches/prototype/_source/skins/default/toolbar.css
===================================================================
--- /CKEditor/branches/prototype/_source/skins/default/toolbar.css	(revision 2601)
+++ /CKEditor/branches/prototype/_source/skins/default/toolbar.css	(revision 2602)
@@ -141,2 +141,7 @@
 	background-position: 0 -320px;
 }
+
+.cke_skin_default a.cke_button_smiley .cke_icon
+{
+	background-position: 0 -640px;
+}
