Bug 100507 - Progress bar shadow tree sometimes is not relayouted.
Summary: Progress bar shadow tree sometimes is not relayouted.
Status: RESOLVED DUPLICATE of bug 83664
Alias: None
Product: WebKit
Classification: Unclassified
Component: Layout and Rendering (show other bugs)
Version: 528+ (Nightly build)
Hardware: PC All
: P2 Normal
Assignee: Nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-10-26 05:06 PDT by Andrey Khalyavin
Modified: 2012-10-29 02:18 PDT (History)
1 user (show)

See Also:


Attachments
test page (758 bytes, text/html)
2012-10-26 05:06 PDT, Andrey Khalyavin
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Andrey Khalyavin 2012-10-26 05:06:54 PDT
Created attachment 170899 [details]
test page

Progress bar shadow tree sometimes is not relayouted.
Steps to reproduce:
1. Open page in attachment.
2. Click on a button.
3. See that first bar is updated while second bar is not.

What is going on behind the cover:
HTMLProgressElement has a shadow tree which consist in 3 nested divs. The most nested div (HTMLProgressElement::m_value) represents progress bar value and is updated by HTMLProgressElement::didElementStateChange method.

When javascripts on the page sets the second progress bar value, m_value node loses IsStyleAttributeValidFlag flag. Then <progress> element is inserted into tree and InDocumentFlag is set in m_value. Then Element::recalcStyle is called on HTMLProgressElement and it executes reattach method for it. Method reattach calls attach and as result m_value receives IsAttachedFlag. Then HTMLProgressElement::attach calls didElementStateChange method which calls m_value->setWidthPercentage which sets InlineStyleChange flag to m_value node and ChildNeedsStyleRecalc flag to all its parent nodes. But then reattach methods returns and Element::recalcStyle calls clearNeedsStyleRecalc and clearChildNeedsStyleRecalc methods on HTMLProgressElement node. 

So now we have m_value node that needs style recalculation but HTMLProgressElement node doesn't have ChildNeedsStyleRecalcFlag flag. As a result, any subsequent changes to progress element doesn't do anything since m_value is already marked as needed to recalculate style. But m_value never recalculates style since HTMLProgressElement doesn't have ChildNeedsRecalcFlag.
Comment 1 Takashi Sakamoto 2012-10-29 02:18:01 PDT
The reason why progress bar is not re-layouted is:
- HTMLProgressElement updates inline styles, i.e. setWidthPercentage, in HTMLProgressElement::attach().
- Element::recalcStyle updates HTMLProgressElement's style by using "reattach()".

Element::reaclcStyle()
...
            // FIXME: The style gets computed twice by calling attach. We could do better if we passed the style along.
            reattach();
            // attach recalculates the style for all children. No need to do it twice.
            clearNeedsStyleRecalc();
            clearChildNeedsStyleRecalc();
...

So after reattach(), clearNeedsStyleRecalc() and clearChildNeedsStyleRecalc() reset update flags set by setWidthPercentage. Now ProgressValueElement has had "InlineStyleChange" style change type, but its relayout flag is cleared. This disables "setNeedsStyleRecalc" to relayout:

void Node::setNeedsStyleRecalc(...)
...
    if (existingChangeType == NoStyleChange)
        markAncestorsWithChildNeedsStyleRecalc();
...

I will fix this issue by bug 83664.

Best regards,
Takashi Sakamoto

*** This bug has been marked as a duplicate of bug 83664 ***