haikuwebkit/LayoutTests/fast/selectors/class-direct-adjacent-style...

37 lines
2.8 KiB
Plaintext
Raw Permalink Normal View History

Style invalidation does not work for adjacent node updates https://bugs.webkit.org/show_bug.cgi?id=136145 Reviewed by Antti Koivisto. Source/WebCore: There were a bunch of cases in which the style would be in an inconsistent state until the style resolver kicks in for the entire document. For example, let's take the selector "foo.bar + target". When the class "bar" changes, the element foo is invalidated. The element target is untouched. Now, if the style of "target" is accessed, nodeOrItsAncestorNeedsStyleRecalc() returns false and the old style is accessed. At some point, when the style of the entire document is resolved, the node "foo" is styled, and "target" is invalidated. To fix the issue, this patch adds an extra flag keeping track of subtrees that have any node needing style recalc: DirectChildNeedsStyleRecalcFlag. When invalidating the node "foo", its parent is marked with DirectChildNeedsStyleRecalcFlag to note that one of the child nodes has an invalid style. When verifying the style state in nodeOrItsAncestorNeedsStyleRecalc(), we check that flag in addition to the siblings dependencies to find if the node is part of a subtree that may be invalid due to sibling selectors. Similarly, in the style resolver, we use the flag to clear the style on all elements that could potentially be invalid. This patch removes the changes introduced by r172721 (The style is not updated correctly when the pseudo class :empty is applied on anything but the rightmost element). That bug was just a special case of what is solved here. Tests: fast/selectors/attribute-direct-adjacent-style-update.html fast/selectors/attribute-sibling-style-update.html fast/selectors/class-direct-adjacent-style-update.html fast/selectors/class-sibling-style-update.html fast/selectors/first-child-direct-adjacent-style-update.html fast/selectors/first-child-sibling-style-update.html * css/SelectorChecker.cpp: (WebCore::SelectorChecker::checkOne): * cssjit/SelectorCompiler.cpp: (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsEmpty): (WebCore::SelectorCompiler::setStyleOfSiblingsAffectedByEmpty): Deleted. * dom/ContainerNode.h: (WebCore::ContainerNode::directChildNeedsStyleRecalc): (WebCore::ContainerNode::setDirectChildNeedsStyleRecalc): Remove the special case for :empty. * dom/Document.cpp: (WebCore::nodeOrItsAncestorNeedsStyleRecalc): * dom/Element.cpp: (WebCore::checkForEmptyStyleChange): (WebCore::checkForSiblingStyleChanges): (WebCore::Element::setStyleOfSiblingsAffectedByEmpty): Deleted. (WebCore::Element::rareDataStyleOfSiblingsAffectedByEmpty): Deleted. * dom/Element.h: (WebCore::Element::styleOfSiblingsAffectedByEmpty): Deleted. * dom/ElementRareData.h: (WebCore::ElementRareData::ElementRareData): (WebCore::ElementRareData::styleOfSiblingsAffectedByEmpty): Deleted. (WebCore::ElementRareData::setStyleOfSiblingsAffectedByEmpty): Deleted. * dom/Node.cpp: (WebCore::markAncestorsWithChildNeedsStyleRecalc): (WebCore::Node::setNeedsStyleRecalc): (WebCore::Node::markAncestorsWithChildNeedsStyleRecalc): Deleted. * dom/Node.h: (WebCore::Node::clearChildNeedsStyleRecalc): * style/StyleResolveTree.cpp: (WebCore::Style::resetStyleForNonRenderedDescendants): LayoutTests: Add tests covering the basic cases: classes and attributes. First-child covers the basic positional updates. The tests have a version without any indirect adjacent ("~") because the marking used for those is much more generic and having them hide some bugs. Some tests are still failing. That is due to the style resolver not handling direct siblings ("+") correctly when there are multiple of them. I will address that separately. * fast/selectors/attribute-direct-adjacent-style-update-expected.txt: Added. * fast/selectors/attribute-direct-adjacent-style-update.html: Added. * fast/selectors/attribute-sibling-style-update-expected.txt: Added. * fast/selectors/attribute-sibling-style-update.html: Added. * fast/selectors/class-direct-adjacent-style-update-expected.txt: Added. * fast/selectors/class-direct-adjacent-style-update.html: Added. * fast/selectors/class-sibling-style-update-expected.txt: Added. * fast/selectors/class-sibling-style-update.html: Added. * fast/selectors/first-child-direct-adjacent-style-update.html: Added. * fast/selectors/first-child-sibling-style-update-expected.txt: Added. * fast/selectors/first-child-sibling-style-update.html: Added. * fast/selectors/placeholder-shown-sibling-style-update-expected.txt: Canonical link: https://commits.webkit.org/154010@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@172880 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2014-08-23 04:30:33 +00:00
Test style update caused by class changes on a sibling. This test does not use any sibling "~" combinator to avoid its more generic marking.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
Initial state does not match, the class is not there.
PASS getComputedStyle(document.getElementById("bar-with-renderer")).backgroundColor is "rgb(255, 255, 255)"
PASS getComputedStyle(document.getElementById("baz-with-renderer")).backgroundColor is "rgb(255, 255, 255)"
PASS getComputedStyle(document.getElementById("bar-without-renderer")).backgroundColor is "rgb(255, 255, 255)"
PASS getComputedStyle(document.getElementById("baz-without-renderer")).backgroundColor is "rgb(255, 255, 255)"
PASS getComputedStyle(document.getElementById("bar-with-renderer")).color is "rgb(0, 0, 0)"
PASS getComputedStyle(document.getElementById("baz-with-renderer")).color is "rgb(0, 0, 0)"
PASS getComputedStyle(document.getElementById("bar-without-renderer")).color is "rgb(0, 0, 0)"
PASS getComputedStyle(document.getElementById("baz-without-renderer")).color is "rgb(0, 0, 0)"
Adding the class, the extra rules should match.
Fix style invalidation of elements with multiple siblings dependencies https://bugs.webkit.org/show_bug.cgi?id=136472 Reviewed by Andreas Kling. Source/WebCore: Previously, style invalidation of siblings was driven by a pair of flags: -ChildrenAffectedByDirectAdjacentRules. -ChildrenAffectedByForwardPositionalRules. When ChildrenAffectedByDirectAdjacentRules was set, the element after an element with "needsStyleRecalc" was also recomputed. While this work for pair of elements: a + b It does not work for more than that. For example, with a.propery + b + c When the state of <a> changes, the style of <b> was updated, which is useless. The style of <c> was untouched, which is incorrect. When ChildrenAffectedByForwardPositionalRules, all elements after one with "needsStyleRecalc" were invalidated. While more correct, it caused avalanche of style recalc and was not a very useful "optimization". To fix the correctness issues (e.g. "a + b + c"), I could have gone two ways: 1) Invalidate the parent of a, b, c. The children would always get a correct style when their parent's style would be resolved. 2) Create invalidation relations to enforce that the right siblings are invalidated. I have decided for a weak version of (2). The reason is that most DOM trees are very shallow while being very wide. Invalidating the parent generally causes massive style recalculation. To keep things simple for now, there is no explicit dependency list between siblings. Instead, each element has a pair of flag: 1) The element's style depends on the state of a previous sibling. 2) The element's state affects following siblings. With the notation "<-" for (1), "->" for (2), the selector "a + b + c" create this kind of marking: a + b + c -> -> <- When <a> is invalidated, the style resolver will go through the chain of dependent elements and invalidate any element that can be affected by a prior invalidation, here <c>. Overlaps are possible. For example with the two selector, "a + b + c", "b ~ d" the marking would be a + b + c + d -> -> -> <- <- A change in <a> would invalidate both <c> and <d>. This is overkill, but the end result is correct and it is a net improvement over the previous flags. As usual, the CSS JIT makes an effort at compile time to reduce tree marking. SelectorChecker marks everything as usual. Tests: fast/css/direct-adjacent-style-update-optimization.html fast/css/indirect-adjacent-style-update-optimization.html fast/css/non-matching-adjacent-style-update.html fast/selectors/first-of-type-direct-adjacent-style-update.html fast/selectors/first-of-type-sibling-style-update.html fast/selectors/id-direct-adjacent-style-update.html fast/selectors/id-sibling-style-update.html fast/selectors/nth-child-as-first-simple-selector-style-update.html fast/selectors/nth-child-direct-adjacent-style-update.html fast/selectors/nth-child-style-update.html * css/SelectorChecker.cpp: (WebCore::isFirstOfType): (WebCore::countElementsBefore): (WebCore::countElementsOfTypeBefore): Counting selectors are not unlike adjacent combinators, they are handled the exact same way. For example a :nth-child(4) would generate somewhat similar marking as :first-child + * + * + * Everything prior to the element with the counter affects the style of the element. (WebCore::hasScrollbarPseudoElement): The assertion was incorrect. You can get an scrollbar pseudo ID on an element without scrollbar. It will never match, but such case is possible. (WebCore::SelectorChecker::matchRecursively): (WebCore::SelectorChecker::checkOne): * css/StyleResolver.cpp: (WebCore::StyleResolver::canShareStyleWithElement): Previously, any subtree affected by sibling selectors were unshareable. That was done by checking for Element::hasFlagsSetDuringStylingOfChildren(). Now that sibling relation are local, they no longer prevent sharing of all children. Instead, we can test locally for subgroup with sibling relations. * cssjit/SelectorCompiler.cpp: (WebCore::SelectorCompiler::isAdjacentRelation): (WebCore::SelectorCompiler::shouldMarkStyleIsAffectedByPreviousSibling): (WebCore::SelectorCompiler::SelectorCodeGenerator::generateSelectorChecker): (WebCore::SelectorCompiler::SelectorCodeGenerator::generateDirectAdjacentTreeWalker): (WebCore::SelectorCompiler::SelectorCodeGenerator::generateIndirectAdjacentTreeWalker): (WebCore::SelectorCompiler::SelectorCodeGenerator::markElementIfResolvingStyle): (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsNthChild): (WebCore::SelectorCompiler::SelectorCodeGenerator::markParentElementIfResolvingStyle): Deleted. * dom/Document.cpp: (WebCore::nodeOrItsAncestorNeedsStyleRecalc): * dom/Element.cpp: (WebCore::checkForSiblingStyleChanges): (WebCore::Element::hasFlagsSetDuringStylingOfChildren): (WebCore::Element::setChildrenAffectedByForwardPositionalRules): Deleted. (WebCore::Element::rareDataChildrenAffectedByForwardPositionalRules): Deleted. * dom/Element.h: (WebCore::Element::affectsNextSiblingElementStyle): (WebCore::Element::setAffectsNextSiblingElementStyle): (WebCore::Element::setStyleIsAffectedByPreviousSibling): (WebCore::Element::childrenAffectedByPositionalRules): Deleted. (WebCore::Element::childrenAffectedByDirectAdjacentRules): Deleted. (WebCore::Element::childrenAffectedByForwardPositionalRules): Deleted. (WebCore::Element::setChildrenAffectedByDirectAdjacentRules): Deleted. (WebCore::Element::setChildrenAffectedByForwardPositionalRules): Deleted. * dom/ElementRareData.h: (WebCore::ElementRareData::ElementRareData): (WebCore::ElementRareData::resetDynamicRestyleObservations): (WebCore::ElementRareData::childrenAffectedByForwardPositionalRules): Deleted. (WebCore::ElementRareData::setChildrenAffectedByForwardPositionalRules): Deleted. * dom/Node.h: (WebCore::Node::styleIsAffectedByPreviousSibling): (WebCore::Node::flagAffectsNextSiblingElementStyle): (WebCore::Node::flagStyleIsAffectedByPreviousSibling): (WebCore::Node::flagChildrenAffectedByDirectAdjacentRulesFlag): Deleted. * html/HTMLElement.h: (WebCore::HTMLElement::isHTMLUnknownElement): * html/HTMLUnknownElement.h: * style/StyleResolveTree.cpp: (WebCore::Style::resetStyleForNonRenderedDescendants): (WebCore::Style::resolveTree): LayoutTests: The test coverage was pretty bad. :( I tried to cover the most obvious problems. * fast/css/direct-adjacent-style-update-optimization-expected.txt: Added. * fast/css/direct-adjacent-style-update-optimization.html: Added. * fast/css/indirect-adjacent-style-update-optimization-expected.txt: Added. * fast/css/indirect-adjacent-style-update-optimization.html: Added. * fast/css/non-matching-adjacent-style-update-expected.txt: Added. * fast/css/non-matching-adjacent-style-update.html: Added. * fast/selectors/attribute-direct-adjacent-style-update-expected.txt: * fast/selectors/class-direct-adjacent-style-update-expected.txt: * fast/selectors/first-child-direct-adjacent-style-update-expected.txt: * fast/selectors/first-of-type-direct-adjacent-style-update-expected.txt: Copied from LayoutTests/fast/selectors/attribute-direct-adjacent-style-update-expected.txt. * fast/selectors/first-of-type-direct-adjacent-style-update.html: Added. * fast/selectors/first-of-type-sibling-style-update-expected.txt: Added. * fast/selectors/first-of-type-sibling-style-update.html: Added. * fast/selectors/id-direct-adjacent-style-update-expected.txt: Copied from LayoutTests/fast/selectors/attribute-direct-adjacent-style-update-expected.txt. * fast/selectors/id-direct-adjacent-style-update.html: Added. * fast/selectors/id-sibling-style-update-expected.txt: Added. * fast/selectors/id-sibling-style-update.html: Added. * fast/selectors/nth-child-as-first-simple-selector-style-update-expected.txt: Added. * fast/selectors/nth-child-as-first-simple-selector-style-update.html: Added. * fast/selectors/nth-child-direct-adjacent-style-update-expected.txt: Copied from LayoutTests/fast/selectors/attribute-direct-adjacent-style-update-expected.txt. * fast/selectors/nth-child-direct-adjacent-style-update.html: Added. * fast/selectors/nth-child-style-update-expected.txt: Added. * fast/selectors/nth-child-style-update.html: Added. Canonical link: https://commits.webkit.org/154293@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@173229 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2014-09-03 21:30:31 +00:00
PASS getComputedStyle(document.getElementById("bar-with-renderer")).backgroundColor is "rgb(1, 2, 3)"
Style invalidation does not work for adjacent node updates https://bugs.webkit.org/show_bug.cgi?id=136145 Reviewed by Antti Koivisto. Source/WebCore: There were a bunch of cases in which the style would be in an inconsistent state until the style resolver kicks in for the entire document. For example, let's take the selector "foo.bar + target". When the class "bar" changes, the element foo is invalidated. The element target is untouched. Now, if the style of "target" is accessed, nodeOrItsAncestorNeedsStyleRecalc() returns false and the old style is accessed. At some point, when the style of the entire document is resolved, the node "foo" is styled, and "target" is invalidated. To fix the issue, this patch adds an extra flag keeping track of subtrees that have any node needing style recalc: DirectChildNeedsStyleRecalcFlag. When invalidating the node "foo", its parent is marked with DirectChildNeedsStyleRecalcFlag to note that one of the child nodes has an invalid style. When verifying the style state in nodeOrItsAncestorNeedsStyleRecalc(), we check that flag in addition to the siblings dependencies to find if the node is part of a subtree that may be invalid due to sibling selectors. Similarly, in the style resolver, we use the flag to clear the style on all elements that could potentially be invalid. This patch removes the changes introduced by r172721 (The style is not updated correctly when the pseudo class :empty is applied on anything but the rightmost element). That bug was just a special case of what is solved here. Tests: fast/selectors/attribute-direct-adjacent-style-update.html fast/selectors/attribute-sibling-style-update.html fast/selectors/class-direct-adjacent-style-update.html fast/selectors/class-sibling-style-update.html fast/selectors/first-child-direct-adjacent-style-update.html fast/selectors/first-child-sibling-style-update.html * css/SelectorChecker.cpp: (WebCore::SelectorChecker::checkOne): * cssjit/SelectorCompiler.cpp: (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsEmpty): (WebCore::SelectorCompiler::setStyleOfSiblingsAffectedByEmpty): Deleted. * dom/ContainerNode.h: (WebCore::ContainerNode::directChildNeedsStyleRecalc): (WebCore::ContainerNode::setDirectChildNeedsStyleRecalc): Remove the special case for :empty. * dom/Document.cpp: (WebCore::nodeOrItsAncestorNeedsStyleRecalc): * dom/Element.cpp: (WebCore::checkForEmptyStyleChange): (WebCore::checkForSiblingStyleChanges): (WebCore::Element::setStyleOfSiblingsAffectedByEmpty): Deleted. (WebCore::Element::rareDataStyleOfSiblingsAffectedByEmpty): Deleted. * dom/Element.h: (WebCore::Element::styleOfSiblingsAffectedByEmpty): Deleted. * dom/ElementRareData.h: (WebCore::ElementRareData::ElementRareData): (WebCore::ElementRareData::styleOfSiblingsAffectedByEmpty): Deleted. (WebCore::ElementRareData::setStyleOfSiblingsAffectedByEmpty): Deleted. * dom/Node.cpp: (WebCore::markAncestorsWithChildNeedsStyleRecalc): (WebCore::Node::setNeedsStyleRecalc): (WebCore::Node::markAncestorsWithChildNeedsStyleRecalc): Deleted. * dom/Node.h: (WebCore::Node::clearChildNeedsStyleRecalc): * style/StyleResolveTree.cpp: (WebCore::Style::resetStyleForNonRenderedDescendants): LayoutTests: Add tests covering the basic cases: classes and attributes. First-child covers the basic positional updates. The tests have a version without any indirect adjacent ("~") because the marking used for those is much more generic and having them hide some bugs. Some tests are still failing. That is due to the style resolver not handling direct siblings ("+") correctly when there are multiple of them. I will address that separately. * fast/selectors/attribute-direct-adjacent-style-update-expected.txt: Added. * fast/selectors/attribute-direct-adjacent-style-update.html: Added. * fast/selectors/attribute-sibling-style-update-expected.txt: Added. * fast/selectors/attribute-sibling-style-update.html: Added. * fast/selectors/class-direct-adjacent-style-update-expected.txt: Added. * fast/selectors/class-direct-adjacent-style-update.html: Added. * fast/selectors/class-sibling-style-update-expected.txt: Added. * fast/selectors/class-sibling-style-update.html: Added. * fast/selectors/first-child-direct-adjacent-style-update.html: Added. * fast/selectors/first-child-sibling-style-update-expected.txt: Added. * fast/selectors/first-child-sibling-style-update.html: Added. * fast/selectors/placeholder-shown-sibling-style-update-expected.txt: Canonical link: https://commits.webkit.org/154010@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@172880 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2014-08-23 04:30:33 +00:00
PASS getComputedStyle(document.getElementById("baz-with-renderer")).backgroundColor is "rgb(255, 255, 255)"
PASS getComputedStyle(document.getElementById("bar-without-renderer")).backgroundColor is "rgb(1, 2, 3)"
PASS getComputedStyle(document.getElementById("baz-without-renderer")).backgroundColor is "rgb(255, 255, 255)"
PASS getComputedStyle(document.getElementById("bar-with-renderer")).color is "rgb(0, 0, 0)"
Fix style invalidation of elements with multiple siblings dependencies https://bugs.webkit.org/show_bug.cgi?id=136472 Reviewed by Andreas Kling. Source/WebCore: Previously, style invalidation of siblings was driven by a pair of flags: -ChildrenAffectedByDirectAdjacentRules. -ChildrenAffectedByForwardPositionalRules. When ChildrenAffectedByDirectAdjacentRules was set, the element after an element with "needsStyleRecalc" was also recomputed. While this work for pair of elements: a + b It does not work for more than that. For example, with a.propery + b + c When the state of <a> changes, the style of <b> was updated, which is useless. The style of <c> was untouched, which is incorrect. When ChildrenAffectedByForwardPositionalRules, all elements after one with "needsStyleRecalc" were invalidated. While more correct, it caused avalanche of style recalc and was not a very useful "optimization". To fix the correctness issues (e.g. "a + b + c"), I could have gone two ways: 1) Invalidate the parent of a, b, c. The children would always get a correct style when their parent's style would be resolved. 2) Create invalidation relations to enforce that the right siblings are invalidated. I have decided for a weak version of (2). The reason is that most DOM trees are very shallow while being very wide. Invalidating the parent generally causes massive style recalculation. To keep things simple for now, there is no explicit dependency list between siblings. Instead, each element has a pair of flag: 1) The element's style depends on the state of a previous sibling. 2) The element's state affects following siblings. With the notation "<-" for (1), "->" for (2), the selector "a + b + c" create this kind of marking: a + b + c -> -> <- When <a> is invalidated, the style resolver will go through the chain of dependent elements and invalidate any element that can be affected by a prior invalidation, here <c>. Overlaps are possible. For example with the two selector, "a + b + c", "b ~ d" the marking would be a + b + c + d -> -> -> <- <- A change in <a> would invalidate both <c> and <d>. This is overkill, but the end result is correct and it is a net improvement over the previous flags. As usual, the CSS JIT makes an effort at compile time to reduce tree marking. SelectorChecker marks everything as usual. Tests: fast/css/direct-adjacent-style-update-optimization.html fast/css/indirect-adjacent-style-update-optimization.html fast/css/non-matching-adjacent-style-update.html fast/selectors/first-of-type-direct-adjacent-style-update.html fast/selectors/first-of-type-sibling-style-update.html fast/selectors/id-direct-adjacent-style-update.html fast/selectors/id-sibling-style-update.html fast/selectors/nth-child-as-first-simple-selector-style-update.html fast/selectors/nth-child-direct-adjacent-style-update.html fast/selectors/nth-child-style-update.html * css/SelectorChecker.cpp: (WebCore::isFirstOfType): (WebCore::countElementsBefore): (WebCore::countElementsOfTypeBefore): Counting selectors are not unlike adjacent combinators, they are handled the exact same way. For example a :nth-child(4) would generate somewhat similar marking as :first-child + * + * + * Everything prior to the element with the counter affects the style of the element. (WebCore::hasScrollbarPseudoElement): The assertion was incorrect. You can get an scrollbar pseudo ID on an element without scrollbar. It will never match, but such case is possible. (WebCore::SelectorChecker::matchRecursively): (WebCore::SelectorChecker::checkOne): * css/StyleResolver.cpp: (WebCore::StyleResolver::canShareStyleWithElement): Previously, any subtree affected by sibling selectors were unshareable. That was done by checking for Element::hasFlagsSetDuringStylingOfChildren(). Now that sibling relation are local, they no longer prevent sharing of all children. Instead, we can test locally for subgroup with sibling relations. * cssjit/SelectorCompiler.cpp: (WebCore::SelectorCompiler::isAdjacentRelation): (WebCore::SelectorCompiler::shouldMarkStyleIsAffectedByPreviousSibling): (WebCore::SelectorCompiler::SelectorCodeGenerator::generateSelectorChecker): (WebCore::SelectorCompiler::SelectorCodeGenerator::generateDirectAdjacentTreeWalker): (WebCore::SelectorCompiler::SelectorCodeGenerator::generateIndirectAdjacentTreeWalker): (WebCore::SelectorCompiler::SelectorCodeGenerator::markElementIfResolvingStyle): (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsNthChild): (WebCore::SelectorCompiler::SelectorCodeGenerator::markParentElementIfResolvingStyle): Deleted. * dom/Document.cpp: (WebCore::nodeOrItsAncestorNeedsStyleRecalc): * dom/Element.cpp: (WebCore::checkForSiblingStyleChanges): (WebCore::Element::hasFlagsSetDuringStylingOfChildren): (WebCore::Element::setChildrenAffectedByForwardPositionalRules): Deleted. (WebCore::Element::rareDataChildrenAffectedByForwardPositionalRules): Deleted. * dom/Element.h: (WebCore::Element::affectsNextSiblingElementStyle): (WebCore::Element::setAffectsNextSiblingElementStyle): (WebCore::Element::setStyleIsAffectedByPreviousSibling): (WebCore::Element::childrenAffectedByPositionalRules): Deleted. (WebCore::Element::childrenAffectedByDirectAdjacentRules): Deleted. (WebCore::Element::childrenAffectedByForwardPositionalRules): Deleted. (WebCore::Element::setChildrenAffectedByDirectAdjacentRules): Deleted. (WebCore::Element::setChildrenAffectedByForwardPositionalRules): Deleted. * dom/ElementRareData.h: (WebCore::ElementRareData::ElementRareData): (WebCore::ElementRareData::resetDynamicRestyleObservations): (WebCore::ElementRareData::childrenAffectedByForwardPositionalRules): Deleted. (WebCore::ElementRareData::setChildrenAffectedByForwardPositionalRules): Deleted. * dom/Node.h: (WebCore::Node::styleIsAffectedByPreviousSibling): (WebCore::Node::flagAffectsNextSiblingElementStyle): (WebCore::Node::flagStyleIsAffectedByPreviousSibling): (WebCore::Node::flagChildrenAffectedByDirectAdjacentRulesFlag): Deleted. * html/HTMLElement.h: (WebCore::HTMLElement::isHTMLUnknownElement): * html/HTMLUnknownElement.h: * style/StyleResolveTree.cpp: (WebCore::Style::resetStyleForNonRenderedDescendants): (WebCore::Style::resolveTree): LayoutTests: The test coverage was pretty bad. :( I tried to cover the most obvious problems. * fast/css/direct-adjacent-style-update-optimization-expected.txt: Added. * fast/css/direct-adjacent-style-update-optimization.html: Added. * fast/css/indirect-adjacent-style-update-optimization-expected.txt: Added. * fast/css/indirect-adjacent-style-update-optimization.html: Added. * fast/css/non-matching-adjacent-style-update-expected.txt: Added. * fast/css/non-matching-adjacent-style-update.html: Added. * fast/selectors/attribute-direct-adjacent-style-update-expected.txt: * fast/selectors/class-direct-adjacent-style-update-expected.txt: * fast/selectors/first-child-direct-adjacent-style-update-expected.txt: * fast/selectors/first-of-type-direct-adjacent-style-update-expected.txt: Copied from LayoutTests/fast/selectors/attribute-direct-adjacent-style-update-expected.txt. * fast/selectors/first-of-type-direct-adjacent-style-update.html: Added. * fast/selectors/first-of-type-sibling-style-update-expected.txt: Added. * fast/selectors/first-of-type-sibling-style-update.html: Added. * fast/selectors/id-direct-adjacent-style-update-expected.txt: Copied from LayoutTests/fast/selectors/attribute-direct-adjacent-style-update-expected.txt. * fast/selectors/id-direct-adjacent-style-update.html: Added. * fast/selectors/id-sibling-style-update-expected.txt: Added. * fast/selectors/id-sibling-style-update.html: Added. * fast/selectors/nth-child-as-first-simple-selector-style-update-expected.txt: Added. * fast/selectors/nth-child-as-first-simple-selector-style-update.html: Added. * fast/selectors/nth-child-direct-adjacent-style-update-expected.txt: Copied from LayoutTests/fast/selectors/attribute-direct-adjacent-style-update-expected.txt. * fast/selectors/nth-child-direct-adjacent-style-update.html: Added. * fast/selectors/nth-child-style-update-expected.txt: Added. * fast/selectors/nth-child-style-update.html: Added. Canonical link: https://commits.webkit.org/154293@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@173229 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2014-09-03 21:30:31 +00:00
PASS getComputedStyle(document.getElementById("baz-with-renderer")).color is "rgb(4, 5, 6)"
Style invalidation does not work for adjacent node updates https://bugs.webkit.org/show_bug.cgi?id=136145 Reviewed by Antti Koivisto. Source/WebCore: There were a bunch of cases in which the style would be in an inconsistent state until the style resolver kicks in for the entire document. For example, let's take the selector "foo.bar + target". When the class "bar" changes, the element foo is invalidated. The element target is untouched. Now, if the style of "target" is accessed, nodeOrItsAncestorNeedsStyleRecalc() returns false and the old style is accessed. At some point, when the style of the entire document is resolved, the node "foo" is styled, and "target" is invalidated. To fix the issue, this patch adds an extra flag keeping track of subtrees that have any node needing style recalc: DirectChildNeedsStyleRecalcFlag. When invalidating the node "foo", its parent is marked with DirectChildNeedsStyleRecalcFlag to note that one of the child nodes has an invalid style. When verifying the style state in nodeOrItsAncestorNeedsStyleRecalc(), we check that flag in addition to the siblings dependencies to find if the node is part of a subtree that may be invalid due to sibling selectors. Similarly, in the style resolver, we use the flag to clear the style on all elements that could potentially be invalid. This patch removes the changes introduced by r172721 (The style is not updated correctly when the pseudo class :empty is applied on anything but the rightmost element). That bug was just a special case of what is solved here. Tests: fast/selectors/attribute-direct-adjacent-style-update.html fast/selectors/attribute-sibling-style-update.html fast/selectors/class-direct-adjacent-style-update.html fast/selectors/class-sibling-style-update.html fast/selectors/first-child-direct-adjacent-style-update.html fast/selectors/first-child-sibling-style-update.html * css/SelectorChecker.cpp: (WebCore::SelectorChecker::checkOne): * cssjit/SelectorCompiler.cpp: (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsEmpty): (WebCore::SelectorCompiler::setStyleOfSiblingsAffectedByEmpty): Deleted. * dom/ContainerNode.h: (WebCore::ContainerNode::directChildNeedsStyleRecalc): (WebCore::ContainerNode::setDirectChildNeedsStyleRecalc): Remove the special case for :empty. * dom/Document.cpp: (WebCore::nodeOrItsAncestorNeedsStyleRecalc): * dom/Element.cpp: (WebCore::checkForEmptyStyleChange): (WebCore::checkForSiblingStyleChanges): (WebCore::Element::setStyleOfSiblingsAffectedByEmpty): Deleted. (WebCore::Element::rareDataStyleOfSiblingsAffectedByEmpty): Deleted. * dom/Element.h: (WebCore::Element::styleOfSiblingsAffectedByEmpty): Deleted. * dom/ElementRareData.h: (WebCore::ElementRareData::ElementRareData): (WebCore::ElementRareData::styleOfSiblingsAffectedByEmpty): Deleted. (WebCore::ElementRareData::setStyleOfSiblingsAffectedByEmpty): Deleted. * dom/Node.cpp: (WebCore::markAncestorsWithChildNeedsStyleRecalc): (WebCore::Node::setNeedsStyleRecalc): (WebCore::Node::markAncestorsWithChildNeedsStyleRecalc): Deleted. * dom/Node.h: (WebCore::Node::clearChildNeedsStyleRecalc): * style/StyleResolveTree.cpp: (WebCore::Style::resetStyleForNonRenderedDescendants): LayoutTests: Add tests covering the basic cases: classes and attributes. First-child covers the basic positional updates. The tests have a version without any indirect adjacent ("~") because the marking used for those is much more generic and having them hide some bugs. Some tests are still failing. That is due to the style resolver not handling direct siblings ("+") correctly when there are multiple of them. I will address that separately. * fast/selectors/attribute-direct-adjacent-style-update-expected.txt: Added. * fast/selectors/attribute-direct-adjacent-style-update.html: Added. * fast/selectors/attribute-sibling-style-update-expected.txt: Added. * fast/selectors/attribute-sibling-style-update.html: Added. * fast/selectors/class-direct-adjacent-style-update-expected.txt: Added. * fast/selectors/class-direct-adjacent-style-update.html: Added. * fast/selectors/class-sibling-style-update-expected.txt: Added. * fast/selectors/class-sibling-style-update.html: Added. * fast/selectors/first-child-direct-adjacent-style-update.html: Added. * fast/selectors/first-child-sibling-style-update-expected.txt: Added. * fast/selectors/first-child-sibling-style-update.html: Added. * fast/selectors/placeholder-shown-sibling-style-update-expected.txt: Canonical link: https://commits.webkit.org/154010@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@172880 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2014-08-23 04:30:33 +00:00
PASS getComputedStyle(document.getElementById("bar-without-renderer")).color is "rgb(0, 0, 0)"
PASS getComputedStyle(document.getElementById("baz-without-renderer")).color is "rgb(4, 5, 6)"
Removing the class, we should be back to the original state.
PASS getComputedStyle(document.getElementById("bar-with-renderer")).backgroundColor is "rgb(255, 255, 255)"
PASS getComputedStyle(document.getElementById("baz-with-renderer")).backgroundColor is "rgb(255, 255, 255)"
PASS getComputedStyle(document.getElementById("bar-without-renderer")).backgroundColor is "rgb(255, 255, 255)"
PASS getComputedStyle(document.getElementById("baz-without-renderer")).backgroundColor is "rgb(255, 255, 255)"
PASS getComputedStyle(document.getElementById("bar-with-renderer")).color is "rgb(0, 0, 0)"
PASS getComputedStyle(document.getElementById("baz-with-renderer")).color is "rgb(0, 0, 0)"
PASS getComputedStyle(document.getElementById("bar-without-renderer")).color is "rgb(0, 0, 0)"
PASS getComputedStyle(document.getElementById("baz-without-renderer")).color is "rgb(0, 0, 0)"
PASS successfullyParsed is true
TEST COMPLETE