Subtrees with :first-child and :last-child are not invalidated when siblings are...
authorbenjamin@webkit.org <benjamin@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 18 Jun 2014 22:10:36 +0000 (22:10 +0000)
committerbenjamin@webkit.org <benjamin@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 18 Jun 2014 22:10:36 +0000 (22:10 +0000)
commitef3ae90eaf68df5ca0ba5c6b79e1a489ce58f57a
tree589cb1025d32c4f9374dbc3c43c200008c46f552
parent15a46c81cd53e487aee8f7cd1ea90a6e6ee832bb
Subtrees with :first-child and :last-child are not invalidated when siblings are added/removed
https://bugs.webkit.org/show_bug.cgi?id=133934

Reviewed by Antti Koivisto.

Source/WebCore:
When adding/removing nodes on an element, we try to invalidate only the elements that are
affected. In the case of :first-child and :last-child, that optimizations is implemented
through two types of flags that are updated during style resolution.

The first flag is childrenAffectedByFirstChildRules (childrenAffectedByLastChildRules),
set on the parent of any element that could be affected by :first-child (:last-child).

The other part of the optimization is marking the style itself with firstChildState (lastChildState)
to further reduce invalidations.

The problem in this case happen with a subtree of element is detached. Since there is no renderer,
the computed style is resolved ad-hoc and stored directly on the element. When the element is moved,
the computed style was never cleared because the invalidation optimizations were not handling
elements without style.

Credit to Yusuke Suzuki for discovering the issue and creating test cases.

Tests: fast/css/getComputedStyle/empty-update-without-renderer.html
       fast/css/getComputedStyle/first-child-update-without-renderer.html
       fast/css/getComputedStyle/last-child-update-without-renderer.html

* dom/Element.cpp:
(WebCore::checkForEmptyStyleChange):
Clean up: pull the style directly from the function instead of expection the call sites to do that.
Refine the checks to avoid invalidation.

(WebCore::checkForSiblingStyleChanges):
Do not early return if the parent is detached, the children may still need invalidation.

When there is no renderer, assume the worst first-child/last-child and force the invalidation.

(WebCore::Element::childrenChanged):

LayoutTests:
* fast/css/getComputedStyle/empty-update-without-renderer-expected.txt: Added.
* fast/css/getComputedStyle/empty-update-without-renderer.html: Added.
* fast/css/getComputedStyle/first-child-update-without-renderer-expected.txt: Added.
* fast/css/getComputedStyle/first-child-update-without-renderer.html: Added.
* fast/css/getComputedStyle/last-child-update-without-renderer-expected.txt: Added.
* fast/css/getComputedStyle/last-child-update-without-renderer.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@170121 268f45cc-cd09-0410-ab3c-d52691b4dbfc
LayoutTests/ChangeLog
LayoutTests/fast/css/getComputedStyle/empty-update-without-renderer-expected.txt [new file with mode: 0644]
LayoutTests/fast/css/getComputedStyle/empty-update-without-renderer.html [new file with mode: 0644]
LayoutTests/fast/css/getComputedStyle/first-child-update-without-renderer-expected.txt [new file with mode: 0644]
LayoutTests/fast/css/getComputedStyle/first-child-update-without-renderer.html [new file with mode: 0644]
LayoutTests/fast/css/getComputedStyle/last-child-update-without-renderer-expected.txt [new file with mode: 0644]
LayoutTests/fast/css/getComputedStyle/last-child-update-without-renderer.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/dom/Element.cpp