intrinsic min-widths don't override width for file upload controls
authorojan@chromium.org <ojan@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 10 Jan 2013 18:08:36 +0000 (18:08 +0000)
committerojan@chromium.org <ojan@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 10 Jan 2013 18:08:36 +0000 (18:08 +0000)
https://bugs.webkit.org/show_bug.cgi?id=106517

Reviewed by Tony Chang.

Source/WebCore:

Separate out computing intrinsic width from perferred width so that
we can use the intrinsic width correctly when applying min-width/max-width.
The preferred width is the width used in its container's computation
of its intrinsic width.

This is the first in a series of patches making this work across
the render tree.

Test: fast/forms/file/intrinsic-min-width-overrides-width.html

* rendering/RenderBox.cpp:
(WebCore::RenderBox::minIntrinsicLogicalWidth):
(WebCore):
(WebCore::RenderBox::maxIntrinsicLogicalWidth):
(WebCore::RenderBox::computeIntrinsicLogicalWidths):
(WebCore::RenderBox::computeLogicalWidthInRegionUsing):
* rendering/RenderBox.h:
(RenderBox):
* rendering/RenderFileUploadControl.cpp:
(WebCore::RenderFileUploadControl::computeIntrinsicLogicalWidths):
(WebCore):
(WebCore::RenderFileUploadControl::computePreferredLogicalWidths):
* rendering/RenderFileUploadControl.h:
(RenderFileUploadControl):

LayoutTests:

* fast/forms/file/intrinsic-min-width-overrides-width-expected.html: Added.
* fast/forms/file/intrinsic-min-width-overrides-width.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@139329 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/forms/file/intrinsic-min-width-overrides-width-expected.html [new file with mode: 0644]
LayoutTests/fast/forms/file/intrinsic-min-width-overrides-width.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderBox.cpp
Source/WebCore/rendering/RenderBox.h
Source/WebCore/rendering/RenderFileUploadControl.cpp
Source/WebCore/rendering/RenderFileUploadControl.h

index 660ad04..eb9db35 100644 (file)
@@ -1,3 +1,13 @@
+2013-01-09  Ojan Vafai  <ojan@chromium.org>
+
+        intrinsic min-widths don't override width for file upload controls
+        https://bugs.webkit.org/show_bug.cgi?id=106517
+
+        Reviewed by Tony Chang.
+
+        * fast/forms/file/intrinsic-min-width-overrides-width-expected.html: Added.
+        * fast/forms/file/intrinsic-min-width-overrides-width.html: Added.
+
 2013-01-10  Florin Malita  <fmalita@chromium.org>
 
         [Chromium] Unreviewed gardening.
diff --git a/LayoutTests/fast/forms/file/intrinsic-min-width-overrides-width-expected.html b/LayoutTests/fast/forms/file/intrinsic-min-width-overrides-width-expected.html
new file mode 100644 (file)
index 0000000..72aea6b
--- /dev/null
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<style>
+input {
+    background-color: pink;
+    margin: 0;
+}
+</style>
+
+<input type="file">
+<input type="file">
diff --git a/LayoutTests/fast/forms/file/intrinsic-min-width-overrides-width.html b/LayoutTests/fast/forms/file/intrinsic-min-width-overrides-width.html
new file mode 100644 (file)
index 0000000..1ba8cd6
--- /dev/null
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<style>
+.min {
+    min-width: -ie-min-content;
+    min-width: -moz-min-content;
+    min-width: -webkit-min-content;
+    min-width: min-content;
+}
+.max {
+    min-width: -ie-max-content;
+    min-width: -moz-max-content;
+    min-width: -webkit-max-content;
+    min-width: max-content;
+}
+input {
+    width: 10px;
+    background-color: pink;
+    margin: 0;
+}
+</style>
+
+<input class="min" type="file">
+<input class="max" type="file">
index f4eeb5d..b02b46b 100644 (file)
@@ -1,3 +1,35 @@
+2013-01-09  Ojan Vafai  <ojan@chromium.org>
+
+        intrinsic min-widths don't override width for file upload controls
+        https://bugs.webkit.org/show_bug.cgi?id=106517
+
+        Reviewed by Tony Chang.
+
+        Separate out computing intrinsic width from perferred width so that
+        we can use the intrinsic width correctly when applying min-width/max-width.
+        The preferred width is the width used in its container's computation
+        of its intrinsic width.
+
+        This is the first in a series of patches making this work across
+        the render tree. 
+
+        Test: fast/forms/file/intrinsic-min-width-overrides-width.html
+
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::minIntrinsicLogicalWidth):
+        (WebCore):
+        (WebCore::RenderBox::maxIntrinsicLogicalWidth):
+        (WebCore::RenderBox::computeIntrinsicLogicalWidths):
+        (WebCore::RenderBox::computeLogicalWidthInRegionUsing):
+        * rendering/RenderBox.h:
+        (RenderBox):
+        * rendering/RenderFileUploadControl.cpp:
+        (WebCore::RenderFileUploadControl::computeIntrinsicLogicalWidths):
+        (WebCore):
+        (WebCore::RenderFileUploadControl::computePreferredLogicalWidths):
+        * rendering/RenderFileUploadControl.h:
+        (RenderFileUploadControl):
+
 2013-01-10  Victor Carbune  <victor@rosedu.org>
 
         media/video-controls-captions.html fails after fixing https://bugs.webkit.org/show_bug.cgi?id=105536
index a7a8c5b..13759ea 100644 (file)
@@ -791,6 +791,28 @@ void RenderBox::applyCachedClipAndScrollOffsetForRepaint(LayoutRect& paintRect)
     paintRect = intersection(paintRect, clipRect);
 }
 
+LayoutUnit RenderBox::minIntrinsicLogicalWidth() const
+{
+    LayoutUnit minLogicalWidth = 0;
+    LayoutUnit maxLogicalWidth = 0;
+    computeIntrinsicLogicalWidths(minLogicalWidth, maxLogicalWidth);
+    return minLogicalWidth + borderAndPaddingLogicalWidth();
+}
+
+LayoutUnit RenderBox::maxIntrinsicLogicalWidth() const
+{
+    LayoutUnit minLogicalWidth = 0;
+    LayoutUnit maxLogicalWidth = 0;
+    computeIntrinsicLogicalWidths(minLogicalWidth, maxLogicalWidth);
+    return maxLogicalWidth + borderAndPaddingLogicalWidth();
+}
+
+void RenderBox::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
+{
+    minLogicalWidth = minPreferredLogicalWidth() - borderAndPaddingLogicalWidth();
+    maxLogicalWidth = maxPreferredLogicalWidth() - borderAndPaddingLogicalWidth();
+}
+
 LayoutUnit RenderBox::minPreferredLogicalWidth() const
 {
     if (preferredLogicalWidthsDirty())
@@ -1995,9 +2017,9 @@ LayoutUnit RenderBox::computeLogicalWidthInRegionUsing(SizeType widthType, Layou
     }
 
     if (logicalWidth.type() == MinContent)
-        return minPreferredLogicalWidth();
+        return minIntrinsicLogicalWidth();
     if (logicalWidth.type() == MaxContent)
-        return maxPreferredLogicalWidth();
+        return maxIntrinsicLogicalWidth();
 
     RenderView* renderView = view();
     LayoutUnit marginStart = minimumValueForLength(styleToUse->marginStart(), availableLogicalWidth, renderView);
index ab4ba6b..cd1c7ac 100644 (file)
@@ -294,6 +294,9 @@ public:
     virtual void paint(PaintInfo&, const LayoutPoint&);
     virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE;
 
+    LayoutUnit minIntrinsicLogicalWidth() const;
+    LayoutUnit maxIntrinsicLogicalWidth() const;
+
     virtual LayoutUnit minPreferredLogicalWidth() const;
     virtual LayoutUnit maxPreferredLogicalWidth() const;
 
@@ -650,6 +653,8 @@ private:
     void computePositionedLogicalHeightReplaced(LogicalExtentComputedValues&) const;
     void computePositionedLogicalWidthReplaced(LogicalExtentComputedValues&) const;
 
+    virtual void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const;
+
     // This function calculates the minimum and maximum preferred widths for an object.
     // These values are used in shrink-to-fit layout systems.
     // These include tables, positioned objects, floats and flexible boxes.
index da08493..098442f 100644 (file)
@@ -164,6 +164,28 @@ void RenderFileUploadControl::paintObject(PaintInfo& paintInfo, const LayoutPoin
     RenderBlock::paintObject(paintInfo, paintOffset);
 }
 
+void RenderFileUploadControl::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
+{
+    // Figure out how big the filename space needs to be for a given number of characters
+    // (using "0" as the nominal character).
+    const UChar character = '0';
+    const String characterAsString = String(&character, 1);
+    const Font& font = style()->font();
+    // FIXME: Remove the need for this const_cast by making constructTextRun take a const RenderObject*.
+    RenderFileUploadControl* renderer = const_cast<RenderFileUploadControl*>(this);
+    float minDefaultLabelWidth = defaultWidthNumChars * font.width(constructTextRun(renderer, font, characterAsString, style(), TextRun::AllowTrailingExpansion));
+
+    const String label = theme()->fileListDefaultLabel(node()->toInputElement()->multiple());
+    float defaultLabelWidth = font.width(constructTextRun(renderer, font, label, style(), TextRun::AllowTrailingExpansion));
+    if (HTMLInputElement* button = uploadButton())
+        if (RenderObject* buttonRenderer = button->renderer())
+            defaultLabelWidth += buttonRenderer->maxPreferredLogicalWidth() + afterButtonSpacing;
+    maxLogicalWidth = static_cast<int>(ceilf(max(minDefaultLabelWidth, defaultLabelWidth)));
+
+    if (!style()->width().isPercent())
+        minLogicalWidth = maxLogicalWidth;
+}
+
 void RenderFileUploadControl::computePreferredLogicalWidths()
 {
     ASSERT(preferredLogicalWidthsDirty());
@@ -171,38 +193,19 @@ void RenderFileUploadControl::computePreferredLogicalWidths()
     m_minPreferredLogicalWidth = 0;
     m_maxPreferredLogicalWidth = 0;
 
-    RenderStyle* style = this->style();
-    ASSERT(style);
-
-    const Font& font = style->font();
-    if (style->width().isFixed() && style->width().value() > 0)
-        m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = adjustContentBoxLogicalWidthForBoxSizing(style->width().value());
-    else {
-        // Figure out how big the filename space needs to be for a given number of characters
-        // (using "0" as the nominal character).
-        const UChar character = '0';
-        const String characterAsString = String(&character, 1);
-        float minDefaultLabelWidth = defaultWidthNumChars * font.width(constructTextRun(this, font, characterAsString, style, TextRun::AllowTrailingExpansion));
-
-        const String label = theme()->fileListDefaultLabel(node()->toInputElement()->multiple());
-        float defaultLabelWidth = font.width(constructTextRun(this, font, label, style, TextRun::AllowTrailingExpansion));
-        if (HTMLInputElement* button = uploadButton())
-            if (RenderObject* buttonRenderer = button->renderer())
-                defaultLabelWidth += buttonRenderer->maxPreferredLogicalWidth() + afterButtonSpacing;
-        m_maxPreferredLogicalWidth = static_cast<int>(ceilf(max(minDefaultLabelWidth, defaultLabelWidth)));
-
-        if (!style->width().isPercent())
-            m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth;
-    }
+    if (style()->width().isFixed() && style()->width().value() > 0)
+        m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = adjustContentBoxLogicalWidthForBoxSizing(style()->width().value());
+    else
+        computeIntrinsicLogicalWidths(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
 
-    if (style->minWidth().isFixed() && style->minWidth().value() > 0) {
-        m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style->minWidth().value()));
-        m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style->minWidth().value()));
+    if (style()->minWidth().isFixed() && style()->minWidth().value() > 0) {
+        m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style()->minWidth().value()));
+        m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style()->minWidth().value()));
     }
 
-    if (style->maxWidth().isFixed()) {
-        m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style->maxWidth().value()));
-        m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style->maxWidth().value()));
+    if (style()->maxWidth().isFixed()) {
+        m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style()->maxWidth().value()));
+        m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style()->maxWidth().value()));
     }
 
     int toAdd = borderAndPaddingWidth();
index 2ce4ca6..89453f4 100644 (file)
@@ -46,6 +46,7 @@ private:
 
     virtual bool canBeReplacedWithInlineRunIn() const OVERRIDE;
     virtual void updateFromElement();
+    virtual void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const OVERRIDE;
     virtual void computePreferredLogicalWidths();
     virtual void paintObject(PaintInfo&, const LayoutPoint&);