Bug 21925 - li or div with float and text-transform wraps unexpectedly when dynamically updating inner span
Summary: li or div with float and text-transform wraps unexpectedly when dynamically u...
Status: UNCONFIRMED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Layout and Rendering (show other bugs)
Version: 528+ (Nightly build)
Hardware: PC Windows XP
: P2 Normal
Assignee: Nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-10-28 08:50 PDT by Mike Henry
Modified: 2013-06-17 23:34 PDT (History)
9 users (show)

See Also:


Attachments
test case (2.00 KB, text/html)
2008-10-28 08:59 PDT, Mike Henry
no flags Details
test case that shows issue + weird behaviour (1.81 KB, text/html)
2010-02-16 05:43 PST, David Jennes
no flags Details
test case that shows issue and some weird behaviour (1.81 KB, text/html)
2010-02-16 05:46 PST, David Jennes
no flags Details
do not mark dirty if has no parent (840 bytes, patch)
2012-03-02 04:47 PST, Mikhail
no flags Details | Formatted Diff | Diff
Patch (4.61 KB, patch)
2012-12-20 07:19 PST, Mikhail
bfulgham: review-
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Mike Henry 2008-10-28 08:50:43 PDT
Overview Description:

The li or div element should resize horizontally to fit the updated content, but wraps instead.

Steps to Reproduce:
For an li:
1) Create a ul with an li and a span within the li.
2) Set the style on the li to "float: left; text-transform: uppercase;"
3) Use JavaScript to add text to the span in step (1).

For a div:
1) Create a div with a a span within the div.
2) Set the style on the div to "float: left; text-transform: uppercase;"
3) Use JavaScript to add text to the span in step (1).

Actual Results:
The li/div from step (1) wraps vertically.

Expected Results:
The li/div from step (1) should expand horizontally to fit the updated text.

Build Date & Platform:
WebKit-r37894 (2008-10-27) on Windows XP SP3

Additional Builds and Platforms:
Also occurs on:
Safari 3.1.2 (525.21) on Windows XP SP3
Google Chrome 0.2.149.30 on Windows XP SP3
Safari 3.1.1 (5525.20) on Mac OS X 10.5.3

Doesn't occur on:
Mozilla Firefox 3.0.3 on Windows XP SP3
Internet Explorer 7.0.5730.13 on Windows XP SP3
Comment 1 Mike Henry 2008-10-28 08:59:03 PDT
Created attachment 24715 [details]
test case
Comment 2 David Jennes 2010-02-16 05:14:24 PST
I can confirm this bug, noticed it today while developing some web app. It had me totally stumped for a while, I thought I was doing something wrong somewhere but couldn't understand why the calculated width was 0 pixels.

Removing the text-transform attribute corrects webkit's behavior. Also, a span inside the div isn't needed, that's how I discovered it in my case: after my faulty div come some other elements (img, div, whatever) and normally they display fine (next to each other). When the transform attribute is set, the faulty div gets a calculated width of 0px (I am not setting the width anywhere) so the other elements that come after it are now displayed on top of it.
Comment 3 David Jennes 2010-02-16 05:21:11 PST
Oh and it also happens when using capitalize and lowercase (so any time a transform is actually done).

Tested on Mac OS X 10.5.8 with:
- Safari 4.0.4
- Webkit-r54814
Comment 4 David Jennes 2010-02-16 05:43:15 PST
Created attachment 48810 [details]
test case that shows issue + weird behaviour

This (shamelessly copied) test case shows issue + an interesting behavior that arises:
when the div's are empty and dynamically filled with javascript, the issue happens. However, this does not happen when the div's already have some text inside of them.
Comment 5 David Jennes 2010-02-16 05:46:06 PST
Created attachment 48811 [details]
test case that shows issue and some weird behaviour

woops forgot to save my file locally before sending it :-P
Comment 6 Mikhail 2012-03-02 04:47:34 PST
Created attachment 129881 [details]
do not mark dirty if has no parent

The bug occurs when width of container node is not recalculated after text-transformed node is appended to it.

This happened because setPreferredLogicalWidthsDirty is called twice when text is css-transformed, and when it called first time TextRender has no parent yet. When text is not transformed there is one call.
Extra call is occurs during after calling setText in RenderText.cpp, RenderText::styleDidChange:
204	    if (needsResetText || oldTransform != newStyle->textTransform() || oldSecurity != newStyle->textSecurity()) {
205	        if (RefPtr<StringImpl> textToTransform = originalText())
206	            setText(textToTransform.release(), true);
207	    }

#0  WebCore::RenderObject::setPreferredLogicalWidthsDirty (this=0x81e0fcc, 
#1  0xb5d0f42a in WebCore::RenderObject::setNeedsLayoutAndPrefWidthsRecalc (
#2  0xb6252ee6 in WebCore::RenderText::setText (this=0x81e0fcc, text=..., 


First time setPreferredLogicalWidthsDirty() is called on RenderText when it has no parent renderer, so invalidateContainerPreferredLogicalWidths() cannot mark container for recalculating width.
Next time when setPreferredLogicalWidthsDirty() is called (this time after addChild()) invalidateContainerPreferredLogicalWidths() isn't called because dirty flag was set previous time.

It can be fixed by resetting width-dirty flag if RenderObject has no parent,
in invalidateContainerPreferredLogicalWidths call. See patch.
Comment 7 Robert Hogan 2012-10-02 11:23:08 PDT
(In reply to comment #6)
> Created an attachment (id=129881) [details]
> do not mark dirty if has no parent
> 
> The bug occurs when width of container node is not recalculated after text-transformed node is appended to it.

This sounds plausible - can you do up a proper patch for it and we'll get it reviewed?
Comment 8 Mikhail 2012-12-20 07:19:01 PST
Created attachment 180337 [details]
Patch
Comment 9 Brent Fulgham 2013-06-17 23:34:13 PDT
Comment on attachment 180337 [details]
Patch

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

Thanks for working on this.  I think your source change is correct, but your test case is messed up.  Can you please fix the test case so we can get this integrated?  Thanks.

> LayoutTests/fast/text/transform-container-width-expected.html:1
> +<html>

This file should be a text document showing the expected DRT output.  This looks like a duplicate of the original test.