Don't clear StyleAffectedByEmpty before recalc.

ElementRareData::resetStyleState() cleared the StyleAffectedByEmpty flag
before recalculating style for an Element. However, this flag can be set by
style recalc for any of the sibling subtree elements in the presence of
adjacent combinators. If you have a LocalStyleChange for the element that
may become empty/non-empty, the flag can not be cleared since it may never
be set again unless the siblings affected by the :empty state are
recalculated.

R=esprehn@chromium.org
BUG=412950

Review URL: https://codereview.chromium.org/558333002

git-svn-id: svn://svn.chromium.org/blink/trunk@181799 bbb929c8-8fbe-4397-9dbb-9b2b20218538
diff --git a/third_party/WebKit/LayoutTests/fast/css/pseudo-empty-adjacent-dynamic-expected.txt b/third_party/WebKit/LayoutTests/fast/css/pseudo-empty-adjacent-dynamic-expected.txt
new file mode 100644
index 0000000..29d66dce
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/css/pseudo-empty-adjacent-dynamic-expected.txt
@@ -0,0 +1,11 @@
+Check that the sibling of an element that becomes :empty is properly recalculated
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS getComputedStyle(sibling, '').backgroundColor is transparent
+PASS getComputedStyle(sibling, '').backgroundColor is green
+PASS successfullyParsed is true
+
+TEST COMPLETE
+This text should be green
diff --git a/third_party/WebKit/LayoutTests/fast/css/pseudo-empty-adjacent-dynamic.html b/third_party/WebKit/LayoutTests/fast/css/pseudo-empty-adjacent-dynamic.html
new file mode 100644
index 0000000..8fdbd40
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/css/pseudo-empty-adjacent-dynamic.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<script src="../../resources/js-test.js"></script>
+<style>
+:empty + div { background-color: green; }
+</style>
+<div id="empty">To be removed</div>
+<div id="sibling">This text should be green</div>
+<script>
+description("Check that the sibling of an element that becomes :empty is properly recalculated");
+
+var transparent = "rgba(0, 0, 0, 0)";
+var green = "rgb(0, 128, 0)";
+
+empty.offsetTop; // force recalc
+empty.style.color = "red"; // force LocalStyleChange on #empty
+empty.offsetTop; // force recalc
+
+shouldBe("getComputedStyle(sibling, '').backgroundColor", "transparent");
+
+empty.removeChild(empty.firstChild);
+empty.offsetTop; // force recalc
+
+shouldBe("getComputedStyle(sibling, '').backgroundColor", "green");
+</script>
diff --git a/third_party/WebKit/LayoutTests/fast/css/pseudo-not-empty-adjacent-dynamic-expected.txt b/third_party/WebKit/LayoutTests/fast/css/pseudo-not-empty-adjacent-dynamic-expected.txt
new file mode 100644
index 0000000..049af6a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/css/pseudo-not-empty-adjacent-dynamic-expected.txt
@@ -0,0 +1,11 @@
+Check that the sibling of an element that becomes :not(:empty) is properly recalculated
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS getComputedStyle(sibling, '').backgroundColor is transparent
+PASS getComputedStyle(sibling, '').backgroundColor is green
+PASS successfullyParsed is true
+
+TEST COMPLETE
+This text should be green
diff --git a/third_party/WebKit/LayoutTests/fast/css/pseudo-not-empty-adjacent-dynamic.html b/third_party/WebKit/LayoutTests/fast/css/pseudo-not-empty-adjacent-dynamic.html
new file mode 100644
index 0000000..b667115
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/css/pseudo-not-empty-adjacent-dynamic.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<script src="../../resources/js-test.js"></script>
+<style>
+#empty:not(:empty) + div { background-color: green; }
+</style>
+<div id="empty"></div>
+<div id="sibling">This text should be green</div>
+<script>
+description("Check that the sibling of an element that becomes :not(:empty) is properly recalculated");
+
+var transparent = "rgba(0, 0, 0, 0)";
+var green = "rgb(0, 128, 0)";
+
+empty.offsetTop; // force recalc
+empty.style.color = "red"; // force LocalStyleChange on #empty
+empty.offsetTop; // force recalc
+
+shouldBe("getComputedStyle(sibling, '').backgroundColor", "transparent");
+
+empty.appendChild(document.createElement("div"));
+empty.offsetTop; // force recalc
+
+shouldBe("getComputedStyle(sibling, '').backgroundColor", "green");
+</script>
diff --git a/third_party/WebKit/Source/core/dom/Element.cpp b/third_party/WebKit/Source/core/dom/Element.cpp
index 1f2fed6..b0623cd 100644
--- a/third_party/WebKit/Source/core/dom/Element.cpp
+++ b/third_party/WebKit/Source/core/dom/Element.cpp
@@ -1327,9 +1327,6 @@
     if (hasRareData() && styleChangeType() == NeedsReattachStyleChange) {
         ElementRareData* data = elementRareData();
         data->clearComputedStyle();
-        // Only clear the style state if we're not going to reuse the style from recalcStyle.
-        if (!context.resolvedStyle)
-            data->resetStyleState();
     }
 
     RenderTreeBuilder(this, context.resolvedStyle).createRendererForElementIfNeeded();
@@ -1368,11 +1365,9 @@
         ElementRareData* data = elementRareData();
         data->clearPseudoElements();
 
-        // attach() will perform the below steps for us when inside recalcStyle.
-        if (!document().inStyleRecalc()) {
-            data->resetStyleState();
+        // attach() will clear the computed style for us when inside recalcStyle.
+        if (!document().inStyleRecalc())
             data->clearComputedStyle();
-        }
 
         if (ActiveAnimations* activeAnimations = data->activeAnimations()) {
             if (context.performingReattach) {
@@ -1481,7 +1476,6 @@
     if (change >= Inherit || needsStyleRecalc()) {
         if (hasRareData()) {
             ElementRareData* data = elementRareData();
-            data->resetStyleState();
             data->clearComputedStyle();
 
             if (change >= Inherit) {
diff --git a/third_party/WebKit/Source/core/dom/ElementRareData.h b/third_party/WebKit/Source/core/dom/ElementRareData.h
index 36088bc..f1d57ba5 100644
--- a/third_party/WebKit/Source/core/dom/ElementRareData.h
+++ b/third_party/WebKit/Source/core/dom/ElementRareData.h
@@ -52,8 +52,6 @@
     void setPseudoElement(PseudoId, PassRefPtrWillBeRawPtr<PseudoElement>);
     PseudoElement* pseudoElement(PseudoId) const;
 
-    void resetStyleState();
-
     short tabIndex() const { return m_tabindex; }
 
     void setTabIndexExplicitly(short index)
@@ -227,11 +225,6 @@
     }
 }
 
-inline void ElementRareData::resetStyleState()
-{
-    clearElementFlag(StyleAffectedByEmpty);
-}
-
 } // namespace
 
 #endif // ElementRareData_h