Setting width overrides intrinsic min-width/max-width on flexboxes and their subclasses
authorojan@chromium.org <ojan@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 12 Jan 2013 02:21:28 +0000 (02:21 +0000)
committerojan@chromium.org <ojan@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 12 Jan 2013 02:21:28 +0000 (02:21 +0000)
https://bugs.webkit.org/show_bug.cgi?id=106617

Reviewed by Tony Chang.

Source/WebCore:

Override computeIntrinsicLogicalWidths for all RenderFlexibleBox and RenderDeprecatedFlexibleBox
classes that override computePreferredLogicalWidths so that RenderBox can use
computeIntrinsicLogicalWidths in order to get the correct intrinsic values.

Tests: css3/flexbox/intrinsic-min-width-applies-with-fixed-width.html
       fast/flexbox/intrinsic-min-width-applies-with-fixed-width.html
       fast/forms/select/intrinsic-min-width-applies-with-fixed-width.html

* rendering/RenderBox.cpp:
(WebCore::RenderBox::computeLogicalWidthInRegionUsing):
fit-content needs to use the intrinsic sizes not the preferred sizes
since a fixed width overrides the preferred size.
As best I can tell, the sizesLogicalWidthToFitContent codepath can keep
using preferred widths, which are considerably faster, since that's only used
computing width values. Added a clause to that if-statement to make this more
explicit.

* rendering/RenderDeprecatedFlexibleBox.cpp:
(WebCore::RenderDeprecatedFlexibleBox::computeIntrinsicLogicalWidths):
(WebCore::RenderDeprecatedFlexibleBox::computePreferredLogicalWidths):
* rendering/RenderDeprecatedFlexibleBox.h:
(RenderDeprecatedFlexibleBox):
* rendering/RenderFlexibleBox.cpp:
(WebCore::RenderFlexibleBox::computeIntrinsicLogicalWidths):
(WebCore):
(WebCore::RenderFlexibleBox::computePreferredLogicalWidths):
* rendering/RenderFlexibleBox.h:
* rendering/RenderMenuList.cpp:
(WebCore::RenderMenuList::computeIntrinsicLogicalWidths):
(WebCore):
(WebCore::RenderMenuList::computePreferredLogicalWidths):
* rendering/RenderMenuList.h:
(RenderMenuList):
* rendering/RenderSlider.cpp:
(WebCore::RenderSlider::computeIntrinsicLogicalWidths):
(WebCore):
(WebCore::RenderSlider::computePreferredLogicalWidths):
* rendering/RenderSlider.h:
(RenderSlider):
No logic changes in any of these computeIntrinsic methods. Just moving
the code over from the computePreferred methods.

LayoutTests:

* css3/flexbox/intrinsic-min-width-applies-with-fixed-width-expected.txt: Added.
* css3/flexbox/intrinsic-min-width-applies-with-fixed-width.html: Added.
* fast/flexbox/intrinsic-min-width-applies-with-fixed-width-expected.txt: Added.
* fast/flexbox/intrinsic-min-width-applies-with-fixed-width.html: Added.
* fast/forms/select/intrinsic-min-width-applies-with-fixed-width-expected.html: Added.
* fast/forms/select/intrinsic-min-width-applies-with-fixed-width.html: Added.

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

17 files changed:
LayoutTests/ChangeLog
LayoutTests/css3/flexbox/intrinsic-min-width-applies-with-fixed-width-expected.txt [new file with mode: 0644]
LayoutTests/css3/flexbox/intrinsic-min-width-applies-with-fixed-width.html [new file with mode: 0644]
LayoutTests/fast/flexbox/intrinsic-min-width-applies-with-fixed-width-expected.txt [new file with mode: 0644]
LayoutTests/fast/flexbox/intrinsic-min-width-applies-with-fixed-width.html [new file with mode: 0644]
LayoutTests/fast/forms/select/intrinsic-min-width-applies-with-fixed-width-expected.html [new file with mode: 0644]
LayoutTests/fast/forms/select/intrinsic-min-width-applies-with-fixed-width.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderBox.cpp
Source/WebCore/rendering/RenderDeprecatedFlexibleBox.cpp
Source/WebCore/rendering/RenderDeprecatedFlexibleBox.h
Source/WebCore/rendering/RenderFlexibleBox.cpp
Source/WebCore/rendering/RenderFlexibleBox.h
Source/WebCore/rendering/RenderMenuList.cpp
Source/WebCore/rendering/RenderMenuList.h
Source/WebCore/rendering/RenderSlider.cpp
Source/WebCore/rendering/RenderSlider.h

index 279b502..a647547 100644 (file)
@@ -1,3 +1,17 @@
+2013-01-10  Ojan Vafai  <ojan@chromium.org>
+
+        Setting width overrides intrinsic min-width/max-width on flexboxes and their subclasses
+        https://bugs.webkit.org/show_bug.cgi?id=106617
+
+        Reviewed by Tony Chang.
+
+        * css3/flexbox/intrinsic-min-width-applies-with-fixed-width-expected.txt: Added.
+        * css3/flexbox/intrinsic-min-width-applies-with-fixed-width.html: Added.
+        * fast/flexbox/intrinsic-min-width-applies-with-fixed-width-expected.txt: Added.
+        * fast/flexbox/intrinsic-min-width-applies-with-fixed-width.html: Added.
+        * fast/forms/select/intrinsic-min-width-applies-with-fixed-width-expected.html: Added.
+        * fast/forms/select/intrinsic-min-width-applies-with-fixed-width.html: Added.
+
 2013-01-11  James Craig  <james@cookiecrook.com>
 
         Need new accessibility layout test to verify levels of headings
diff --git a/LayoutTests/css3/flexbox/intrinsic-min-width-applies-with-fixed-width-expected.txt b/LayoutTests/css3/flexbox/intrinsic-min-width-applies-with-fixed-width-expected.txt
new file mode 100644 (file)
index 0000000..e5f329b
--- /dev/null
@@ -0,0 +1,8 @@
+Check that min-width intrinsic size still applies if a fixed width is set.
+
+PASS
+PASS
+PASS
+PASS
+ PASS
+
diff --git a/LayoutTests/css3/flexbox/intrinsic-min-width-applies-with-fixed-width.html b/LayoutTests/css3/flexbox/intrinsic-min-width-applies-with-fixed-width.html
new file mode 100644 (file)
index 0000000..253662a
--- /dev/null
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<style>
+.min-content {
+    width: 10px;
+    min-width: -webkit-min-content;
+    min-width: -moz-min-content;
+    min-width: -ie-min-content;
+    min-width: -o-min-content;
+    min-width: min-content;
+    outline: 2px solid;
+    display: -webkit-flex;
+    -webkit-flex-wrap: wrap;
+}
+.max-content {
+    width: 10px;
+    min-width: -webkit-max-content;
+    min-width: -moz-max-content;
+    min-width: -ie-max-content;
+    min-width: -o-max-content;
+    min-width: max-content;
+    outline: 2px solid;
+    display: -webkit-flex;
+    -webkit-flex-wrap: wrap;
+}
+.fit-content {
+    width: 10px;
+    min-width: -webkit-fit-content;
+    min-width: -moz-fit-content;
+    min-width: -ie-fit-content;
+    min-width: -o-fit-content;
+    min-width: fit-content;
+    outline: 2px solid;
+    display: -webkit-flex;
+    -webkit-flex-wrap: wrap;
+}
+.child {
+    width: 20px;
+    height: 20px;
+    background-color: pink;
+}
+div {
+    display: inline-block;
+    line-height: 0;
+}
+</style>
+<script src="../../resources/check-layout.js"></script>
+
+<body onload="checkLayout('body > div')">
+<p>Check that min-width intrinsic size still applies if a fixed width is set.</p>
+
+<div class="min-content" data-expected-width=20>
+    <div class="child"></div><div class="child"></div>
+</div>
+
+<div class="max-content" data-expected-width=40>
+    <div class="child"></div><div class="child"></div>
+</div>
+
+<div class="fit-content" data-expected-width=40>
+    <div class="child"></div><div class="child"></div>
+</div>
+
+<div style="width: 30px">
+    <div class="fit-content" data-expected-width=30>
+        <div class="child"></div><div class="child"></div>
+    </div>
+</div>
+
+<div style="width: 10px">
+    <div class="fit-content" data-expected-width=20>
+        <div class="child"></div><div class="child"></div>
+    </div>
+</div>
+
+</body>
diff --git a/LayoutTests/fast/flexbox/intrinsic-min-width-applies-with-fixed-width-expected.txt b/LayoutTests/fast/flexbox/intrinsic-min-width-applies-with-fixed-width-expected.txt
new file mode 100644 (file)
index 0000000..81b0d9b
--- /dev/null
@@ -0,0 +1,8 @@
+Check that min-width intrinsic size still applies if a fixed width is set.
+
+ PASS
+ PASS
+ PASS
+ PASS
+ PASS
+
diff --git a/LayoutTests/fast/flexbox/intrinsic-min-width-applies-with-fixed-width.html b/LayoutTests/fast/flexbox/intrinsic-min-width-applies-with-fixed-width.html
new file mode 100644 (file)
index 0000000..0482f39
--- /dev/null
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<style>
+.min-content {
+    width: 10px;
+    min-width: -webkit-min-content;
+    min-width: -moz-min-content;
+    min-width: -ie-min-content;
+    min-width: -o-min-content;
+    min-width: min-content;
+    outline: 2px solid;
+    display: -webkit-box;
+    -webkit-box-lines: multiple;
+}
+.max-content {
+    width: 10px;
+    min-width: -webkit-max-content;
+    min-width: -moz-max-content;
+    min-width: -ie-max-content;
+    min-width: -o-max-content;
+    min-width: max-content;
+    outline: 2px solid;
+    display: -webkit-box;
+    -webkit-box-lines: multiple;
+}
+.fit-content {
+    width: 10px;
+    min-width: -webkit-fit-content;
+    min-width: -moz-fit-content;
+    min-width: -ie-fit-content;
+    min-width: -o-fit-content;
+    min-width: fit-content;
+    outline: 2px solid;
+    display: -webkit-box;
+    -webkit-box-lines: multiple;
+}
+.child {
+    width: 20px;
+    height: 20px;
+    background-color: pink;
+}
+div {
+    display: inline-block;
+    line-height: 0;
+}
+</style>
+<script src="../../resources/check-layout.js"></script>
+
+<body onload="checkLayout('body > div')">
+<p>Check that min-width intrinsic size still applies if a fixed width is set.</p>
+
+<div class="min-content" data-expected-width=20>
+    <div class="child"></div><div class="child"></div>
+</div>
+
+<div class="max-content" data-expected-width=40>
+    <div class="child"></div><div class="child"></div>
+</div>
+
+<div class="fit-content" data-expected-width=40>
+    <div class="child"></div><div class="child"></div>
+</div>
+
+<div style="width: 30px">
+    <div class="fit-content" data-expected-width=30>
+        <div class="child"></div><div class="child"></div>
+    </div>
+</div>
+
+<div style="width: 10px">
+    <div class="fit-content" data-expected-width=20>
+        <div class="child"></div><div class="child"></div>
+    </div>
+</div>
+
+</body>
diff --git a/LayoutTests/fast/forms/select/intrinsic-min-width-applies-with-fixed-width-expected.html b/LayoutTests/fast/forms/select/intrinsic-min-width-applies-with-fixed-width-expected.html
new file mode 100644 (file)
index 0000000..efd666d
--- /dev/null
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<style>
+select {
+    outline: 2px solid;
+    margin: 0;
+}
+</style>
+<body>
+<p>Check that min-width intrinsic size still applies if a fixed width is set.</p>
+
+<select></select>
+
+<select></select>
+
+<select></select>
+
+<div style="width: 30px">
+    <select></select>
+</div>
+
+<div style="width: 10px">
+    <select></select>
+</div>
+
+</body>
diff --git a/LayoutTests/fast/forms/select/intrinsic-min-width-applies-with-fixed-width.html b/LayoutTests/fast/forms/select/intrinsic-min-width-applies-with-fixed-width.html
new file mode 100644 (file)
index 0000000..8995e63
--- /dev/null
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<style>
+.min-content {
+    width: 1px;
+    min-width: -webkit-min-content;
+    min-width: -moz-min-content;
+    min-width: -ie-min-content;
+    min-width: -o-min-content;
+    min-width: min-content;
+}
+.max-content {
+    width: 1px;
+    min-width: -webkit-max-content;
+    min-width: -moz-max-content;
+    min-width: -ie-max-content;
+    min-width: -o-max-content;
+    min-width: max-content;
+}
+.fit-content {
+    width: 1px;
+    min-width: -webkit-fit-content;
+    min-width: -moz-fit-content;
+    min-width: -ie-fit-content;
+    min-width: -o-fit-content;
+    min-width: fit-content;
+}
+select {
+    outline: 2px solid;
+    margin: 0;
+}
+</style>
+<body>
+<p>Check that min-width intrinsic size still applies if a fixed width is set.</p>
+
+<select class="min-content"></select>
+
+<select class="max-content"></select>
+
+<select class="fit-content"></select>
+
+<div style="width: 30px">
+    <select class="fit-content"></select>
+</div>
+
+<div style="width: 10px">
+    <select class="fit-content"></select>
+</div>
+
+</body>
index f4cd7b9..c50b326 100644 (file)
@@ -1,3 +1,52 @@
+2013-01-10  Ojan Vafai  <ojan@chromium.org>
+
+        Setting width overrides intrinsic min-width/max-width on flexboxes and their subclasses
+        https://bugs.webkit.org/show_bug.cgi?id=106617
+
+        Reviewed by Tony Chang.
+
+        Override computeIntrinsicLogicalWidths for all RenderFlexibleBox and RenderDeprecatedFlexibleBox
+        classes that override computePreferredLogicalWidths so that RenderBox can use
+        computeIntrinsicLogicalWidths in order to get the correct intrinsic values.
+
+        Tests: css3/flexbox/intrinsic-min-width-applies-with-fixed-width.html
+               fast/flexbox/intrinsic-min-width-applies-with-fixed-width.html
+               fast/forms/select/intrinsic-min-width-applies-with-fixed-width.html
+
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::computeLogicalWidthInRegionUsing):
+        fit-content needs to use the intrinsic sizes not the preferred sizes
+        since a fixed width overrides the preferred size.
+        As best I can tell, the sizesLogicalWidthToFitContent codepath can keep
+        using preferred widths, which are considerably faster, since that's only used
+        computing width values. Added a clause to that if-statement to make this more
+        explicit.
+
+        * rendering/RenderDeprecatedFlexibleBox.cpp:
+        (WebCore::RenderDeprecatedFlexibleBox::computeIntrinsicLogicalWidths):
+        (WebCore::RenderDeprecatedFlexibleBox::computePreferredLogicalWidths):
+        * rendering/RenderDeprecatedFlexibleBox.h:
+        (RenderDeprecatedFlexibleBox):
+        * rendering/RenderFlexibleBox.cpp:
+        (WebCore::RenderFlexibleBox::computeIntrinsicLogicalWidths):
+        (WebCore):
+        (WebCore::RenderFlexibleBox::computePreferredLogicalWidths):
+        * rendering/RenderFlexibleBox.h:
+        * rendering/RenderMenuList.cpp:
+        (WebCore::RenderMenuList::computeIntrinsicLogicalWidths):
+        (WebCore):
+        (WebCore::RenderMenuList::computePreferredLogicalWidths):
+        * rendering/RenderMenuList.h:
+        (RenderMenuList):
+        * rendering/RenderSlider.cpp:
+        (WebCore::RenderSlider::computeIntrinsicLogicalWidths):
+        (WebCore):
+        (WebCore::RenderSlider::computePreferredLogicalWidths):
+        * rendering/RenderSlider.h:
+        (RenderSlider):
+        No logic changes in any of these computeIntrinsic methods. Just moving
+        the code over from the computePreferred methods.
+
 2013-01-11  Tony Gentilcore  <tonyg@chromium.org>
 
         Move HTMLTokenTypes to its own file
index 18f3c86..4b30de5 100644 (file)
@@ -2017,7 +2017,19 @@ LayoutUnit RenderBox::computeLogicalWidthInRegionUsing(SizeType widthType, Layou
     if (shrinkToAvoidFloats() && cb->containsFloats())
         logicalWidthResult = min(logicalWidthResult, shrinkLogicalWidthToAvoidFloats(marginStart, marginEnd, cb, region, offsetFromLogicalTopOfFirstPage));
 
-    if (logicalWidth.type() == FitContent || (logicalWidth.type() != FillAvailable && sizesLogicalWidthToFitContent(widthType)))
+    if (logicalWidth.type() == FitContent) {
+        LayoutUnit minLogicalWidth = 0;
+        LayoutUnit maxLogicalWidth = 0;
+        computeIntrinsicLogicalWidths(minLogicalWidth, maxLogicalWidth);
+        minLogicalWidth += borderAndPaddingLogicalWidth();
+        maxLogicalWidth += borderAndPaddingLogicalWidth();
+        return max(minLogicalWidth, min(maxLogicalWidth, logicalWidthResult));
+    }
+
+    if (logicalWidth.type() == FillAvailable)
+        return logicalWidthResult;
+
+    if (widthType == MainOrPreferredSize && sizesLogicalWidthToFitContent(widthType))
         return max(minPreferredLogicalWidth(), min(maxPreferredLogicalWidth(), logicalWidthResult));
     return logicalWidthResult;
 }
index fbf9c1a..1b35274 100644 (file)
@@ -174,53 +174,47 @@ void RenderDeprecatedFlexibleBox::styleWillChange(StyleDifference diff, const Re
     RenderBlock::styleWillChange(diff, newStyle);
 }
 
-void RenderDeprecatedFlexibleBox::calcHorizontalPrefWidths()
+void RenderDeprecatedFlexibleBox::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
 {
-    for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
-        if (childDoesNotAffectWidthOrFlexing(child))
-            continue;
+    if (hasMultipleLines() || isVertical()) {
+        for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
+            if (childDoesNotAffectWidthOrFlexing(child))
+                continue;
 
-        LayoutUnit margin = marginWidthForChild(child);
-        m_minPreferredLogicalWidth += child->minPreferredLogicalWidth() + margin;
-        m_maxPreferredLogicalWidth += child->maxPreferredLogicalWidth() + margin;
-    }
-}
+            LayoutUnit margin = marginWidthForChild(child);
+            LayoutUnit width = child->minPreferredLogicalWidth() + margin;
+            minLogicalWidth = max(width, minLogicalWidth);
 
-void RenderDeprecatedFlexibleBox::calcVerticalPrefWidths()
-{
-    for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
-        if (childDoesNotAffectWidthOrFlexing(child))
-            continue;
-
-        LayoutUnit margin = marginWidthForChild(child);
-        LayoutUnit width = child->minPreferredLogicalWidth() + margin;
-        m_minPreferredLogicalWidth = max(width, m_minPreferredLogicalWidth);
+            width = child->maxPreferredLogicalWidth() + margin;
+            maxLogicalWidth = max(width, maxLogicalWidth);
+        }
+    } else {
+        for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
+            if (childDoesNotAffectWidthOrFlexing(child))
+                continue;
 
-        width = child->maxPreferredLogicalWidth() + margin;
-        m_maxPreferredLogicalWidth = max(width, m_maxPreferredLogicalWidth);
+            LayoutUnit margin = marginWidthForChild(child);
+            minLogicalWidth += child->minPreferredLogicalWidth() + margin;
+            maxLogicalWidth += child->maxPreferredLogicalWidth() + margin;
+        }
     }
+
+    maxLogicalWidth = max(minLogicalWidth, maxLogicalWidth);
+
+    LayoutUnit scrollbarWidth = instrinsicScrollbarLogicalWidth();
+    maxLogicalWidth += scrollbarWidth;
+    minLogicalWidth += scrollbarWidth;
 }
 
 void RenderDeprecatedFlexibleBox::computePreferredLogicalWidths()
 {
     ASSERT(preferredLogicalWidthsDirty());
 
+    m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = 0;
     if (style()->width().isFixed() && style()->width().value() > 0)
         m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = adjustContentBoxLogicalWidthForBoxSizing(style()->width().value());
-    else {
-        m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = 0;
-
-        if (hasMultipleLines() || isVertical())
-            calcVerticalPrefWidths();
-        else
-            calcHorizontalPrefWidths();
-
-        m_maxPreferredLogicalWidth = max(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
-
-        LayoutUnit scrollbarWidth = instrinsicScrollbarLogicalWidth();
-        m_maxPreferredLogicalWidth += scrollbarWidth;
-        m_minPreferredLogicalWidth += scrollbarWidth;
-    }
+    else
+        computeIntrinsicLogicalWidths(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
 
     if (style()->minWidth().isFixed() && style()->minWidth().value() > 0) {
         m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style()->minWidth().value()));
index 851fbe4..7c41084 100644 (file)
@@ -36,10 +36,6 @@ public:
 
     virtual const char* renderName() const;
 
-    virtual void computePreferredLogicalWidths();
-    void calcHorizontalPrefWidths();
-    void calcVerticalPrefWidths();
-
     virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle) OVERRIDE;
 
     virtual void layoutBlock(bool relayoutChildren, LayoutUnit pageHeight = 0);
@@ -54,6 +50,9 @@ public:
     void placeChild(RenderBox* child, const LayoutPoint& location);
 
 protected:
+    virtual void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const OVERRIDE;
+    virtual void computePreferredLogicalWidths() OVERRIDE;
+
     LayoutUnit allowedChildFlex(RenderBox* child, bool expanding, unsigned group);
 
     bool hasMultipleLines() const { return style()->boxLines() == MULTIPLE; }
index eabba11..9e2144e 100644 (file)
@@ -155,51 +155,54 @@ static LayoutUnit marginLogicalWidthForChild(RenderBox* child, RenderStyle* pare
     return margin;
 }
 
+void RenderFlexibleBox::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
+{
+    for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
+        if (child->isOutOfFlowPositioned())
+            continue;
+
+        LayoutUnit margin = marginLogicalWidthForChild(child, style());
+        bool hasOrthogonalWritingMode = child->isHorizontalWritingMode() != isHorizontalWritingMode();
+        LayoutUnit minPreferredLogicalWidth = hasOrthogonalWritingMode ? child->logicalHeight() : child->minPreferredLogicalWidth();
+        LayoutUnit maxPreferredLogicalWidth = hasOrthogonalWritingMode ? child->logicalHeight() : child->maxPreferredLogicalWidth();
+        minPreferredLogicalWidth += margin;
+        maxPreferredLogicalWidth += margin;
+        if (!isColumnFlow()) {
+            maxLogicalWidth += maxPreferredLogicalWidth;
+            if (isMultiline()) {
+                // For multiline, the min preferred width is if you put a break between each item.
+                minLogicalWidth = std::max(m_minPreferredLogicalWidth, minPreferredLogicalWidth);
+            } else
+                minLogicalWidth += minPreferredLogicalWidth;
+        } else {
+            minLogicalWidth = std::max(minPreferredLogicalWidth, minLogicalWidth);
+            if (isMultiline()) {
+                // For multiline, the max preferred width is if you put a break between each item.
+                maxLogicalWidth += maxPreferredLogicalWidth;
+            } else
+                maxLogicalWidth = std::max(maxPreferredLogicalWidth, maxLogicalWidth);
+        }
+    }
+
+    maxLogicalWidth = std::max(minLogicalWidth, maxLogicalWidth);
+
+    LayoutUnit scrollbarWidth = instrinsicScrollbarLogicalWidth();
+    maxLogicalWidth += scrollbarWidth;
+    minLogicalWidth += scrollbarWidth;
+}
+
 void RenderFlexibleBox::computePreferredLogicalWidths()
 {
     ASSERT(preferredLogicalWidthsDirty());
 
+    m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = 0;
+
     RenderStyle* styleToUse = style();
     // FIXME: This should probably be checking for isSpecified since you should be able to use percentage, calc or viewport relative values for width.
     if (styleToUse->logicalWidth().isFixed() && styleToUse->logicalWidth().value() > 0)
         m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalWidth().value());
-    else {
-        m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = 0;
-
-        for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
-            if (child->isOutOfFlowPositioned())
-                continue;
-
-            LayoutUnit margin = marginLogicalWidthForChild(child, style());
-            bool hasOrthogonalWritingMode = child->isHorizontalWritingMode() != isHorizontalWritingMode();
-            LayoutUnit minPreferredLogicalWidth = hasOrthogonalWritingMode ? child->logicalHeight() : child->minPreferredLogicalWidth();
-            LayoutUnit maxPreferredLogicalWidth = hasOrthogonalWritingMode ? child->logicalHeight() : child->maxPreferredLogicalWidth();
-            minPreferredLogicalWidth += margin;
-            maxPreferredLogicalWidth += margin;
-            if (!isColumnFlow()) {
-                m_maxPreferredLogicalWidth += maxPreferredLogicalWidth;
-                if (isMultiline()) {
-                    // For multiline, the min preferred width is if you put a break between each item.
-                    m_minPreferredLogicalWidth = std::max(m_minPreferredLogicalWidth, minPreferredLogicalWidth);
-                } else
-                    m_minPreferredLogicalWidth += minPreferredLogicalWidth;
-            } else {
-                m_minPreferredLogicalWidth = std::max(minPreferredLogicalWidth, m_minPreferredLogicalWidth);
-                if (isMultiline()) {
-                    // For multiline, the max preferred width is if you put a break between each item.
-                    m_maxPreferredLogicalWidth += maxPreferredLogicalWidth;
-                } else
-                    m_maxPreferredLogicalWidth = std::max(maxPreferredLogicalWidth, m_maxPreferredLogicalWidth);
-            }
-        }
-
-        m_maxPreferredLogicalWidth = std::max(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
-
-        LayoutUnit scrollbarWidth = instrinsicScrollbarLogicalWidth();
-        m_maxPreferredLogicalWidth += scrollbarWidth;
-        m_minPreferredLogicalWidth += scrollbarWidth;
-    }
-
+    else
+        computeIntrinsicLogicalWidths(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
 
     // FIXME: This should probably be checking for isSpecified since you should be able to use percentage, calc or viewport relative values for min-width.
     if (styleToUse->logicalMinWidth().isFixed() && styleToUse->logicalMinWidth().value() > 0) {
index 933a9d8..f83ab53 100644 (file)
@@ -45,7 +45,6 @@ public:
     virtual bool isFlexibleBox() const OVERRIDE { return true; }
     virtual bool avoidsFloats() const OVERRIDE { return true; }
     virtual bool canCollapseAnonymousBlockChild() const OVERRIDE { return false; }
-    virtual void computePreferredLogicalWidths() OVERRIDE;
     virtual void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0) OVERRIDE;
 
     virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const OVERRIDE;
@@ -56,6 +55,10 @@ public:
 
     bool isHorizontalFlow() const;
 
+protected:
+    virtual void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const OVERRIDE;
+    virtual void computePreferredLogicalWidths() OVERRIDE;
+
 private:
     enum FlexSign {
         PositiveFlexibility,
index e8fd73d..66f60f9 100644 (file)
@@ -272,6 +272,13 @@ LayoutRect RenderMenuList::controlClipRect(const LayoutPoint& additionalOffset)
     return intersection(outerBox, innerBox);
 }
 
+void RenderMenuList::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
+{
+    maxLogicalWidth = max(m_optionsWidth, theme()->minimumMenuListSize(style())) + m_innerBlock->paddingLeft() + m_innerBlock->paddingRight();
+    if (!style()->width().isPercent())
+        minLogicalWidth = maxLogicalWidth;
+}
+
 void RenderMenuList::computePreferredLogicalWidths()
 {
     m_minPreferredLogicalWidth = 0;
@@ -279,12 +286,8 @@ void RenderMenuList::computePreferredLogicalWidths()
     
     if (style()->width().isFixed() && style()->width().value() > 0)
         m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = adjustContentBoxLogicalWidthForBoxSizing(style()->width().value());
-    else {
-        m_maxPreferredLogicalWidth = max(m_optionsWidth, theme()->minimumMenuListSize(style())) + m_innerBlock->paddingLeft() + m_innerBlock->paddingRight();
-
-        if (!style()->width().isPercent())
-            m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth;
-    }
+    else
+        computeIntrinsicLogicalWidths(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
 
     if (style()->minWidth().isFixed() && style()->minWidth().value() > 0) {
         m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style()->minWidth().value()));
index df42f16..8a9f35e 100644 (file)
@@ -75,7 +75,8 @@ private:
 
     virtual const char* renderName() const { return "RenderMenuList"; }
 
-    virtual void computePreferredLogicalWidths();
+    virtual void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const OVERRIDE;
+    virtual void computePreferredLogicalWidths() OVERRIDE;
 
     virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
 
index ed92aff..e53f8e5 100644 (file)
@@ -70,6 +70,13 @@ int RenderSlider::baselinePosition(FontBaseline, bool /*firstLine*/, LineDirecti
     return height() + marginTop();
 }
 
+void RenderSlider::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
+{
+    maxLogicalWidth = defaultTrackLength * style()->effectiveZoom();
+    if (!style()->width().isPercent())
+        minLogicalWidth = maxLogicalWidth;
+}
+
 void RenderSlider::computePreferredLogicalWidths()
 {
     m_minPreferredLogicalWidth = 0;
@@ -77,12 +84,8 @@ void RenderSlider::computePreferredLogicalWidths()
 
     if (style()->width().isFixed() && style()->width().value() > 0)
         m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = adjustContentBoxLogicalWidthForBoxSizing(style()->width().value());
-    else {
-        m_maxPreferredLogicalWidth = defaultTrackLength * style()->effectiveZoom();
-
-        if (!style()->width().isPercent())
-            m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth;
-    }
+    else
+        computeIntrinsicLogicalWidths(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
 
     if (style()->minWidth().isFixed() && style()->minWidth().value() > 0) {
         m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style()->minWidth().value()));
index 252cd08..e94ef8f 100644 (file)
@@ -44,7 +44,8 @@ private:
     virtual bool canBeReplacedWithInlineRunIn() const OVERRIDE;
 
     virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
-    virtual void computePreferredLogicalWidths();
+    virtual void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const OVERRIDE;
+    virtual void computePreferredLogicalWidths() OVERRIDE;
     virtual bool requiresForcedStyleRecalcPropagation() const { return true; }
     virtual void layout();
 };