Bug 101116

Summary: Text nodes in shadow roots don't inherit style properly
Product: WebKit Reporter: Elliott Sprehn <esprehn>
Component: Layout and RenderingAssignee: Takashi Sakamoto <tasak>
Status: RESOLVED FIXED    
Severity: Normal CC: allan.jensen, cmarcelo, dglazkov, macpherson, menard, morrita, ojan.autocc, ojan, shinyak, webcomponents-bugzilla, webkit.review.bot
Priority: P2 Keywords: HasReduction
Version: 528+ (Nightly build)   
Hardware: Unspecified   
OS: Unspecified   
Bug Depends on:    
Bug Blocks: 72352, 95528    
Attachments:
Description Flags
Patch
none
Patch
none
Patch
none
Patch
none
Patch
none
Patch
none
Patch
none
Patch
none
Patch
none
Patch
none
Patch
none
Patch
none
Patch
none
Patch
none
Patch
none
Patch
none
Patch
none
Patch none

Description Elliott Sprehn 2012-11-02 15:49:44 PDT
Test case:

shadow = new WebKitShadowRoot(document.body)
span = document.createElement('span')
span.textContent = "foo";
shadow.appendChild(span);
shadow.appendChild(document.createTextNode("bar"))
document.body.offsetTop; // cause a layout.
document.body.style.fontSize = '5em';

You should see foo bar in big text, but you only see "foo" in big text.

The bug is here:

http://code.google.com/searchframe#OAMlx_jo-ck/src/third_party/WebKit/Source/WebCore/dom/Text.cpp&exact_package=chromium&l=259

and SVG has a hack for it:

http://code.google.com/searchframe#OAMlx_jo-ck/src/third_party/WebKit/Source/WebCore/svg/SVGTRefElement.cpp&exact_package=chromium&q=SVGTRefElement&type=cs&l=156

This means text in a shadow root is broken for zooming and style changes.
Comment 1 Takashi Sakamoto 2012-11-06 03:09:27 PST
Created attachment 172539 [details]
Patch
Comment 2 Build Bot 2012-11-06 06:28:29 PST
Comment on attachment 172539 [details]
Patch

Attachment 172539 [details] did not pass mac-ews (mac):
Output: http://queues.webkit.org/results/14747411
Comment 3 Dimitri Glazkov (Google) 2012-11-06 09:37:41 PST
Comment on attachment 172539 [details]
Patch

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

> Source/WebCore/dom/Text.cpp:267
> +        Node* parentForStyle = parent->isShadowRoot() ?
> +            toShadowRoot(parent)->shadowHost() :
> +            parent;

This should probably be just one line.
Comment 4 Elliott Sprehn 2012-11-06 09:59:17 PST
Comment on attachment 172539 [details]
Patch

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

When resetStyleInheritance is true we have no m_parentStyle in StyleResolver and then go down this code path: http://code.google.com/searchframe#OAMlx_jo-ck/src/third_party/WebKit/Source/WebCore/css/StyleResolver.cpp&exact_package=chromium&q=StyleResolver.cpp&type=cs&l=1545

You need to have this same behavior for text nodes.

> Source/WebCore/dom/Text.cpp:262
>      // is a shadow root.

Remove this comment since it doesn't apply now.

> Source/WebCore/dom/Text.cpp:268
> +        renderer->setStyle(parentForStyle->renderStyle());

This is wrong if you have resetStyleInheritance set because you unconditionally inherit from the shadow host. You need to expose the default style from inside the StyleResolver, perhaps with some abstraction like document()->styleResolver()->styleForText(this) that models the existing styleForElement.
Comment 5 Dimitri Glazkov (Google) 2012-11-06 10:44:30 PST
Comment on attachment 172539 [details]
Patch

Thanks for looking this over, Elliot.
Comment 6 Takashi Sakamoto 2012-11-19 21:01:26 PST
Thank you for reviewing.

I missed reset-style-inheritance. I agree that I have to think about this.

So.. however I would like to confirm what style we should apply to resetted text nodes. The reason why I'm thinking about this is:
(1) we cannot directly apply any styles to text nodes.
(2) if we have to check reset-style-inheritance flag, we have to modify NodeRendererFactory::createRendererIfNeeded() too, i.e.

---- before -----
    Element* element = node->isElementNode() ? toElement(node) : 0;
    if (element)
        m_context.setStyle(element->styleForRenderer());
    else if (RenderObject* parentRenderer = m_context.parentRenderer())
        m_context.setStyle(parentRenderer->style());
---- after ----
    Element* element = node->isElementNode() ? toElement(node) : 0;
    if (element)
        m_context.setStyle(element->styleForRenderer());
    else if (node->isTextNode())
        m_context.setStyle(document()->styleResolver()->styleForText(node); // added
    else if (RenderObject* parentRenderer = m_context.parentRenderer())
        m_context.setStyle(parentRenderer->style());

Since for each text node we have to use NodeRenderingContext to check reset-style-inheritance, I'm afraid of performance regression. Is this allowable regression?

Best regards,
Takashi Sakamoto
Comment 7 Hajime Morrita 2012-11-19 21:18:21 PST
(In reply to comment #6)
> Thank you for reviewing.
> 
> I missed reset-style-inheritance. I agree that I have to think about this.
> 
> So.. however I would like to confirm what style we should apply to resetted text nodes. The reason why I'm thinking about this is:
> (1) we cannot directly apply any styles to text nodes.
> (2) if we have to check reset-style-inheritance flag, we have to modify NodeRendererFactory::createRendererIfNeeded() too, i.e.
> 
> ---- before -----
>     Element* element = node->isElementNode() ? toElement(node) : 0;
>     if (element)
>         m_context.setStyle(element->styleForRenderer());
>     else if (RenderObject* parentRenderer = m_context.parentRenderer())
>         m_context.setStyle(parentRenderer->style());
> ---- after ----
>     Element* element = node->isElementNode() ? toElement(node) : 0;
>     if (element)
>         m_context.setStyle(element->styleForRenderer());
>     else if (node->isTextNode())
>         m_context.setStyle(document()->styleResolver()->styleForText(node); // added
>     else if (RenderObject* parentRenderer = m_context.parentRenderer())
>         m_context.setStyle(parentRenderer->style());
> 
> Since for each text node we have to use NodeRenderingContext to check reset-style-inheritance, I'm afraid of performance regression. Is this allowable regression?

First of all, let's measure it. Our PerformanceTests has some parser-related tests which exercise
not only the parser but also the style computation. It would be a good starting point.
Comment 8 Elliott Sprehn 2012-11-19 21:44:07 PST
(In reply to comment #6)
> ...
> Since for each text node we have to use NodeRenderingContext to check reset-style-inheritance, I'm afraid of performance regression. Is this allowable regression?

isShadowRoot and isTextNode are bitfield checks and we only need this special case for text nodes that are direct descendants of shadow roots.

Element* element = node->isElementNode() ? toElement(node) : 0;
if (element)
  m_context.setStyle(element->styleForRenderer());
else if (node->isTextNode() && node->parentOrHostNode()->isShadowRoot())
  m_context.setStyle(document()->styleResolver()->styleForText(node);
else
  m_context.setStyle(m_context.parentRenderer()->style());

The last check is simplified as in Bug 102765 and since the conditional is on a bitfield it seems very unlikely there's a perf regression.
Comment 9 Takashi Sakamoto 2012-11-19 22:56:29 PST
Created attachment 175145 [details]
Patch
Comment 10 Takashi Sakamoto 2012-11-19 23:07:08 PST
(In reply to comment #8)
> (In reply to comment #6)
> > ...
> > Since for each text node we have to use NodeRenderingContext to check reset-style-inheritance, I'm afraid of performance regression. Is this allowable regression?
> 
> isShadowRoot and isTextNode are bitfield checks and we only need this special case for text nodes that are direct descendants of shadow roots.
> 
> Element* element = node->isElementNode() ? toElement(node) : 0;
> if (element)
>   m_context.setStyle(element->styleForRenderer());
> else if (node->isTextNode() && node->parentOrHostNode()->isShadowRoot())
>   m_context.setStyle(document()->styleResolver()->styleForText(node);
> else
>   m_context.setStyle(m_context.parentRenderer()->style());
> 
> The last check is simplified as in Bug 102765 and since the conditional is on a bitfield it seems very unlikely there's a perf regression.

Thank you.
I will recreate a new patch and upload.

Best regards,
Takashi Sakamoto
Comment 11 Takashi Sakamoto 2012-11-19 23:18:01 PST
Created attachment 175150 [details]
Patch
Comment 12 Takashi Sakamoto 2012-11-19 23:19:49 PST
Created attachment 175151 [details]
Patch
Comment 13 Takashi Sakamoto 2012-11-19 23:22:06 PST
Created attachment 175152 [details]
Patch
Comment 14 Elliott Sprehn 2012-11-19 23:22:25 PST
Comment on attachment 175145 [details]
Patch

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

We can make createRendererIfNeeded faster by not creating a whole new NodeRenderingContext and skipping the parent traversal using an overload and passing in the context from NodeRenderFactory:

StyleResolver::styleForText(Node* textNode, NodeRenderingContext& context) { ... }
StyleResolver::styleForText(Node* textNode)
{
  NodeRenderingContext context(textNode);
  return styleForText(textNode, context);
}

I'm not sure this optimization is needed, but what you have right now does traverse the parents repeatedly.

> Source/WebCore/ChangeLog:8
> +        Use NodeRenderingContext to solve styles of text nodes.

resolve

> Source/WebCore/ChangeLog:9
> +        If text nodes are direct chilren of shadow roots, the text nodes

children

> Source/WebCore/css/StyleResolver.cpp:1795
> +    NodeRenderingContext context(textNode);

It seems kind of silly to create a whole new rendering context and do the ComposedShadowTreeWalker::findParent traversal during createRendererIfNeeded() when we already have all that information in createRendererIfNeeded. It might not actually matter for performance though.
Comment 15 Takashi Sakamoto 2012-11-19 23:39:32 PST
Created attachment 175156 [details]
Patch
Comment 16 Takashi Sakamoto 2012-11-19 23:41:30 PST
Comment on attachment 175145 [details]
Patch

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

Thank you for quickly reviewing.

>> Source/WebCore/ChangeLog:8
>> +        Use NodeRenderingContext to solve styles of text nodes.
> 
> resolve

Done. Thanks.

>> Source/WebCore/ChangeLog:9
>> +        If text nodes are direct chilren of shadow roots, the text nodes
> 
> children

Done.

>> Source/WebCore/css/StyleResolver.cpp:1795
>> +    NodeRenderingContext context(textNode);
> 
> It seems kind of silly to create a whole new rendering context and do the ComposedShadowTreeWalker::findParent traversal during createRendererIfNeeded() when we already have all that information in createRendererIfNeeded. It might not actually matter for performance though.

I see. I added styleForElement(Node*, NodeRenderingContext&).
Comment 17 Elliott Sprehn 2012-11-19 23:46:09 PST
Comment on attachment 175156 [details]
Patch

Looks good to me.
Comment 18 Takashi Sakamoto 2012-11-20 03:50:06 PST
Created attachment 175183 [details]
Patch
Comment 19 Takashi Sakamoto 2012-11-20 03:52:58 PST
I modified the condition in createRendererIfNeeded, because I think, m_context.insertionPoint() is a little better than isShadowHost(node->parentOrHostNode()).

Best regards,
Takashi Sakamoto
Comment 20 Takashi Sakamoto 2012-11-20 04:44:03 PST
Created attachment 175189 [details]
Patch
Comment 21 Build Bot 2012-11-20 04:59:22 PST
Comment on attachment 175189 [details]
Patch

Attachment 175189 [details] did not pass mac-ews (mac):
Output: http://queues.webkit.org/results/14894596
Comment 22 Takashi Sakamoto 2012-11-20 23:41:34 PST
Created attachment 175347 [details]
Patch
Comment 23 Hajime Morrita 2012-11-20 23:43:13 PST
What about performance?
Comment 24 Elliott Sprehn 2012-11-20 23:48:21 PST
Comment on attachment 175347 [details]
Patch

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

This looks good to me, but I'm not a reviewer so I can't r+. Perhaps someone else can do that. :)

> Source/WebCore/dom/NodeRenderingContext.cpp:252
> +        m_context.setStyle(node->document()->styleResolver()->styleForText(m_context));

You can just move the Document* document = node->document(); line back to the top of the function again if you want too.
Comment 25 Elliott Sprehn 2012-11-20 23:52:15 PST
(In reply to comment #23)
> What about performance?

To test performance of this use the html5-full-render.html perf test. It's a good test of createRendererIfNeeded() and recalcTextStyle().
Comment 26 Takashi Sakamoto 2012-11-21 00:18:04 PST
(In reply to comment #25)
> (In reply to comment #23)
> > What about performance?
> 
> To test performance of this use the html5-full-render.html perf test. It's a good test of createRendererIfNeeded() and recalcTextStyle().

Thank you. I looked at PerfTest/Parser/*.

So I found that this patch makes Parser/tiny-innerHTML much slower (10%-20% slower).
The test updates innerHTML again and again:

PerfTestRunner.measureRunsPerSecond({run:function() {
    var testDiv = document.createElement("div");
    testDiv.style.display = "none";
    document.body.appendChild(testDiv);
    for (var x = 0; x < 100000; x++) {
        testDiv.innerHTML = "This is a tiny HTML document";
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    }
    document.body.removeChild(testDiv);
}});

So the newly added "if" , i.e.

 + else if (node->isTextNode() && (node->parentOrHostNode()->isShadowRoot() || m_context.insertionPoint()))
 +       m_context.setStyle(node->document()->styleResolver()->styleForText(m_context));

is checked every time testDiv.innerHTML is updated. I couldn't find the way to avoid this performance regression.

Best regards,
Takashi Sakamoto
Comment 27 Elliott Sprehn 2012-11-21 13:32:37 PST
(In reply to comment #26)
> (In reply to comment #25)
> > (In reply to comment #23)
> > > What about performance?
> > 
> > To test performance of this use the html5-full-render.html perf test. It's a good test of createRendererIfNeeded() and recalcTextStyle().
> 
> Thank you. I looked at PerfTest/Parser/*.
> 
> So I found that this patch makes Parser/tiny-innerHTML much slower (10%-20% slower).
> The test updates innerHTML again and again:
> 

Can you try this test but with ENABLE(DIALOG_ELEMENT) turned off and ENABLE(FULLSCREEN_API) turned off?  It seems very suspicious that adding this check is such a big perf regression but those two feature flags don't cause similarly massive perf regressions.
Comment 28 Hajime Morrita 2012-11-21 15:48:28 PST
> 
> Can you try this test but with ENABLE(DIALOG_ELEMENT) turned off and ENABLE(FULLSCREEN_API) turned off?  It seems very suspicious that adding this check is such a big perf regression but those two feature flags don't cause similarly massive perf regressions.

Another thing we can try is to use pprof and see the difference
between before and after the change.
Comment 29 Takashi Sakamoto 2012-11-27 01:41:11 PST
Created attachment 176199 [details]
Patch
Comment 30 Takashi Sakamoto 2012-11-27 02:29:11 PST
Thank you for advising, Elliott and Morita-san.

Today I rebased my patch. So I found no big performance regression...

I measured by using the command, "Tools/Scripts/run-perf-tests --release --no-build Parser/\*" and I used the Patch(2012-11-27 01:41 PST).

So I'm now trying to use pperf.

Best regards,
Takashi Sakamoto
Comment 31 Takashi Sakamoto 2012-11-29 01:20:46 PST
Created attachment 176674 [details]
Patch
Comment 32 Takashi Sakamoto 2012-11-29 01:25:33 PST
I created a spreadsheet for Parser/tiny-innerHTML, Parser/html5-full-render, Parser/html-parser:
https://docs.google.com/spreadsheet/ccc?key=0AtdkWCxGaEc2dDhUcTlFanprMUR0cGU0QlB1eWNoMWc

I guess, someone's refactoring would probably hide my change.

Best regards,
Takashi Sakamoto
Comment 33 Dimitri Glazkov (Google) 2012-11-29 10:15:42 PST
(In reply to comment #32)
> I guess, someone's refactoring would probably hide my change.

Not sure what this means :) Can you elaborate?
Comment 34 Takashi Sakamoto 2012-12-03 03:40:05 PST
(In reply to comment #33)
> (In reply to comment #32)
> > I guess, someone's refactoring would probably hide my change.
> 
> Not sure what this means :) Can you elaborate?

I found that some one changed createRendererIfNeeded in NodeRenderingContext.cpp. 
My first patch was for updating NodeRendererFactory::createRendererIfNeeded.
But now NodeRenderingContext::createRendererForTextIfNeeded was implemented for just creating a renderer for a text node. I recreated my patch to update the createRendererForTextIfNeeded.
I think, this change affected number of "if" (or ...) when testDiv.innerHTML = "This is a tiny HTML document" is executed.
 
Best regards,
Takashi Sakamoto
Comment 35 Hajime Morrita 2012-12-05 20:39:03 PST
Comment on attachment 176674 [details]
Patch

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

> Source/WebCore/dom/Text.cpp:292
> +            renderer->setStyle(parent->renderer()->style());

Having these tricky condition in two places is unfortunate and error prone.
Can we put this inside StyleResolver::styleForText() somehow?
Comment 36 Takashi Sakamoto 2012-12-06 20:40:09 PST
Created attachment 178150 [details]
Patch
Comment 37 Takashi Sakamoto 2012-12-06 20:42:41 PST
Comment on attachment 176674 [details]
Patch

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

>> Source/WebCore/dom/Text.cpp:292
>> +            renderer->setStyle(parent->renderer()->style());
> 
> Having these tricky condition in two places is unfortunate and error prone.
> Can we put this inside StyleResolver::styleForText() somehow?

I see. Done.
Comment 38 Hajime Morrita 2012-12-06 20:55:43 PST
Comment on attachment 178150 [details]
Patch

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

> Source/WebCore/dom/NodeRenderingContext.cpp:285
> +    if (m_node->parentOrHostNode()->isShadowRoot() || insertionPoint())

Apparently this check also can be part of styleForText().
Comment 39 Takashi Sakamoto 2012-12-06 22:53:39 PST
Created attachment 178166 [details]
Patch
Comment 40 Hajime Morrita 2012-12-07 00:22:15 PST
Comment on attachment 178166 [details]
Patch

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

> Source/WebCore/css/StyleResolver.cpp:1809
> +        m_style->font().update(0);

This empty style creation code looks like being copied from styleForElement(). can we share this between two method?

> Source/WebCore/css/StyleResolver.cpp:1821
> +        return parentNode->renderStyle();

This code is so cryptic and hard to see its correctness. 
Is it possible to just let stleForText(NodeRenderingContext) do this? 
Is it so slow?
Comment 41 Takashi Sakamoto 2012-12-07 00:25:38 PST
Created attachment 178172 [details]
Patch
Comment 42 Takashi Sakamoto 2012-12-07 01:13:28 PST
Created attachment 178176 [details]
Patch
Comment 43 Takashi Sakamoto 2012-12-07 01:16:06 PST
Created attachment 178177 [details]
Patch
Comment 44 Takashi Sakamoto 2012-12-07 01:17:13 PST
Comment on attachment 178166 [details]
Patch

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

>> Source/WebCore/css/StyleResolver.cpp:1809
>> +        m_style->font().update(0);
> 
> This empty style creation code looks like being copied from styleForElement(). can we share this between two method?

I see. Done.

>> Source/WebCore/css/StyleResolver.cpp:1821
>> +        return parentNode->renderStyle();
> 
> This code is so cryptic and hard to see its correctness. 
> Is it possible to just let stleForText(NodeRenderingContext) do this? 
> Is it so slow?

I agree that this code looks not-good.
I heard that NodeRenderingContext is a little slow. So this code is to creating a fast path, i.e. avoiding creating NodeRenderingContext.
If always using NodeRenderingContext here is ok, I would like to remove this.
Comment 45 Takashi Sakamoto 2012-12-07 01:27:18 PST
Created attachment 178180 [details]
Patch
Comment 46 Takashi Sakamoto 2012-12-07 01:29:25 PST
Comment on attachment 178166 [details]
Patch

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

>>> Source/WebCore/css/StyleResolver.cpp:1821
>>> +        return parentNode->renderStyle();
>> 
>> This code is so cryptic and hard to see its correctness. 
>> Is it possible to just let stleForText(NodeRenderingContext) do this? 
>> Is it so slow?
> 
> I agree that this code looks not-good.
> I heard that NodeRenderingContext is a little slow. So this code is to creating a fast path, i.e. avoiding creating NodeRenderingContext.
> If always using NodeRenderingContext here is ok, I would like to remove this.

Done.
I removed the code.
Comment 47 Elliott Sprehn 2012-12-07 01:38:31 PST
Comment on attachment 178180 [details]
Patch

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

Looks awesome :)

> Source/WebCore/css/StyleResolver.cpp:1781
> +PassRefPtr<RenderStyle> StyleResolver::defaultStyleForElement()

defaultStyleForNode() ? Text are not Elements.

> Source/WebCore/css/StyleResolver.cpp:1794
> +PassRefPtr<RenderStyle> StyleResolver::styleForText(Node* textNode)

This should just take Text* and you can remove the isTextNode() assert below.

> Source/WebCore/dom/NodeRenderingContext.cpp:285
> +    if (UNLIKELY(resetStyleInheritance()))

Does the UNLIKELY actually make a difference? ojan has said it doesn't usually matter (and produces identical assembly).
Comment 48 Dimitri Glazkov (Google) 2012-12-07 08:57:21 PST
Comment on attachment 178180 [details]
Patch

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

>> Source/WebCore/css/StyleResolver.cpp:1781
>> +PassRefPtr<RenderStyle> StyleResolver::defaultStyleForElement()
> 
> defaultStyleForNode() ? Text are not Elements.

In this context, he's just initializing defaults for element style resolution.

>> Source/WebCore/css/StyleResolver.cpp:1794
>> +PassRefPtr<RenderStyle> StyleResolver::styleForText(Node* textNode)
> 
> This should just take Text* and you can remove the isTextNode() assert below.

Good point!

>> Source/WebCore/dom/NodeRenderingContext.cpp:285
>> +    if (UNLIKELY(resetStyleInheritance()))
> 
> Does the UNLIKELY actually make a difference? ojan has said it doesn't usually matter (and produces identical assembly).

It's called UNLIKELY, because it is unlikely to have any effect on your code.
Comment 49 Takashi Sakamoto 2012-12-11 20:46:46 PST
Created attachment 178955 [details]
Patch
Comment 50 Takashi Sakamoto 2012-12-11 20:55:46 PST
Comment on attachment 178180 [details]
Patch

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

>>> Source/WebCore/css/StyleResolver.cpp:1781
>>> +PassRefPtr<RenderStyle> StyleResolver::defaultStyleForElement()
>> 
>> defaultStyleForNode() ? Text are not Elements.
> 
> In this context, he's just initializing defaults for element style resolution.

Yes. Thank you Dimitri. I would like to say so.

>>> Source/WebCore/css/StyleResolver.cpp:1794
>>> +PassRefPtr<RenderStyle> StyleResolver::styleForText(Node* textNode)
>> 
>> This should just take Text* and you can remove the isTextNode() assert below.
> 
> Good point!

Thanks. Done.

>>> Source/WebCore/dom/NodeRenderingContext.cpp:285
>>> +    if (UNLIKELY(resetStyleInheritance()))
>> 
>> Does the UNLIKELY actually make a difference? ojan has said it doesn't usually matter (and produces identical assembly).
> 
> It's called UNLIKELY, because it is unlikely to have any effect on your code.

I removed UNLIKELY. Done.
Comment 51 Hajime Morrita 2012-12-11 21:00:38 PST
Comment on attachment 178955 [details]
Patch

Looks good now. Thanks for the fix!
Comment 52 WebKit Review Bot 2012-12-11 22:25:34 PST
Comment on attachment 178955 [details]
Patch

Clearing flags on attachment: 178955

Committed r137418: <http://trac.webkit.org/changeset/137418>
Comment 53 WebKit Review Bot 2012-12-11 22:25:41 PST
All reviewed patches have been landed.  Closing bug.