Percentage width replaced element incorrectly rendered when intrinsic size changed
https://bugs.webkit.org/show_bug.cgi?id=102784

Patch by KyungTae Kim <ktf.kim@samsung.com> on 2012-12-17
Reviewed by Tony Chang.

Source/WebCore:

To make relayout when the image dimension is changed,
and if the logical width is percent type and the containing block fits to it.
In this case, the containing block's width need to be updated first,
because the 'newWidth' was calculated from the 'old containing block width'.

Test: fast/css/percent-width-img-src-change.html

* rendering/RenderImage.cpp:
(WebCore::RenderImage::imageDimensionsChanged):

LayoutTests:

Add test to check when the source of images with percentage width is changed.

* fast/css/percent-width-img-src-change.html: Added.
* fast/css/percent-width-img-src-change-expected.txt: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@137960 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/rendering/RenderImage.cpp b/Source/WebCore/rendering/RenderImage.cpp
index c3bcf3a..a479735 100644
--- a/Source/WebCore/rendering/RenderImage.cpp
+++ b/Source/WebCore/rendering/RenderImage.cpp
@@ -228,7 +228,15 @@
         computeLogicalHeight(height(), 0, computedValues);
         LayoutUnit newHeight = computedValues.m_extent;
 
-        if (imageSizeChanged || width() != newWidth || height() != newHeight) {
+        // FIXME: We only need to recompute the containing block's preferred size
+        // if the containing block's size depends on the image's size (i.e., the container uses shrink-to-fit sizing).
+        // There's no easy way to detect that shrink-to-fit is needed, always force a layout.
+        bool containingBlockNeedsToRecomputePreferredSize =
+            style()->logicalWidth().type() == Percent
+            || style()->logicalMaxWidth().type() == Percent
+            || style()->logicalMinWidth().type() == Percent;
+
+        if (imageSizeChanged || width() != newWidth || height() != newHeight || containingBlockNeedsToRecomputePreferredSize) {
             shouldRepaint = false;
             if (!selfNeedsLayout())
                 setNeedsLayout(true);