Index: /CKEditor/branches/prototype/_source/core/dom/element.js
===================================================================
--- /CKEditor/branches/prototype/_source/core/dom/element.js	(revision 2413)
+++ /CKEditor/branches/prototype/_source/core/dom/element.js	(revision 2414)
@@ -91,5 +91,7 @@
 	var temp = new CKEDITOR.dom.element( 'div', ownerDocument );
 	temp.setHtml( html );
-	return temp.getFirst();
+	var retval = temp.getFirst();
+	retval.remove();
+	return retval;
 };
 
@@ -717,4 +719,11 @@
 						}
 					}
-				}
+				},
+
+		getDisplayedStyle : function( name )
+		{
+			return this.getWindow().$.getComputedStyle ?
+				this.getWindow().$.getComputedStyle( this.$, null ).getPropertyValue( name ) :
+				this.$.currentStyle[CKEDITOR.tools.cssStyleToDomStyle( name )];
+		}
 	});
Index: /CKEditor/branches/prototype/_source/core/dom/window.js
===================================================================
--- /CKEditor/branches/prototype/_source/core/dom/window.js	(revision 2413)
+++ /CKEditor/branches/prototype/_source/core/dom/window.js	(revision 2414)
@@ -52,4 +52,32 @@
 		{
 			this.$.focus();
+		},
+
+		getViewPaneSize : function()
+		{
+			if ( 'innerWidth' in this.$ )
+				return {
+					width : this.$.innerWidth || 0,
+					height : this.$.innerHeight || 0
+				};
+			else
+				return {
+					width : this.$.document.clientWidth || this.$.document.body.clientWidth || 0,
+					height : this.$.document.clientHeight || this.$.document.body.clientHeight || 0
+				};
+		},
+
+		getScrollPosition : function()
+		{
+			if ( 'pageXOffset' in this.$ )
+				return {
+					x : this.$.pageXOffset || 0,
+					y : this.$.pageYOffset || 0
+				};
+			else
+				return {
+					x : this.$.document.documentElement.scrollLeft || this.$.document.body.scrollLeft || 0,
+					y : this.$.document.documentElement.scrollTop || this.$.document.body.scrollTop || 0
+				};
 		}
 	});
Index: /CKEditor/branches/prototype/_source/plugins/dialog/plugin.js
===================================================================
--- /CKEditor/branches/prototype/_source/plugins/dialog/plugin.js	(revision 2413)
+++ /CKEditor/branches/prototype/_source/plugins/dialog/plugin.js	(revision 2414)
@@ -45,14 +45,131 @@
 
 	dialogDefinitions : {
-		'testOnly' : function()
+		testOnly : function()
 		{
 			return {
-				'title' : 'Test Dialog',
-				'resizable' : CKEDITOR.DIALOG_RESIZE_NONE,
-				'minWidth' : 500,
-				'minHeight' : 400,
-				'contents' : []
+				title : 'Test Dialog',
+				resizable : CKEDITOR.DIALOG_RESIZE_NONE,
+				minWidth : 500,
+				minHeight : 400,
+				contents : []
 			};
 		}
+	},
+
+	storedDialogs : {},
+
+	construct : function( editor, dialogName )
+	{
+		if ( arguments.length < 2 )
+			return;
+
+		var definitions = CKEDITOR.dialog.dialogDefinitions;
+		if ( !( dialogName in definitions ) )
+		{
+			alert( 'Error: The dialog "' + dialogName + '" is not defined.' );
+			return;
+		}
+
+		this._ = {
+			editor : editor,
+			element : editor.theme.buildDialog( editor ),
+			name : dialogName,
+			definition : CKEDITOR.tools.extend( {}, CKEDITOR.dialog._.defaultDialogDefinition, definitions[dialogName]() ),
+			isShown : false,
+			size : { width : 0, height : 0 }
+		};
+		this._.dialogId = this._.element.dialogId;
+	}
+};
+
+CKEDITOR.dialog._ = {
+	defaultDialogDefinition :
+	{
+		resizable : CKEDITOR.DIALOG_RESIZE_NONE,
+		minWidth : 600,
+		minHeight : 400,
+		buttons : [CKEDITOR.dialog.okButton, CKEDITOR.dialog.cancelButton],
+		onOk : function(){alert('ok called');},
+		onCancel : function(){alert('cancel caled');},
+		onLoad : function(){alert('onload called');}
+	}
+}
+
+
+CKEDITOR.dialog.construct.prototype = {
+	resize : (function()
+	{
+		// Define the function for resizing dialog parts at load to speed up
+		// the actual resize operation.
+		var setSize = function( dialog, partName, width, height )
+		{
+			var id = dialog._.dialogId;
+			var element = CKEDITOR.document.getById( partName ? 'cke_dialog_' + partName + '_' + id : 'cke_dialog_' + id);
+			element.setStyles( {
+				width : Math.max( width || 0, 0 ) + 'px',
+				height : Math.max( height || 0, 0 ) + 'px'
+			} );
+		}
+
+		// Dialog parts dimensions.
+		//  16x16  |  ?x16  |  16x16
+		//  16x?   |  ?x?   |  16x?
+		//  30x51  |  ?x51  |  30x51
+		return function( width, height )
+		{
+			setSize( this, 'T', width - 32, 16 );
+			setSize( this, 'L', 16, height - 67 );
+			setSize( this, 'C', width - 32, height - 67 );
+			setSize( this, 'R', 16, height - 67 );
+			setSize( this, 'B', width - 60, 51 );
+			setSize( this, null, width, height );
+			this._.size = { width : width, height : height };
+		}
+	})(),
+
+	move : function( x, y )
+	{
+		// The dialog may be fixed positioned or absolute positioned. Ask the
+		// browser what is the current situation first.
+		var isFixed = this._.element.getDisplayedStyle( 'position' ) == 'fixed';
+
+		// If not fixed positioned, add scroll position to the coordinates.
+		if ( !isFixed )
+		{
+			var scrollPosition = CKEDITOR.document.getWindow().getScrollPosition();
+			x += scrollPosition.x;
+			y += scrollPosition.y;
+		}
+
+		this._.element.getFirst().setStyles(
+				{
+					'left' : x + 'px',
+					'top' : y + 'px'
+				});
+	},
+
+	show : function()
+	{
+		// Insert the dialog's element to the root document.
+		var element = this._.element;
+		var definition = this._.definition;
+		if ( !element.getParent() )
+			element.appendTo( CKEDITOR.document.getBody() );
+
+		// First, set the dialog to an appropriate size.
+		this.resize( definition.minWidth, definition.minHeight );
+
+		// Rearrange the dialog to the middle of the window.
+		var viewSize = CKEDITOR.document.getWindow().getViewPaneSize();
+		this.move( ( viewSize.width - this._.size.width ) / 2, ( viewSize.height - this._.size.height ) / 2 );
+	},
+
+	hide : function()
+	{
+		// Remove the dialog's element from the root document.
+		var element = this._.element;
+		if ( !element.getParent() )
+			return;
+		element.remove();
 	}
 };
@@ -60,36 +177,12 @@
 (function()
 {
-	var defaultDialogDefinition = {
-		'resizable' : CKEDITOR.DIALOG_RESIZE_NONE,
-		'minWidth' : 600,
-		'minHeight' : 400,
-		'buttons' : [CKEDITOR.dialog.okButton, CKEDITOR.dialog.cancelButton],
-		'onOk' : function(){alert('ok called');},
-		'onCancel' : function(){alert('cancel caled');},
-		'onLoad' : function(){alert('onload called');}
-	};
-
 	CKEDITOR.tools.extend( CKEDITOR.editor.prototype,
 		{
 			'openDialog' : function( dialogName )
 			{
-				if ( !( dialogName in CKEDITOR.dialog.dialogDefinitions) )
-				{
-					alert( 'The dialog "' + dialogName + '" is not defined.' );
-					return false;
-				}
-
-				// Add the dialog to the top document.
-				var dialogElement = this.theme.buildDialog( this ),
-					doc = CKEDITOR.document;
-				dialogElement.appendTo( doc.getBody() );
-
-				var dialogDefinition = CKEDITOR.tools.extend( {}, defaultDialogDefinition,
-					CKEDITOR.dialog.dialogDefinitions[dialogName]() );
-
-				// Resize the dialog to the minimum size.
-				this.theme.resizeDialog( this, dialogElement, dialogDefinition.minWidth, dialogDefinition.minHeight );
-
-				return true;
+				var dialog = CKEDITOR.dialog.storedDialogs[dialogName] || new CKEDITOR.dialog.construct( this, dialogName );
+				CKEDITOR.dialog.storedDialogs[dialogName] = dialog;
+				dialog.show();
+				return dialog;
 			}
 		});
Index: /CKEditor/branches/prototype/_source/skins/default/dialog.css
===================================================================
--- /CKEditor/branches/prototype/_source/skins/default/dialog.css	(revision 2413)
+++ /CKEditor/branches/prototype/_source/skins/default/dialog.css	(revision 2414)
@@ -22,5 +22,8 @@
 .cke_skin_default .cke_dialog
 {
-	position: absolute;
+	position: fixed;
+
+	/* IE6 or IE7 quirks mode do not support fixed positioning. */
+	_position: absolute;
 }
 
Index: /CKEditor/branches/prototype/_source/themes/default/theme.js
===================================================================
--- /CKEditor/branches/prototype/_source/themes/default/theme.js	(revision 2413)
+++ /CKEditor/branches/prototype/_source/themes/default/theme.js	(revision 2414)
@@ -129,15 +129,6 @@
 			].join( '' ).replace( /%d/g, dialogId ) );
 
+		container.dialogId = dialogId;
 		return container;
-	},
-
-	resizeDialog : function( editor, dialog, width, height )
-	{
-		// Just let the skin handle the resize operation.
-		this.fire( 'dialogResize', {
-					dialog : dialog,
-					width : width,
-					height : height
-				});
 	},
 
