Index: /CKEditor/branches/prototype/_source/plugins/dialog/plugin.js
===================================================================
--- /CKEditor/branches/prototype/_source/plugins/dialog/plugin.js	(revision 2454)
+++ /CKEditor/branches/prototype/_source/plugins/dialog/plugin.js	(revision 2455)
@@ -52,12 +52,15 @@
 
 	// Initialize some basic parameters.
-	this._ = {
-		editor : editor,
-		element : editor.theme.buildDialog( editor ),
-		name : dialogName,
-		definition : definition,
-		isShown : false,
-		size : { width : 0, height : 0 }
-	};
+	if ( !this._ )
+		this._ = {};
+	CKEDITOR.tools.extend( this._, {
+			editor : editor,
+			element : editor.theme.buildDialog( editor ),
+			name : dialogName,
+			definition : definition,
+			isShown : false,
+			size : { width : 0, height : 0 },
+			contents : {}
+		});
 
 	// Initialize the parts map.
@@ -109,5 +112,6 @@
 }
 
-CKEDITOR.dialog.prototype = {
+CKEDITOR.dialog.prototype = 
+{
 	resize : (function()
 	{
@@ -201,5 +205,5 @@
 			if ( !builder )
 				continue;
-			builder.build( item, pageHtml );
+			builder.build( this, item, pageHtml );
 		}
 		pageHtml.push( '</div>' );
@@ -263,5 +267,5 @@
 		cancelButton : null,
 
-		addUIElement: function( typeName, builder )
+		addUIElement : function( typeName, builder )
 		{
 			this._.uiElementBuilders[typeName] = builder;
@@ -271,5 +275,6 @@
 	});
 
-CKEDITOR.dialog._ = {
+CKEDITOR.dialog._ = 
+{
 	defaultDialogDefinition :
 	{
@@ -301,5 +306,5 @@
 						elements : [
 							{
-								type : 'hbox',
+								type : 'vbox',
 								children : []
 							}
@@ -314,5 +319,5 @@
 						elements : [
 							{
-								type : 'hbox',
+								type : 'vbox',
 								children : []
 							}
@@ -327,5 +332,5 @@
 						elements : [
 							{
-								type : 'hbox',
+								type : 'vbox',
 								children : []
 							}
@@ -338,81 +343,218 @@
 };
 
+CKEDITOR.ui.dialog = 
+{
+	uiElement : function( dialog, elementDefinition, htmlList, nodeNameArg, stylesArg, attributesArg, contentsArg )
+	{
+		if (arguments.length < 4 )
+			return;
+
+		var id = this.id = elementDefinition.id,
+			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( elementDefinition ) : contentsArg ) || '';
+
+		// Set the id.
+		if ( id )
+		{
+			html.push( 'id="' + id + '" ' );
+			dialog._.contents[id] = this;
+		}
+
+		// Set the type and definition CSS class names.
+		var classes = {};
+		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 ( var i = 0 ; i < attributeClasses.length ; i++ )
+		{
+			if ( attributeClasses[i] )
+				classes[ attributeClasses[i] ] = 1;
+		}
+		var finalClasses = [];
+		for ( var i in classes )
+			finalClasses.push( i );
+		attributes.class = finalClasses.join( ' ' );
+
+		// Write the inline CSS styles.
+		html.push( 'style="' );
+		for ( var i in styles )
+			html.push( i + ':' + styles[i] + ';' );
+		html.push( '" ' );
+
+		// Write the attributes.
+		for ( var 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( '' ) );
+	},
+
+	hbox : function( dialog, elementDefinition, htmlList, stylesArg, attributesArg )
+	{
+		if (arguments.length < 3 )
+			return;
+
+		if ( !this._ )
+			this._ = {};
+		var children = this._.children = [];
+		var innerHTML = function( innerDefinition )
+		{
+			var html = [];
+			for ( var i = 0 ; i < innerDefinition.children.length ; i++ )
+			{
+				var child = innerDefinition.children[i],
+					type = child.type;
+				html.push( '<div style="float:left;' );
+				if ( innerDefinition.widths && isFinite( parseFloat( innerDefinition.widths[i] ) ) )
+					html.push( 'width:' + innerDefinition.widths[i] + 'px;' );
+				if ( innerDefinition.height && isFinite( parseFloat( innerDefinition.height ) ) )
+					html.push( 'height:' + innerDefinition.height + 'px;' );
+				html.push( '">' );
+				children.push( CKEDITOR.dialog._.uiElementBuilders[type].build( dialog, child, html ) );
+				html.push( '</div>' );
+			}
+			return html.join( '' );
+		}
+		CKEDITOR.ui.dialog.uiElement.call(this, dialog, elementDefinition, htmlList, 'div', stylesArg, attributesArg, innerHTML );
+	},
+
+	vbox : function( dialog, elementDefinition, htmlList, stylesArg, attributesArg )
+	{
+		if (arguments.length < 3 )
+			return;
+
+		if ( !this._ )
+			this._ = {};
+		var children = this._.children = [];
+		var innerHTML = function( innerDefinition )
+		{
+			var html = [];
+			for ( var i = 0 ; i < innerDefinition.children.length ; i++ )
+			{
+				var child = innerDefinition.children[i],
+					type = child.type;
+				html.push( '<div style="' );
+				if ( innerDefinition.width && isFinite( parseFloat( innerDefinition.width ) ) )
+					html.push( 'width:' + innerDefinition.width + 'px;' );
+				if ( innerDefinition.heights && isFinite( parseFloat( innerDefinition.heights[i] ) ) )
+					html.push( 'height:' + innerDefinition.heights[i] + 'px;' );
+				html.push( '">' );
+				children.push( CKEDITOR.dialog._.uiElementBuilders[type].build( dialog, child, html ) );
+				html.push( '</div>' );
+			}
+			return html.join( '' );
+		}
+		CKEDITOR.ui.dialog.uiElement.call(this, dialog, elementDefinition, htmlList, 'div', stylesArg, attributesArg, innerHTML );
+	}
+};
+
+CKEDITOR.ui.dialog.uiElement.prototype = 
+{
+	getElement: function()
+	{
+		return CKEDITOR.document.getById( this.id );
+	},
+
+	setValue : function( value )
+	{
+		this.getElement().value = value;
+	},
+
+	getValue : function()
+	{
+		return this.getElement().value;
+	},
+
+	isChanged : function()
+	{
+		// Override in subclasses.
+		return false;
+	},
+
+	focus : function()
+	{
+		this.getElement().focus();
+	}
+};
+
+CKEDITOR.ui.dialog.hbox.prototype = CKEDITOR.tools.extend(new CKEDITOR.ui.dialog.uiElement,
+	{
+		setValue : function( value )
+		{
+			var len = Math.min( value.length, this._.children.length );
+			for ( var i = 0 ; i < len ; i++ )
+				this._.children[i].setValue( value[i] );
+		},
+
+		getValue : function()
+		{
+			var retval = [];
+			for ( var i = 0 ; i < this._.children.length ; i++ )
+				retval.push( this._.children[i].getValue() );
+			return retval;
+		},
+
+		isChanged : function()
+		{
+			var retval = false;
+			for ( var i = 0 ; i < this._.children.length ; i++ )
+				retval |= this._.children[i].isChanged();
+			return retval;
+		},
+
+		focus : function()
+		{
+			this.getElement().focus();
+		},
+
+		getChild : function( indices )
+		{
+			if ( !indices.splice )
+				indices = [ indices ];
+			if ( indices.length < 2 )
+				return this._.children[ indices[0] ];
+			else
+				return ( this._.children[ indices[0] ] && this._.children[ indices[0] ].getChild ) ?
+					this._.children[ indices[0] ].getChild( indices.slice( 1, indices.length ) ) :
+					null;
+		}
+	});
+
+CKEDITOR.ui.dialog.vbox.prototype = CKEDITOR.ui.dialog.hbox.prototype;
+
+CKEDITOR.tools.extend( CKEDITOR.editor.prototype,
+	{
+		openDialog : function( dialogName )
+		{
+			var dialog = CKEDITOR.dialog.storedDialogs[dialogName] || new CKEDITOR.dialog( this, dialogName );
+			CKEDITOR.dialog.storedDialogs[dialogName] = dialog;
+			dialog.show();
+			return dialog;
+		}
+	});
+
 (function()
 {
-	CKEDITOR.tools.extend( CKEDITOR.editor.prototype,
-		{
-			'openDialog' : function( dialogName )
+	CKEDITOR.dialog.addUIElement( 'hbox',
 			{
-				var dialog = CKEDITOR.dialog.storedDialogs[dialogName] || new CKEDITOR.dialog( this, dialogName );
-				CKEDITOR.dialog.storedDialogs[dialogName] = dialog;
-				dialog.show();
-				return dialog;
-			}
-		});
+				build : function( dialog, elementDefinition, output )
+				{
+					return new CKEDITOR.ui.dialog.hbox( dialog, elementDefinition, output );
+				}
+			});
+
+	CKEDITOR.dialog.addUIElement( 'vbox',
+			{
+				build : function( dialog, elementDefinition, output )
+				{
+					return new CKEDITOR.ui.dialog.vbox( dialog, elementDefinition, output );
+				}
+			});
 })();
-
-CKEDITOR.dialog.addUIElement( 'hbox',
-		{
-			build : function( elementDefinition, output )
-			{
-				var id = 'cke_dialog_hbox_' + CKEDITOR.tools.getNextNumber(),
-					html = [ '<div id="', id, '">' ],
-					children = [];
-				for ( var i = 0 ; i < elementDefinition.children.length ; i++ )
-				{
-					var child = elementDefinition.children[i],
-						type = child.type;
-					html.push( '<div style="float:left;' );
-					if ( elementDefinition.widths && isFinite( parseFloat( elementDefinition.widths[i] ) ) )
-						html.push( 'width:', elementDefinition.widths[i], 'px;' );
-					if ( elementDefinition.height && isFinite( parseFloat( elementDefinition.height ) ) )
-						html.push( 'height:', elementDefinition.height, 'px;' )
-					html.push( '">' );
-					children.push( this._.uiElementBuilders[type].build( child, html ) );
-					html.push( '</div>' );
-				}
-				html.push( '</div>' );
-				output.push( html.join( '' ) );
-				return {
-					setValue : function( value )
-					{
-						var len = Math.min( value.length, children.length );
-						for ( var i = 0 ; i < len ; i++ )
-							children[i].setValue( value[i] );
-					},
-
-					getValue : function()
-					{
-						var retval = [];
-						for ( var i = 0 ; i < children.length ; i++ )
-							retval.push( children[i].getValue() );
-						return retval;
-					},
-
-					isChanged : function()
-					{
-						var retval = false;
-						for ( var i = 0 ; i < children.length ; i++ )
-							retval |= children[i].isChanged();
-						return retval;
-					},
-
-					focus : function()
-					{
-						CKEDITOR.document.getById( id ).focus();
-					},
-
-					getChild : function( indices )
-					{
-						if ( !indices.splice )
-							indices = [ indices ];
-						if ( indices.length < 2 )
-							return children[ indices[0] ];
-						else
-							return ( children[ indices[0] ] && children[ indices[0] ].getChild ) ?
-								children[ indices[0] ].getChild( indices.slice( 1, indices.length ) ) :
-								null;
-					}
-				};
-			}
-		});
