Bug 97706

Summary: Scroll offset of flex items lost during relayout
Product: WebKit Reporter: Tony Chang <tony>
Component: Layout and RenderingAssignee: Kenneth Rohde Christiansen <kenneth>
Status: RESOLVED FIXED    
Severity: Normal CC: dglazkov, eric, james, kenneth, ojan, rakuco, webkit.review.bot
Priority: P2    
Version: 528+ (Nightly build)   
Hardware: Unspecified   
OS: Unspecified   
URL: http://jsfiddle.net/XrU6J/4/
Bug Depends on:    
Bug Blocks: 62048    
Attachments:
Description Flags
Patch
none
Patch
none
Patch none

Description Tony Chang 2012-09-26 11:12:45 PDT
See the test case in the URL.  It does the following:
1) A flexbox with a flexitem that has a scrollbar.
2) Set the scroll offset of the flexitem.
3) Change the flexbox (e.g., resize the window or insert a new flex item).
4) The scroll offset is lost.

This is happening because flexbox does a 2 pass layout of the flex children. We layout the child without scrollbars (to get the size used for flexing), then we layout the child at it's final size.  During the first layout, we remove the scrollbars, then during the second layout, we recreate the scrollbars (but without the scroll offset).

There's some code in the old flexbox to handle this, we just need to add it to the new flexbox.
Comment 1 Tony Chang 2012-09-26 11:13:07 PDT
Original bug reported here: http://code.google.com/p/chromium/issues/detail?id=113383
Comment 2 Tony Chang 2012-09-26 13:12:16 PDT
In RenderDeprecatedFlexibleBox.cpp, we use RenderBlock::startDelayUpdateScrollInfo() and RenderBlock::finishDelayUpdateScrollInfo() to keep our scroll info.  We just need to call those in the right places in RenderFlexibleBox.cpp.
Comment 3 Kenneth Rohde Christiansen 2012-09-27 16:05:06 PDT
Created attachment 166085 [details]
Patch
Comment 4 Ojan Vafai 2012-09-27 16:21:31 PDT
Comment on attachment 166085 [details]
Patch

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

Looks great. I have a bunch of nits about the test. It's not official style rules obviously, but keeping tests smaller is good practice IMO. Feel free to skip any bits you disagree with.

> LayoutTests/fast/flexbox/overflow-keep-scrollpos.html:27
> +    if (window.testRunner)
> +        testRunner.dumpAsText();
> +
> +    function log(message)
> +    {
> +        document.querySelector("#console").appendChild(document.createTextNode(message + "\n"));
> +    }

How about importing js-test-pre.js? Then you wouldn't need to define any of this.

> LayoutTests/fast/flexbox/overflow-keep-scrollpos.html:41
> +        if (scrollPos === 50)
> +            log("SUCCESS")
> +        else
> +            log("FAIL: scrolltop should be 50, was: " + scrollPos)

With js-test-pre.js these four lines would just be:
shouldBe("document.querySelector('.overflow-auto').scrollTop", "50");

> LayoutTests/fast/flexbox/overflow-keep-scrollpos.html:46
> +<body onload="runTest()">

Can you move the script tag to the end of the body element? Then you don't need to run it onload and you don't need the runTest method at all. Not a big deal, but it makes the test a bit smaller.

> LayoutTests/fast/flexbox/overflow-keep-scrollpos.html:57
> +            <p>...</p>
> +            <p>...</p>
> +            <p>...</p>
> +            <p>...</p>
> +            <p>...</p>
> +            <p>...</p>
> +            <p>...</p>
> +            <p>...</p>

How about just putting a single, 200px div in here? Makes for a more reduced test.
Comment 5 Build Bot 2012-09-27 16:36:22 PDT
Comment on attachment 166085 [details]
Patch

Attachment 166085 [details] did not pass mac-ews (mac):
Output: http://queues.webkit.org/results/14038848

New failing tests:
css3/flexbox/child-overflow.html
Comment 6 WebKit Review Bot 2012-09-27 18:04:08 PDT
Comment on attachment 166085 [details]
Patch

Attachment 166085 [details] did not pass chromium-ews (chromium-xvfb):
Output: http://queues.webkit.org/results/14059094

New failing tests:
css3/flexbox/child-overflow.html
Comment 7 Kenneth Rohde Christiansen 2012-09-28 01:01:37 PDT
(In reply to comment #5)
> (From update of attachment 166085 [details])
> Attachment 166085 [details] did not pass mac-ews (mac):
> Output: http://queues.webkit.org/results/14038848
> 
> New failing tests:
> css3/flexbox/child-overflow.html

I didn't notice the flexbox under css3. Anyway, this test is a bit weird as it works fine when running in the launcher, but not in the testing system. It seems like the result is dumped before the layout is complete.

Maybe some of you have an idea
Comment 8 Kenneth Rohde Christiansen 2012-09-28 01:29:10 PDT
(In reply to comment #4)
> (From update of attachment 166085 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=166085&action=review
> 
> Looks great. I have a bunch of nits about the test. It's not official style rules obviously, but keeping tests smaller is good practice IMO. Feel free to skip any bits you disagree with.

I will fix this, no problem.
Comment 9 Kenneth Rohde Christiansen 2012-09-28 07:22:48 PDT
Created attachment 166249 [details]
Patch
Comment 10 Tony Chang 2012-09-28 11:57:36 PDT
Comment on attachment 166249 [details]
Patch

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

> Source/WebCore/rendering/RenderBlock.cpp:1359
> +        if (style()->isFlippedBlocksWritingMode()) {
> +            // FIXME: Workaround for now. We cannot delay the scroll info for overflow for

We should file a bug about this (losing scroll position when using horizontal-bt or vertical-rl layout).  It would probably be possible to move the code that scrolls a bt or rl layer or maybe make an exception for it.  I'm not sure where that code is, but I bet we could make this work without too much effort.  Seems fine to fix in a separate patch.
Comment 11 Tony Chang 2012-09-28 11:58:46 PDT
Comment on attachment 166249 [details]
Patch

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

> LayoutTests/fast/flexbox/overflow-keep-scrollpos.html:2
> +<!DOCTYPE html>
> +<html>

Oh, we should move this test to css3/flexbox.  fast/flexbox are tests for the old flexbox (display: -webkit-box).
Comment 12 Kenneth Rohde Christiansen 2012-09-28 13:23:38 PDT
(In reply to comment #10)
> (From update of attachment 166249 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=166249&action=review
> 
> > Source/WebCore/rendering/RenderBlock.cpp:1359
> > +        if (style()->isFlippedBlocksWritingMode()) {
> > +            // FIXME: Workaround for now. We cannot delay the scroll info for overflow for
> 
> We should file a bug about this (losing scroll position when using horizontal-bt or vertical-rl layout).  It would probably be possible to move the code that scrolls a bt or rl layer or maybe make an exception for it.  I'm not sure where that code is, but I bet we could make this work without too much effort.  Seems fine to fix in a separate patch.

Yes, I will file a bug after landing this. I will see if I can fix it later, but next week I am travelling.

(In reply to comment #11)
> (From update of attachment 166249 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=166249&action=review
> 
> > LayoutTests/fast/flexbox/overflow-keep-scrollpos.html:2
> > +<!DOCTYPE html>
> > +<html>
> 
> Oh, we should move this test to css3/flexbox.  fast/flexbox are tests for the old flexbox (display: -webkit-box).

Ah OK, I will move it before landing this sometime tomorrow. Thanks for the review.
Comment 13 Kenneth Rohde Christiansen 2012-09-28 13:41:03 PDT
Filed https://bugs.webkit.org/show_bug.cgi?id=97937 Will link to this in the patch.
Comment 14 Kenneth Rohde Christiansen 2012-09-29 02:45:49 PDT
Created attachment 166356 [details]
Patch
Comment 15 WebKit Review Bot 2012-09-29 03:22:09 PDT
Comment on attachment 166356 [details]
Patch

Clearing flags on attachment: 166356

Committed r129975: <http://trac.webkit.org/changeset/129975>
Comment 16 WebKit Review Bot 2012-09-29 03:22:13 PDT
All reviewed patches have been landed.  Closing bug.