Summary: | Progress bar shadow tree sometimes is not relayouted. | ||||||
---|---|---|---|---|---|---|---|
Product: | WebKit | Reporter: | Andrey Khalyavin <halyavin> | ||||
Component: | Layout and Rendering | Assignee: | Nobody <webkit-unassigned> | ||||
Status: | RESOLVED DUPLICATE | ||||||
Severity: | Normal | CC: | tasak | ||||
Priority: | P2 | ||||||
Version: | 528+ (Nightly build) | ||||||
Hardware: | PC | ||||||
OS: | All | ||||||
Attachments: |
|
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 *** |
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.