Index: /CKEditor/branches/prototype/_source/plugins/fakeobjects/plugin.js
===================================================================
--- /CKEditor/branches/prototype/_source/plugins/fakeobjects/plugin.js	(revision 2843)
+++ /CKEditor/branches/prototype/_source/plugins/fakeobjects/plugin.js	(revision 2844)
@@ -33,14 +33,22 @@
 				var flashExtensionRegex = /\.swf($|#|\?)/i,
 					objectTypes =
-					{
-						flash : {
+					[
+						{
 							match : function( nodeName, attributes )
 							{
 								return nodeName == 'embed' && ( attributes.type == 'application/x-shockwave-flash' || flashExtensionRegex.test( attributes.src || '' ) );
 							},
-
-							cssClass : 'flash'
+							cssClass : 'flash',
+							priority : 10
+						},
+						{
+							match : function( nodeName, attributes )
+							{
+								return nodeName == 'embed' || nodeName == 'object';
+							},
+							cssClass : 'object',
+							priority : 0x100000000
 						}
-					},
+					],
 					makeTagOpenerHtml = function( tagName, attributes )
 					{
@@ -58,6 +66,21 @@
 						return decodeURIComponent( s1.substr( 1, s1.length - 2 ) );
 					},
-					namespace =
+					cssWidthRegex = /width\s*:\s*([0-9]+)\s*(?:px)?/i,
+					cssHeightRegex = /height\s*:\s*([0-9]+)\s*(?:px)?/i;
+				
+					/**
+					 * Manages element placeholders in WYSIWYG area.
+					 * @namespace
+					 * @example
+					 */
+					CKEDITOR.plugins.fakeobjects =
 					{
+						/**
+						 * Converts an element into a placeholder &lt;img&gt; element, for adding
+						 * into the WYSIWYG area.
+						 * @param {CKEDITOR.dom.element} element Input DOM element.
+						 * @returns {CKEDITOR.dom.element} The placeholder &lt;img&gt; element.
+						 * @example
+						 */
 						protectElement : function( element )
 						{
@@ -73,5 +96,5 @@
 							// Get the fake element's CSS class.
 							var cssClass = 'unknown';
-							for ( var i in objectTypes )
+							for ( var i = 0 ; i < objectTypes.length ; i++ )
 							{
 								if ( objectTypes[i].match( element.getName(), element.$ ) )
@@ -85,11 +108,29 @@
 							var fakeRawElement = doc.createElement( 'img' );
 							img.className = cssClass;
-							img.src = CKEDITOR.getUrl( 
-									'_source/' +		// TODO: Remove this in release package
-									'skins/' + editor.config.skin + '/images/spacer.gif' );
+							img.src = CKEDITOR.getUrl( 'images/spacer.gif' ); 
 							img.style.cssText = $.style.cssText;
 							return new CKEDITOR.dom.element( fakeRawElement );
 						},
 
+						/**
+						 * Converts a placeholder &lt;img&gt; element back to the real element.
+						 * @param {CKEDITOR.dom.element} fakeImgElement The placeholder &lt;img&gt;.
+						 * @returns {CKEDITOR.dom.element} The real element.
+						 * @example
+						 */
+						restoreElement : function( fakeImgElement )
+						{
+							var html = decodeURIComponent( fakeImgElement.getAttribute( '_cke_protected_html' ) ),
+								realElement = CKEDITOR.dom.element.createFromHtml( html, editor.document );
+
+							return realElement;
+						},
+
+						/**
+						 * Converts protectable elements in an HTML string to placeholders.
+						 * @param {String} html HTML with protectable elements.
+						 * @returns {String} HTML with placeholders.
+						 * @example
+						 */
 						protectHtml : function( html )
 						{
@@ -106,5 +147,5 @@
 								}
 
-								for ( var i in objectTypes )
+								for ( var i = 0 ; i < objectTypes.length ; i++ )
 								{
 									if ( objectTypes[i].match( tagName, attributes ) )
@@ -112,10 +153,16 @@
 										inProtection = true;
 										tagDepth = 1;
+
+										// Get the original object's width and height.
+										var styles = attributes.style || '',
+											widthMatch = styles.match( cssWidthRegex ) || [ 80, 80 ],
+											heightMatch = styles.match( cssHeightRegex ) || [ 80, 80 ];
+
+										// Create the fake <img> tag.
 										processedHtml.push( '<img src="',
-											CKEDITOR.getUrl(
-												'_source/' +	// TODO: Remove for release package
-												'skins/' + editor.config.skin + '/images/spacer.gif' ),
+											CKEDITOR.getUrl( 'images/spacer.gif' ),
 											'" ',
 											'class="_cke_fakeobject ' + objectTypes[i].cssClass + '" ',
+											'style="width:' + widthMatch[1] + 'px;height:' + heightMatch[1] + 'px" ',
 											'_cke_protected_html="');
 										arguments.callee.call( this, tagName, attributes );
@@ -157,4 +204,10 @@
 						},
 
+						/**
+						 * Restores placeholders in an HTML string back to their original elements.
+						 * @param {String} html HTML with placeholders.
+						 * @returns {String} Restored HTML.
+						 * @example
+						 */
 						restoreHtml : function( html )
 						{
@@ -162,11 +215,43 @@
 						},
 
-						addObjectType : function( typeName, typeHandler )
-						{
-							objectTypes.typeName = typeHandler;
+						/**
+						 * Adds an object type to be displayed by placeholders.
+						 * @param {Function} matchFunc A predicate function to determine whether
+						 * an object needs to be replaced by placeholders or not. The function
+						 * should have the following signature:
+						 * <blockquote>function( tagName, attributes )</blockquote>
+						 * In which tagName is the object's tag name, and attributes is an object
+						 * storing all the object's attributes.
+						 * @param {String} cssClass The CSS class that should be added to the
+						 * placeholder &lt;img&gt; for representing this type of object.
+						 * @param {Number} priority (Optional) An integer representing the
+						 * priority of this type of object. If an element matches the descriptions
+						 * of two object types, the object type of <strong>lower</strong> priority
+						 * takes precedance.
+						 * @example
+						 */
+						addObjectType : function( matchFunc, cssClass, priority )
+						{
+							if ( priority === undefined )
+								priority = 10;
+
+							var obj = {
+								match : matchFunc,
+								cssClass : cssClass,
+								priority : priority
+							};
+
+							for ( var i = objectTypes.length - 1 ; i >= 0 ; i-- )
+							{
+								if ( objectTypes[i].priority < priority )
+								{
+									objectTypes.splice( i + 1, 0, obj );
+									return;
+								}
+							}
+
+							objectTypes.unshift( obj );
 						}
 					};
-
-				CKEDITOR.plugins.fakeobjects = namespace;
 			}
 		} );
Index: /CKEditor/branches/prototype/contents.css
===================================================================
--- /CKEditor/branches/prototype/contents.css	(revision 2843)
+++ /CKEditor/branches/prototype/contents.css	(revision 2844)
@@ -29,2 +29,19 @@
 	background-color: #fff;
 }
+
+img._cke_fakeobject
+{
+	background-position: center center;
+	background-repeat: no-repeat;
+	border: 1px solid #a9a9a9;
+}
+
+img._cke_fakeobject.flash
+{
+	background-image: url(images/flashlogo.gif);
+}
+
+img._cke_fakeobject.object
+{
+	background-image: url(images/plugin.gif);
+}
