Index: tests/Popup/Anchored.html
===================================================================
--- tests/Popup/Anchored.html	(revision 7884)
+++ tests/Popup/Anchored.html	(working copy)
@@ -13,7 +13,7 @@
         t.ok( popup instanceof OpenLayers.Popup.Anchored, "new OpenLayers.Popup.Anchored returns Popup.Anchored object" );
         t.ok(popup.id.startsWith("OpenLayers.Popup.Anchored"), "valid default popupid");
         var firstID = popup.id;
-        t.eq(popup.contentHTML, "", "good default popup.contentHTML");
+        t.eq(popup.contentHTML, null, "good default popup.contentHTML");
 
         
         popup = new OpenLayers.Popup.Anchored();
Index: tests/Popup.html
===================================================================
--- tests/Popup.html	(revision 7884)
+++ tests/Popup.html	(working copy)
@@ -17,7 +17,7 @@
              "valid default popupid");
         var firstID = popup.id;
         t.ok(popup.size.equals(size), "good default popup.size");
-        t.eq(popup.contentHTML, "", "good default popup.contentHTML");
+        t.eq(popup.contentHTML, null, "good default popup.contentHTML");
         t.eq(popup.backgroundColor, OpenLayers.Popup.COLOR, "good default popup.backgroundColor");
         t.eq(popup.opacity, OpenLayers.Popup.OPACITY, "good default popup.opacity");
         t.eq(popup.border, OpenLayers.Popup.BORDER, "good default popup.border");
Index: lib/OpenLayers/Popup.js
===================================================================
--- lib/OpenLayers/Popup.js	(revision 7884)
+++ lib/OpenLayers/Popup.js	(working copy)
@@ -55,9 +55,9 @@
 
     /** 
      * Property: contentHTML 
-     * {String} The HTML that this popup displays.
+     * {String} An HTML string for this popup to display.
      */
-    contentHTML: "",
+    contentHTML: null,
     
     /** 
      * Property: backgroundColor 
@@ -184,7 +184,7 @@
     * lonlat - {<OpenLayers.LonLat>}  The position on the map the popup will
     *                                 be shown.
     * size - {<OpenLayers.Size>}      The size of the popup.
-    * contentHTML - {String}          The HTML content to display inside the 
+    * contentHTML - {String}          An HTML string to display inside the   
     *                                 popup.
     * closeBox - {Boolean}            Whether to display a close box inside
     *                                 the popup.
@@ -448,6 +448,78 @@
     },  
 
     /**
+     * APIMethod: updateSize
+     * Auto size the popup so that it precisely fits its contents (as 
+     *     determined by this.contentDiv.innerHTML). Popup size will, of
+     *     course, be limited by the available space on the current map
+     */
+    updateSize: function() {
+        
+        // determine actual render dimensions of the contents by putting its
+        // contents into a fake contentDiv (for the CSS) and then measuring it
+        var preparedHTML = "<div class='" + this.contentDisplayClass+ "'>" + 
+            this.contentDiv.innerHTML + 
+            "<div>";
+        var realSize = OpenLayers.Util.getRenderedDimensions(
+            preparedHTML, null, { displayClass: this.displayClass }
+        );
+
+        // is the "real" size of the div is safe to display in our map?
+        var safeSize = this.getSafeContentSize(realSize);
+
+        var newSize = null;
+        if (safeSize.equals(realSize)) {
+            //real size of content is small enough to fit on the map, 
+            // so we use real size.
+            newSize = realSize;
+
+        } else {
+
+            //make a new OL.Size object with the clipped dimensions 
+            // set or null if not clipped.
+            var fixedSize = new OpenLayers.Size();
+            fixedSize.w = (safeSize.w < realSize.w) ? safeSize.w : null;
+            fixedSize.h = (safeSize.h < realSize.h) ? safeSize.h : null;
+        
+            if (fixedSize.w && fixedSize.h) {
+                //content is too big in both directions, so we will use 
+                // max popup size (safeSize), knowing well that it will 
+                // overflow both ways.                
+                newSize = safeSize;
+            } else {
+                //content is clipped in only one direction, so we need to 
+                // run getRenderedDimensions() again with a fixed dimension
+                var clippedSize = OpenLayers.Util.getRenderedDimensions(
+                    preparedHTML, fixedSize, 
+                    { displayClass: this.contentDisplayClass }
+                );
+                
+                //if the clipped size is still the same as the safeSize, 
+                // that means that our content must be fixed in the 
+                // offending direction. If overflow is 'auto', this means 
+                // we are going to have a scrollbar for sure, so we must 
+                // adjust for that.
+                //
+                var currentOverflow = OpenLayers.Element.getStyle(
+                    this.contentDiv, "overflow"
+                );
+                if ( (currentOverflow != "hidden") && 
+                     (clippedSize.equals(safeSize)) ) {
+                    var scrollBar = OpenLayers.Util.getScrollbarWidth();
+                    if (fixedSize.w) {
+                        clippedSize.h += scrollBar;
+                    } else {
+                        clippedSize.w += scrollBar;
+                    }
+                }
+                
+                newSize = this.getSafeContentSize(clippedSize);
+            }
+        }                        
+        this.setSize(newSize);     
+    },    
+
+    /**
      * Method: setBackgroundColor
      * Sets the background color of the popup.
      *
@@ -511,79 +583,20 @@
      */
     setContentHTML:function(contentHTML) {
 
-        var preparedHTML;
         if (contentHTML != null) {
             this.contentHTML = contentHTML;
         }
        
+        if ((this.contentDiv != null) && 
+            (this.contentHTML != null) &&
+            (this.contentHTML != this.contentDiv.innerHTML)) {
+            this.contentDiv.innerHTML = this.contentHTML;
+        }    
+
         if (this.autoSize) {
-            //fake the contentDiv for the CSS context
-            preparedHTML = "<div class='" + this.contentDisplayClass+ "'>" + this.contentHTML + "<div>";
- 
-            // determine actual render dimensions of the contents
-            var realSize = 
-                OpenLayers.Util.getRenderedDimensions(preparedHTML, null, 
-                    { displayClass: this.displayClass });
+            this.updateSize();
+        }
 
-            // is the "real" size of the div is safe to display in our map?
-            var safeSize = this.getSafeContentSize(realSize);
-
-            var newSize = null;
-             
-            if (safeSize.equals(realSize)) {
-                //real size of content is small enough to fit on the map, 
-                // so we use real size.
-                newSize = realSize;
-
-            } else {
-
-                //make a new OL.Size object with the clipped dimensions 
-                // set or null if not clipped.
-                var fixedSize = new OpenLayers.Size();
-                fixedSize.w = (safeSize.w < realSize.w) ? safeSize.w : null;
-                fixedSize.h = (safeSize.h < realSize.h) ? safeSize.h : null;
-            
-                if (fixedSize.w && fixedSize.h) {
-                    //content is too big in both directions, so we will use 
-                    // max popup size (safeSize), knowing well that it will 
-                    // overflow both ways.                
-                    newSize = safeSize;
-                } else {
-                    //content is clipped in only one direction, so we need to 
-                    // run getRenderedDimensions() again with a fixed dimension
-                    var clippedSize = OpenLayers.Util.getRenderedDimensions(
-                        preparedHTML, fixedSize, 
-                        { displayClass: this.contentDisplayClass }
-                    );
-                    
-                    //if the clipped size is still the same as the safeSize, 
-                    // that means that our content must be fixed in the 
-                    // offending direction. If overflow is 'auto', this means 
-                    // we are going to have a scrollbar for sure, so we must 
-                    // adjust for that.
-                    //
-                    var currentOverflow = OpenLayers.Element.getStyle(
-                        this.contentDiv, "overflow"
-                    );
-                    if ( (currentOverflow != "hidden") && 
-                         (clippedSize.equals(safeSize)) ) {
-                        var scrollBar = OpenLayers.Util.getScrollbarWidth();
-                        if (fixedSize.w) {
-                            clippedSize.h += scrollBar;
-                        } else {
-                            clippedSize.w += scrollBar;
-                        }
-                    }
-                    
-                    newSize = this.getSafeContentSize(clippedSize);
-                }
-            }                        
-            this.setSize(newSize);     
-        }        
-
-        if (this.contentDiv != null) {
-            this.contentDiv.innerHTML = this.contentHTML;
-        }    
     },
     
 
