Bug 81809

Summary: percentage height/width values in quirks mode are incorrectly resolved in flexbox children
Product: WebKit Reporter: Tony Chang <tony>
Component: Layout and RenderingAssignee: Ojan Vafai <ojan>
Status: RESOLVED FIXED    
Severity: Normal CC: eric, esprehn, jchaffraix, ojan, ssandela, webkit.review.bot
Priority: P2    
Version: 528+ (Nightly build)   
Hardware: Unspecified   
OS: Unspecified   
URL: http://plexode.com/eval3/#ht=%3Ciframe%20src%3D%22data%3Atext%2Fhtml%2C%0A%3Cdiv%20style%3D'height%3A%2050px'%3E%0A%20%20%3Cdiv%3E%0A%20%20%20%20%3Cdiv%20style%3D'min-height%3A%20100%25%3B%20background-color%3A%20blue'%3Etest%3C%2Fdiv%3E%0A%20%20%3C%2Fdiv%3E%0A%3C%2Fdiv%3E%0A%3Cdiv%20style%3D'height%3A%2050px'%3E%0A%20%20%3Cdiv%20style%3D'display%3A%20-webkit-flexbox%3B%20-webkit-flex-direction%3A%20column'%3E%0A%20%20%20%20%3Cdiv%20style%3D'min-height%3A%20100%25%3B%20background-color%3A%20green'%3Etest%3C%2Fdiv%3E%0A%20%20%3C%2Fdiv%3E%0A%3C%2Fdiv%3E%0A%22%3E%3C%2Fiframe%3E%0A%0A%3Cdiv%20style%3D'height%3A%2050px'%3E%0A%20%20%3Cdiv%3E%0A%20%20%20%20%3Cdiv%20style%3D'min-height%3A%20100%25%3B%20background-color%3A%20blue'%3Etest%3C%2Fdiv%3E%0A%20%20%3C%2Fdiv%3E%0A%3C%2Fdiv%3E%0A%0A%3Cdiv%20style%3D'height%3A%2050px'%3E%0A%20%20%3Cdiv%20style%3D'display%3A%20-webkit-flexbox%3B%20-webkit-flex-direction%3A%20column'%3E%0A%20%20%20%20%3Cdiv%20style%3D'min-height%3A%20100%25%3B%20background-color%3A%20green'%3Etest%3C%2Fdiv%3E%0A%20%20%3C%2Fdiv%3E%0A%3C%2Fdiv%3E%0A&ohh=1&ohj=1&jt=frames%5B0%5D.document.compatMode&ojh=1&ojj=1&ms=100&oth=0&otj=0&cex=1
Bug Depends on:    
Bug Blocks: 62048    
Attachments:
Description Flags
testcase
none
Patch tony: review+

Description Tony Chang 2012-03-21 11:35:19 PDT
When computing min/max-height/width and height/width of flex children, we resolve percentage values by only looking at the flexbox size.  In quirks mode, if the flexbox size is auto, we should check parents for a definite value.
Comment 1 SravanKumar S(:sravan) 2012-03-22 07:29:36 PDT
Hi Tony, can you please elaborate?.
Are you speaking about RenderFlexibleBox?
Comment 2 Tony Chang 2012-03-22 09:51:17 PDT
(In reply to comment #1)
> Hi Tony, can you please elaborate?.
> Are you speaking about RenderFlexibleBox?

Yes, this is in RenderFlexibleBox.cpp.
Comment 3 Tony Chang 2012-03-22 10:48:38 PDT
Demo in the URL.

This may actually just work (the above test case with min-height seems to).  We should add tests for this.
Comment 5 Ojan Vafai 2012-08-06 13:48:08 PDT
Ugh. All of these are invalid due to renaming flexbox to flex. Uploading a valid test case. Still, we seem to get the height right.
Comment 6 Ojan Vafai 2012-08-06 13:48:20 PDT
Created attachment 156758 [details]
testcase
Comment 7 Tony Chang 2012-08-06 14:07:05 PDT
(In reply to comment #5)
> Ugh. All of these are invalid due to renaming flexbox to flex. Uploading a valid test case. Still, we seem to get the height right.

Yeah, I think we just need to add some layout tests.
Comment 8 Ojan Vafai 2012-08-06 14:15:21 PDT
(In reply to comment #7)
> (In reply to comment #5)
> > Ugh. All of these are invalid due to renaming flexbox to flex. Uploading a valid test case. Still, we seem to get the height right.
> 
> Yeah, I think we just need to add some layout tests.

I've found at least one bug as I've been trying to understand this. I'll post an update once I feel that I've found all the relevant bugs.
Comment 9 Ojan Vafai 2012-08-06 17:07:51 PDT
I've found a few bugs and will post a patch soon. Having some weird issues with my fix. :(
Comment 10 Ojan Vafai 2012-08-07 14:23:49 PDT
Created attachment 157004 [details]
Patch
Comment 11 Elliott Sprehn 2012-08-07 14:41:08 PDT
Comment on attachment 157004 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=157004&action=review

> Source/WebCore/rendering/RenderBox.cpp:2064
> +LayoutUnit RenderBox::computeLogicalClientHeight(SizeType heightType, const Length& height)

Tony originally said this didn't make sense here because it's not useful for things outside new Flexbox. What's different now?

> Source/WebCore/rendering/RenderFlexibleBox.cpp:817
> +            return minSize;

The -1 check seems bad. Negative min/max height are illegal, so it shouldn't even be isSpecified() if it's negative. Is that a bug?
Comment 12 Ojan Vafai 2012-08-07 15:02:29 PDT
Comment on attachment 157004 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=157004&action=review

>> Source/WebCore/rendering/RenderBox.cpp:2064
>> +LayoutUnit RenderBox::computeLogicalClientHeight(SizeType heightType, const Length& height)
> 
> Tony originally said this didn't make sense here because it's not useful for things outside new Flexbox. What's different now?

I'm thinking ahead to Grid, which will need this same logic for restricting to min/max sizes. The alternative for this patch would have been to pass in the RenderBox to use, which is fine (we'd pass in "this" everwhere except in the three cases where we'd pass in the flex item). But given the Grid need, I went with the simpler patch.

I'm a little wary of all these methods with very similar sounding names, but I couldn't think of a great solution.

>> Source/WebCore/rendering/RenderFlexibleBox.cpp:817
>> +            return minSize;
> 
> The -1 check seems bad. Negative min/max height are illegal, so it shouldn't even be isSpecified() if it's negative. Is that a bug?

computePercentageLogicalHeight can return -1 in some cases depending on the state of the containingBlock (e.g. in standards mode if the containing block is height:auto).
Comment 13 Tony Chang 2012-08-07 18:27:18 PDT
Comment on attachment 157004 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=157004&action=review

> Source/WebCore/rendering/RenderFlexibleBox.cpp:407
> +    if (isColumnFlow())
> +        return child->computeLogicalClientHeight(sizeType, size);
> +    return child->computeContentBoxLogicalWidth(valueForLength(size, availableSize, view()));

This looks wrong for orthogonal flows, but I guess it's what we had before.

>>> Source/WebCore/rendering/RenderFlexibleBox.cpp:817
>>> +            return minSize;
>> 
>> The -1 check seems bad. Negative min/max height are illegal, so it shouldn't even be isSpecified() if it's negative. Is that a bug?
> 
> computePercentageLogicalHeight can return -1 in some cases depending on the state of the containingBlock (e.g. in standards mode if the containing block is height:auto).

I wonder if we can remove the isSpecified() check.  I don't have a strong preference one way or another.

> Source/WebCore/rendering/RenderFlexibleBox.h:88
> +    LayoutUnit computeMainAxisSizeForChild(RenderBox* child, SizeType, const Length& size, LayoutUnit availableSize);

Nit: I think we normally use Extent instead of Size for lengths.  I don't feel strongly about this.

> LayoutTests/css3/flexbox/percentage-sizes-quirks.html:37
> +<script>
> +if (window.testRunner)
> +    testRunner.dumpAsText();
> +</script>

Nit: I would probably print document.compatMode somewhere just to be sure.
Comment 14 Ojan Vafai 2012-08-08 10:58:41 PDT
Comment on attachment 157004 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=157004&action=review

>> Source/WebCore/rendering/RenderFlexibleBox.cpp:407
>> +    return child->computeContentBoxLogicalWidth(valueForLength(size, availableSize, view()));
> 
> This looks wrong for orthogonal flows, but I guess it's what we had before.

Good catch. Adding a FIXME for now.

>>>> Source/WebCore/rendering/RenderFlexibleBox.cpp:817
>>>> +            return minSize;
>>> 
>>> The -1 check seems bad. Negative min/max height are illegal, so it shouldn't even be isSpecified() if it's negative. Is that a bug?
>> 
>> computePercentageLogicalHeight can return -1 in some cases depending on the state of the containingBlock (e.g. in standards mode if the containing block is height:auto).
> 
> I wonder if we can remove the isSpecified() check.  I don't have a strong preference one way or another.

Seems fine to me. I suppose the minSize != -1 is redundant with the childSize<minSize check since childSize is at least 0 (but the -1 check is definitely needed for maxSize).

This just means we'll need to check of the auto case first since we want that to go down a special code path for flexitems.

>> Source/WebCore/rendering/RenderFlexibleBox.h:88
>> +    LayoutUnit computeMainAxisSizeForChild(RenderBox* child, SizeType, const Length& size, LayoutUnit availableSize);
> 
> Nit: I think we normally use Extent instead of Size for lengths.  I don't feel strongly about this.

Yeah, I thought about it after the fact and was too lazy to change it. :) But you're right, I should be consistent.

>> LayoutTests/css3/flexbox/percentage-sizes-quirks.html:37
>> +</script>
> 
> Nit: I would probably print document.compatMode somewhere just to be sure.

makes sense
Comment 15 Ojan Vafai 2012-08-08 11:17:51 PDT
Comment on attachment 157004 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=157004&action=review

>>>>> Source/WebCore/rendering/RenderFlexibleBox.cpp:817
>>>>> +            return minSize;
>>>> 
>>>> The -1 check seems bad. Negative min/max height are illegal, so it shouldn't even be isSpecified() if it's negative. Is that a bug?
>>> 
>>> computePercentageLogicalHeight can return -1 in some cases depending on the state of the containingBlock (e.g. in standards mode if the containing block is height:auto).
>> 
>> I wonder if we can remove the isSpecified() check.  I don't have a strong preference one way or another.
> 
> Seems fine to me. I suppose the minSize != -1 is redundant with the childSize<minSize check since childSize is at least 0 (but the -1 check is definitely needed for maxSize).
> 
> This just means we'll need to check of the auto case first since we want that to go down a special code path for flexitems.

Actually, on closer look, the valueForLength functions all ASSERT_NOT_REACHED for intrinsic values other than FillAvailable and Auto. So, we should probably keep the checks in place.
Comment 16 Ojan Vafai 2012-08-08 11:29:11 PDT
Committed r125055: <http://trac.webkit.org/changeset/125055>