Bug 111974

Summary: Text flow broken in elements with vertical align top/bottom and inline elements taller than line-height
Product: WebKit Reporter: Miguel Ventura <miguel.ventura>
Component: Layout and RenderingAssignee: Robert Hogan <robert>
Status: RESOLVED FIXED    
Severity: Normal CC: allan.jensen, buildbot, commit-queue, dglazkov, esprehn+autocc, glenn, macpherson, menard, ojan.autocc, rniwa, robert, webkit.review.bot
Priority: P2    
Version: 528+ (Nightly build)   
Hardware: All   
OS: All   
URL: http://jsfiddle.net/gqL5D/
Attachments:
Description Flags
Patch
none
Patch
none
Patch
none
Archive of layout-test-results from webkit-ews-13 for mac-mountainlion-wk2
none
Patch
none
Patch rniwa: review+

Description Miguel Ventura 2013-03-11 04:42:15 PDT
See example URL for demo: http://jsfiddle.net/gqL5D/

In an element with vertical-align top or bottom, if there's an element in the line that's taller than line-height, the text nodes will be vertically aligned differently from the inline elements.

IE and Firefox render correctly whereas in Safari and Chrome the example given seems like a roller coaster.
Comment 1 Robert Hogan 2013-03-17 08:52:51 PDT
Created attachment 193467 [details]
Patch
Comment 2 Build Bot 2013-03-17 10:26:13 PDT
Comment on attachment 193467 [details]
Patch

Attachment 193467 [details] did not pass mac-ews (mac):
Output: http://webkit-commit-queue.appspot.com/results/17145512

New failing tests:
editing/execCommand/query-command-state.html
Comment 3 WebKit Review Bot 2013-03-17 10:37:45 PDT
Comment on attachment 193467 [details]
Patch

Attachment 193467 [details] did not pass chromium-ews (chromium-xvfb):
Output: http://webkit-commit-queue.appspot.com/results/17181507

New failing tests:
editing/execCommand/query-command-state.html
Comment 4 Build Bot 2013-03-17 12:20:45 PDT
Comment on attachment 193467 [details]
Patch

Attachment 193467 [details] did not pass mac-ews (mac):
Output: http://webkit-commit-queue.appspot.com/results/17222259

New failing tests:
editing/execCommand/query-command-state.html
Comment 5 Build Bot 2013-03-17 19:03:31 PDT
Comment on attachment 193467 [details]
Patch

Attachment 193467 [details] did not pass mac-wk2-ews (mac-wk2):
Output: http://webkit-commit-queue.appspot.com/results/17174374

New failing tests:
editing/execCommand/query-command-state.html
Comment 6 Robert Hogan 2013-04-15 10:52:39 PDT
Created attachment 198135 [details]
Patch
Comment 7 Robert Hogan 2013-05-05 02:04:56 PDT
Created attachment 200586 [details]
Patch
Comment 8 Build Bot 2013-05-05 03:56:20 PDT
Comment on attachment 200586 [details]
Patch

Attachment 200586 [details] did not pass mac-wk2-ews (mac-wk2):
Output: http://webkit-queues.appspot.com/results/411032

New failing tests:
tables/mozilla/bugs/bug14323.html
Comment 9 Build Bot 2013-05-05 03:56:22 PDT
Created attachment 200587 [details]
Archive of layout-test-results from webkit-ews-13 for mac-mountainlion-wk2

The attached test failures were seen while running run-webkit-tests on the mac-wk2-ews.
Bot: webkit-ews-13  Port: mac-mountainlion-wk2  Platform: Mac OS X 10.8.2
Comment 10 Robert Hogan 2013-05-05 03:59:04 PDT
Created attachment 200588 [details]
Patch
Comment 11 Robert Hogan 2013-05-09 15:03:36 PDT
Created attachment 201280 [details]
Patch
Comment 12 Glenn Adams 2013-05-09 15:56:28 PDT
Comment on attachment 201280 [details]
Patch

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

> Source/WebCore/rendering/InlineFlowBox.cpp:486
> +    return !(curr->isText() && !curr->parent()->isInline() && !curr->parent()->isTableCell());

Is this correct? i.e., what you have is the same as !curr->isText() || curr->parent()->isInline() || curr->parent()->isTableCell()
Comment 13 Robert Hogan 2013-05-10 10:46:17 PDT
(In reply to comment #12)
> (From update of attachment 201280 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=201280&action=review
> 
> > Source/WebCore/rendering/InlineFlowBox.cpp:486
> > +    return !(curr->isText() && !curr->parent()->isInline() && !curr->parent()->isTableCell());
> 
> Is this correct? i.e., what you have is the same as !curr->isText() || curr->parent()->isInline() || curr->parent()->isTableCell()

Well they're both correct - but yours is better. :)
Comment 14 Glenn Adams 2013-05-10 10:55:40 PDT
(In reply to comment #13)
> (In reply to comment #12)
> > (From update of attachment 201280 [details] [details])
> > View in context: https://bugs.webkit.org/attachment.cgi?id=201280&action=review
> > 
> > > Source/WebCore/rendering/InlineFlowBox.cpp:486
> > > +    return !(curr->isText() && !curr->parent()->isInline() && !curr->parent()->isTableCell());
> > 
> > Is this correct? i.e., what you have is the same as !curr->isText() || curr->parent()->isInline() || curr->parent()->isTableCell()
> 
> Well they're both correct - but yours is better. :)

Yes, it's best to use De Morgan's laws to simplify, but I also wanted to check that when !curr->isText() is true that it's always something to which vertical position applies.

For example, there is nothing stopping curr from being RenderBlock, yes?
Comment 15 Ryosuke Niwa 2013-05-10 11:03:08 PDT
Comment on attachment 201280 [details]
Patch

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

> Source/WebCore/rendering/InlineFlowBox.cpp:485
> +    // The vertical-align property only applies to inline elements and table cells.

Instead of repeating the code, refer to http://www.w3.org/TR/2011/REC-CSS2-20110607/visudet.html#line-height.

Should we also check this condition in RenderStyle::diff (for optimization)?
Comment 16 Robert Hogan 2013-05-11 05:09:15 PDT
Committed r149929: <http://trac.webkit.org/changeset/149929>
Comment 17 Glenn Adams 2013-05-11 09:52:27 PDT
(In reply to comment #14)
> (In reply to comment #13)
> > (In reply to comment #12)
> > > (From update of attachment 201280 [details] [details] [details])
> > > View in context: https://bugs.webkit.org/attachment.cgi?id=201280&action=review
> > > 
> > > > Source/WebCore/rendering/InlineFlowBox.cpp:486
> > > > +    return !(curr->isText() && !curr->parent()->isInline() && !curr->parent()->isTableCell());
> > > 
> > > Is this correct? i.e., what you have is the same as !curr->isText() || curr->parent()->isInline() || curr->parent()->isTableCell()
> > 
> > Well they're both correct - but yours is better. :)
> 
> Yes, it's best to use De Morgan's laws to simplify, but I also wanted to check that when !curr->isText() is true that it's always something to which vertical position applies.
> 
> For example, there is nothing stopping curr from being RenderBlock, yes?

It would have been nice if you'd simplified the logic and added an assert on curr being an inline renderer before committing.
Comment 18 Robert Hogan 2013-05-11 12:32:02 PDT
(In reply to comment #17)
> (In reply to comment #14)
> > (In reply to comment #13)
> > > (In reply to comment #12)
> > > > (From update of attachment 201280 [details] [details] [details] [details])
> > > > View in context: https://bugs.webkit.org/attachment.cgi?id=201280&action=review
> > > > 
> > > > > Source/WebCore/rendering/InlineFlowBox.cpp:486
> > > > > +    return !(curr->isText() && !curr->parent()->isInline() && !curr->parent()->isTableCell());
> > > > 
> > > > Is this correct? i.e., what you have is the same as !curr->isText() || curr->parent()->isInline() || curr->parent()->isTableCell()
> > > 
> > > Well they're both correct - but yours is better. :)
> > 
> > Yes, it's best to use De Morgan's laws to simplify, but I also wanted to check that when !curr->isText() is true that it's always something to which vertical position applies.
> > 
> > For example, there is nothing stopping curr from being RenderBlock, yes?
> 
> It would have been nice if you'd simplified the logic and added an assert on curr being an inline renderer before committing.

I implemented your suggestion before landing!
Comment 19 Robert Hogan 2013-05-11 12:33:11 PDT
(In reply to comment #14)
> (In reply to comment #13)
> > (In reply to comment #12)
> > > (From update of attachment 201280 [details] [details] [details])
> > > View in context: https://bugs.webkit.org/attachment.cgi?id=201280&action=review
> > > 
> > > > Source/WebCore/rendering/InlineFlowBox.cpp:486
> > > > +    return !(curr->isText() && !curr->parent()->isInline() && !curr->parent()->isTableCell());
> > > 
> > > Is this correct? i.e., what you have is the same as !curr->isText() || curr->parent()->isInline() || curr->parent()->isTableCell()
> > 
> > Well they're both correct - but yours is better. :)
> 
> Yes, it's best to use De Morgan's laws to simplify, but I also wanted to check that when !curr->isText() is true that it's always something to which vertical position applies.
> 
> For example, there is nothing stopping curr from being RenderBlock, yes?

Correct but it will be an inline block so that's alright.
Comment 20 Glenn Adams 2013-05-11 13:50:42 PDT
(In reply to comment #19)
> (In reply to comment #14)
> > (In reply to comment #13)
> > > (In reply to comment #12)
> > > > (From update of attachment 201280 [details] [details] [details] [details])
> > > > View in context: https://bugs.webkit.org/attachment.cgi?id=201280&action=review
> > > > 
> > > > > Source/WebCore/rendering/InlineFlowBox.cpp:486
> > > > > +    return !(curr->isText() && !curr->parent()->isInline() && !curr->parent()->isTableCell());
> > > > 
> > > > Is this correct? i.e., what you have is the same as !curr->isText() || curr->parent()->isInline() || curr->parent()->isTableCell()
> > > 
> > > Well they're both correct - but yours is better. :)
> > 
> > Yes, it's best to use De Morgan's laws to simplify, but I also wanted to check that when !curr->isText() is true that it's always something to which vertical position applies.
> > 
> > For example, there is nothing stopping curr from being RenderBlock, yes?
> 
> Correct but it will be an inline block so that's alright.

In that case, an assert would have been useful, since it in fact assumes that.

Thanks for implementing the simplification. I looked at the last patch, which didn't have it. It would be useful for you to use land-safely if you make a change so that at least the final form of the commit is uploaded as a patch to the bug.