Merge from Chromium at DEPS revision r220549

This commit was generated by merge_to_master.py.

Change-Id: I0d3288f5db2b121c1681ea8d4a70c964cbed1fbd
diff --git a/Source/core/dom/Element.cpp b/Source/core/dom/Element.cpp
index 9577774..ce5e91a 100644
--- a/Source/core/dom/Element.cpp
+++ b/Source/core/dom/Element.cpp
@@ -35,6 +35,7 @@
 #include "bindings/v8/ExceptionState.h"
 #include "core/accessibility/AXObjectCache.h"
 #include "core/animation/DocumentTimeline.h"
+#include "core/animation/css/CSSAnimations.h"
 #include "core/css/CSSParser.h"
 #include "core/css/CSSStyleSheet.h"
 #include "core/css/CSSValuePool.h"
@@ -1449,64 +1450,75 @@
     if (hasCustomStyleCallbacks())
         willRecalcStyle(change);
 
-    // Ref currentStyle in case it would otherwise be deleted when setting the new style in the renderer.
-    RefPtr<RenderStyle> currentStyle = renderStyle();
-    bool hasParentStyle = static_cast<bool>(parentRenderStyle());
-    bool hasDirectAdjacentRules = childrenAffectedByDirectAdjacentRules();
-    bool hasIndirectAdjacentRules = childrenAffectedByForwardPositionalRules();
-
     if (hasRareData() && (change > NoChange || needsStyleRecalc())) {
         ElementRareData* data = elementRareData();
         data->resetStyleState();
         data->clearComputedStyle();
     }
 
-    if (hasParentStyle && (change >= Inherit || needsStyleRecalc())) {
-        StyleChange localChange = Detach;
-        RefPtr<RenderStyle> newStyle;
-        if (currentStyle) {
-            newStyle = styleForRenderer();
-            localChange = Node::diff(currentStyle.get(), newStyle.get(), document());
-        } else if (attached() && isActiveInsertionPoint(this)) {
-            // Active InsertionPoints will never have renderers so there's no reason to
-            // reattach them repeatedly once they're already attached.
-            localChange = change;
-        }
-        if (localChange == Detach) {
-            AttachContext reattachContext;
-            reattachContext.resolvedStyle = newStyle.get();
-            reattach(reattachContext);
+    // Active InsertionPoints have no renderers so they never need to go through a recalc.
+    if ((change >= Inherit || needsStyleRecalc()) && parentRenderStyle() && !isActiveInsertionPoint(this))
+        change = recalcOwnStyle(change);
 
-            if (hasCustomStyleCallbacks())
-                didRecalcStyle(change);
-            return true;
-        }
+    // If we reattached we don't need to recalc the style of our descendants anymore.
+    if (change < Reattach)
+        recalcChildStyle(change);
 
-        InspectorInstrumentation::didRecalculateStyleForElement(this);
+    clearNeedsStyleRecalc();
+    clearChildNeedsStyleRecalc();
 
-        if (RenderObject* renderer = this->renderer()) {
-            if (localChange != NoChange || pseudoStyleCacheIsInvalid(currentStyle.get(), newStyle.get()) || (change == Force && renderer->requiresForcedStyleRecalcPropagation()) || shouldNotifyRendererWithIdenticalStyles()) {
-                renderer->setAnimatableStyle(newStyle.get());
-            } else if (needsStyleRecalc()) {
-                // Although no change occurred, we use the new style so that the cousin style sharing code won't get
-                // fooled into believing this style is the same.
-                renderer->setStyleInternal(newStyle.get());
-            }
-        }
+    if (hasCustomStyleCallbacks())
+        didRecalcStyle(change);
 
-        // If "rem" units are used anywhere in the document, and if the document element's font size changes, then go ahead and force font updating
-        // all the way down the tree. This is simpler than having to maintain a cache of objects (and such font size changes should be rare anyway).
-        if (document()->styleSheetCollection()->usesRemUnits() && document()->documentElement() == this && localChange != NoChange && currentStyle && newStyle && currentStyle->fontSize() != newStyle->fontSize()) {
-            // Cached RenderStyles may depend on the re units.
-            document()->styleResolver()->invalidateMatchedPropertiesCache();
-            change = Force;
-        }
+    return change == Reattach;
+}
 
-        if (styleChangeType() >= SubtreeStyleChange)
-            change = Force;
-        else if (change != Force)
-            change = localChange;
+Node::StyleChange Element::recalcOwnStyle(StyleChange change)
+{
+    ASSERT(document()->inStyleRecalc());
+
+    CSSAnimationUpdateScope cssAnimationUpdateScope(this);
+    RefPtr<RenderStyle> oldStyle = renderStyle();
+    RefPtr<RenderStyle> newStyle = styleForRenderer();
+    StyleChange localChange = oldStyle ? Node::diff(oldStyle.get(), newStyle.get(), document()) : Reattach;
+
+    if (localChange == Reattach) {
+        AttachContext reattachContext;
+        reattachContext.resolvedStyle = newStyle.get();
+        reattach(reattachContext);
+        return Reattach;
     }
+
+    InspectorInstrumentation::didRecalculateStyleForElement(this);
+
+    if (RenderObject* renderer = this->renderer()) {
+        if (localChange != NoChange || pseudoStyleCacheIsInvalid(oldStyle.get(), newStyle.get()) || (change == Force && renderer->requiresForcedStyleRecalcPropagation()) || shouldNotifyRendererWithIdenticalStyles()) {
+            renderer->setAnimatableStyle(newStyle.get());
+        } else if (needsStyleRecalc()) {
+            // Although no change occurred, we use the new style so that the cousin style sharing code won't get
+            // fooled into believing this style is the same.
+            renderer->setStyleInternal(newStyle.get());
+        }
+    }
+
+    // If "rem" units are used anywhere in the document, and if the document element's font size changes, then go ahead and force font updating
+    // all the way down the tree. This is simpler than having to maintain a cache of objects (and such font size changes should be rare anyway).
+    if (document()->styleSheetCollections()->usesRemUnits() && document()->documentElement() == this && oldStyle && newStyle && oldStyle->fontSize() != newStyle->fontSize()) {
+        // Cached RenderStyles may depend on the re units.
+        document()->styleResolver()->invalidateMatchedPropertiesCache();
+        return Force;
+    }
+
+    if (styleChangeType() >= SubtreeStyleChange)
+        return Force;
+
+    return max(localChange, change);
+}
+
+void Element::recalcChildStyle(StyleChange change)
+{
+    ASSERT(document()->inStyleRecalc());
+
     StyleResolverParentPusher parentPusher(this);
 
     for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) {
@@ -1522,6 +1534,8 @@
     // FIXME: This check is good enough for :hover + foo, but it is not good enough for :hover + foo + bar.
     // For now we will just worry about the common case, since it's a lot trickier to get the second case right
     // without doing way too much re-resolution.
+    bool hasDirectAdjacentRules = childrenAffectedByDirectAdjacentRules();
+    bool hasIndirectAdjacentRules = childrenAffectedByForwardPositionalRules();
     bool forceCheckOfNextElementSibling = false;
     bool forceCheckOfAnyElementSibling = false;
     bool forceReattachOfAnyWhitespaceSibling = false;
@@ -1560,13 +1574,6 @@
         updatePseudoElement(AFTER, change);
         updatePseudoElement(BACKDROP, change);
     }
-
-    clearNeedsStyleRecalc();
-    clearChildNeedsStyleRecalc();
-
-    if (hasCustomStyleCallbacks())
-        didRecalcStyle(change);
-    return false;
 }
 
 ElementShadow* Element::shadow() const
@@ -1636,11 +1643,6 @@
     return shadowRoot;
 }
 
-bool Element::supportsShadowElementForUserAgentShadow() const
-{
-    return true;
-}
-
 bool Element::childTypeAllowed(NodeType type) const
 {
     switch (type) {
@@ -2463,9 +2465,6 @@
 
 void Element::createPseudoElementIfNeeded(PseudoId pseudoId)
 {
-    if ((pseudoId == BEFORE || pseudoId == AFTER) && !document()->styleSheetCollection()->usesBeforeAfterRules())
-        return;
-
     if (pseudoId == BACKDROP && !isInTopLayer())
         return;