Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / css / resolver / StyleResolver.cpp
index 7daa31e..28550e6 100644 (file)
 #include "config.h"
 #include "core/css/resolver/StyleResolver.h"
 
-#include "CSSPropertyNames.h"
-#include "HTMLNames.h"
-#include "RuntimeEnabledFeatures.h"
-#include "StylePropertyShorthand.h"
+#include "core/CSSPropertyNames.h"
+#include "core/HTMLNames.h"
+#include "core/MediaTypeNames.h"
+#include "core/StylePropertyShorthand.h"
 #include "core/animation/ActiveAnimations.h"
-#include "core/animation/AnimatableLength.h"
-#include "core/animation/AnimatableValue.h"
 #include "core/animation/Animation.h"
-#include "core/animation/DocumentTimeline.h"
+#include "core/animation/AnimationTimeline.h"
+#include "core/animation/StyleInterpolation.h"
+#include "core/animation/animatable/AnimatableValue.h"
 #include "core/animation/css/CSSAnimatableValueFactory.h"
 #include "core/animation/css/CSSAnimations.h"
 #include "core/css/CSSCalculationValue.h"
 #include "core/css/CSSFontSelector.h"
 #include "core/css/CSSKeyframeRule.h"
 #include "core/css/CSSKeyframesRule.h"
-#include "core/css/parser/BisonCSSParser.h"
 #include "core/css/CSSReflectValue.h"
 #include "core/css/CSSRuleList.h"
 #include "core/css/CSSSelector.h"
 #include "core/css/CSSStyleRule.h"
 #include "core/css/CSSValueList.h"
+#include "core/css/CSSValuePool.h"
 #include "core/css/ElementRuleCollector.h"
 #include "core/css/FontFace.h"
 #include "core/css/MediaQueryEvaluator.h"
@@ -63,6 +63,8 @@
 #include "core/css/resolver/MediaQueryResult.h"
 #include "core/css/resolver/SharedStyleFinder.h"
 #include "core/css/resolver/StyleAdjuster.h"
+#include "core/css/resolver/StyleResolverParentScope.h"
+#include "core/css/resolver/StyleResolverState.h"
 #include "core/css/resolver/StyleResolverStats.h"
 #include "core/css/resolver/ViewportStyleResolver.h"
 #include "core/dom/CSSSelectorWatch.h"
 #include "core/dom/Text.h"
 #include "core/dom/shadow/ElementShadow.h"
 #include "core/dom/shadow/ShadowRoot.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLIFrameElement.h"
 #include "core/inspector/InspectorInstrumentation.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
 #include "core/rendering/RenderView.h"
 #include "core/rendering/style/KeyframeList.h"
 #include "core/svg/SVGDocumentExtensions.h"
 #include "core/svg/SVGElement.h"
 #include "core/svg/SVGFontFaceElement.h"
+#include "platform/RuntimeEnabledFeatures.h"
 #include "wtf/StdLibExtras.h"
 
-using namespace std;
-
 namespace {
 
-using namespace WebCore;
+using namespace blink;
 
 void setAnimationUpdateIfNeeded(StyleResolverState& state, Element& element)
 {
     // If any changes to CSS Animations were detected, stash the update away for application after the
     // render object is updated if we're in the appropriate scope.
     if (state.animationUpdate())
-        element.ensureActiveAnimations()->cssAnimations().setPendingUpdate(state.takeAnimationUpdate());
+        element.ensureActiveAnimations().cssAnimations().setPendingUpdate(state.takeAnimationUpdate());
 }
 
 } // namespace
 
-namespace WebCore {
+namespace blink {
 
 using namespace HTMLNames;
 
@@ -106,7 +107,7 @@ RenderStyle* StyleResolver::s_styleNotYetAvailable;
 
 static StylePropertySet* leftToRightDeclaration()
 {
-    DEFINE_STATIC_REF(MutableStylePropertySet, leftToRightDecl, (MutableStylePropertySet::create()));
+    DEFINE_STATIC_REF_WILL_BE_PERSISTENT(MutableStylePropertySet, leftToRightDecl, (MutableStylePropertySet::create()));
     if (leftToRightDecl->isEmpty())
         leftToRightDecl->setProperty(CSSPropertyDirection, CSSValueLtr);
     return leftToRightDecl;
@@ -114,7 +115,7 @@ static StylePropertySet* leftToRightDeclaration()
 
 static StylePropertySet* rightToLeftDeclaration()
 {
-    DEFINE_STATIC_REF(MutableStylePropertySet, rightToLeftDecl, (MutableStylePropertySet::create()));
+    DEFINE_STATIC_REF_WILL_BE_PERSISTENT(MutableStylePropertySet, rightToLeftDecl, (MutableStylePropertySet::create()));
     if (rightToLeftDecl->isEmpty())
         rightToLeftDecl->setProperty(CSSPropertyDirection, CSSValueRtl);
     return rightToLeftDecl;
@@ -122,7 +123,7 @@ static StylePropertySet* rightToLeftDeclaration()
 
 static void addFontFaceRule(Document* document, CSSFontSelector* cssFontSelector, const StyleRuleFontFace* fontFaceRule)
 {
-    RefPtr<FontFace> fontFace = FontFace::create(document, fontFaceRule);
+    RefPtrWillBeRawPtr<FontFace> fontFace = FontFace::create(document, fontFaceRule);
     if (fontFace)
         cssFontSelector->fontFaceCache()->add(cssFontSelector, fontFaceRule, fontFace);
 }
@@ -131,44 +132,33 @@ StyleResolver::StyleResolver(Document& document)
     : m_document(document)
     , m_viewportStyleResolver(ViewportStyleResolver::create(&document))
     , m_needCollectFeatures(false)
+    , m_printMediaType(false)
     , m_styleResourceLoader(document.fetcher())
+    , m_styleSharingDepth(0)
     , m_styleResolverStatsSequence(0)
     , m_accessCount(0)
 {
-    // Construct document root element default style. This is needed
-    // to evaluate media queries that contain relative constraints, like "screen and (max-width: 10em)"
-    // This is here instead of constructor because when constructor is run,
-    // Document doesn't have documentElement.
-    // NOTE: This assumes that element that gets passed to the styleForElement call
-    // is always from the document that owns the StyleResolver.
     FrameView* view = document.view();
-    if (view)
-        m_medium = adoptPtr(new MediaQueryEvaluator(view->mediaType()));
-    else
+    if (view) {
+        m_medium = adoptPtr(new MediaQueryEvaluator(&view->frame()));
+        m_printMediaType = equalIgnoringCase(view->mediaType(), MediaTypeNames::print);
+    } else {
         m_medium = adoptPtr(new MediaQueryEvaluator("all"));
-
-    Element* root = document.documentElement();
-    if (root)
-        m_rootDefaultStyle = styleForElement(root, 0, DisallowStyleSharing, MatchOnlyUserAgentRules);
-
-    if (m_rootDefaultStyle && view)
-        m_medium = adoptPtr(new MediaQueryEvaluator(view->mediaType(), &view->frame(), m_rootDefaultStyle.get()));
-
-    m_styleTree.clear();
+    }
 
     initWatchedSelectorRules(CSSSelectorWatch::from(document).watchedCallbackSelectors());
 
 #if ENABLE(SVG_FONTS)
     if (document.svgExtensions()) {
-        const HashSet<SVGFontFaceElement*>& svgFontFaceElements = document.svgExtensions()->svgFontFaceElements();
-        HashSet<SVGFontFaceElement*>::const_iterator end = svgFontFaceElements.end();
-        for (HashSet<SVGFontFaceElement*>::const_iterator it = svgFontFaceElements.begin(); it != end; ++it)
+        const WillBeHeapHashSet<RawPtrWillBeMember<SVGFontFaceElement> >& svgFontFaceElements = document.svgExtensions()->svgFontFaceElements();
+        WillBeHeapHashSet<RawPtrWillBeMember<SVGFontFaceElement> >::const_iterator end = svgFontFaceElements.end();
+        for (WillBeHeapHashSet<RawPtrWillBeMember<SVGFontFaceElement> >::const_iterator it = svgFontFaceElements.begin(); it != end; ++it)
             addFontFaceRule(&document, document.styleEngine()->fontSelector(), (*it)->fontFaceRule());
     }
 #endif
 }
 
-void StyleResolver::initWatchedSelectorRules(const Vector<RefPtr<StyleRule> >& watchedSelectors)
+void StyleResolver::initWatchedSelectorRules(const WillBeHeapVector<RefPtrWillBeMember<StyleRule> >& watchedSelectors)
 {
     if (!watchedSelectors.size())
         return;
@@ -177,14 +167,14 @@ void StyleResolver::initWatchedSelectorRules(const Vector<RefPtr<StyleRule> >& w
         m_watchedSelectorsRules->addStyleRule(watchedSelectors[i].get(), RuleHasNoSpecialState);
 }
 
-void StyleResolver::lazyAppendAuthorStyleSheets(unsigned firstNew, const Vector<RefPtr<CSSStyleSheet> >& styleSheets)
+void StyleResolver::lazyAppendAuthorStyleSheets(unsigned firstNew, const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& styleSheets)
 {
     unsigned size = styleSheets.size();
     for (unsigned i = firstNew; i < size; ++i)
         m_pendingStyleSheets.add(styleSheets[i].get());
 }
 
-void StyleResolver::removePendingAuthorStyleSheets(const Vector<RefPtr<CSSStyleSheet> >& styleSheets)
+void StyleResolver::removePendingAuthorStyleSheets(const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& styleSheets)
 {
     for (unsigned i = 0; i < styleSheets.size(); ++i)
         m_pendingStyleSheets.remove(styleSheets[i].get());
@@ -197,31 +187,30 @@ void StyleResolver::appendCSSStyleSheet(CSSStyleSheet* cssSheet)
     if (cssSheet->mediaQueries() && !m_medium->eval(cssSheet->mediaQueries(), &m_viewportDependentMediaQueryResults))
         return;
 
-    ContainerNode* scopingNode = ScopedStyleResolver::scopingNodeFor(document(), cssSheet);
-    if (!scopingNode)
+    TreeScope* treeScope = ScopedStyleResolver::treeScopeFor(document(), cssSheet);
+    if (!treeScope)
         return;
 
-    ScopedStyleResolver* resolver = ensureScopedStyleResolver(scopingNode);
-    ASSERT(resolver);
-    resolver->addRulesFromSheet(cssSheet, *m_medium, this);
+    ScopedStyleResolver& resolver = treeScope->ensureScopedStyleResolver();
+    document().styleEngine()->addScopedStyleResolver(&resolver);
+    resolver.addRulesFromSheet(cssSheet, *m_medium, this);
 }
 
 void StyleResolver::appendPendingAuthorStyleSheets()
 {
-    setBuildScopedStyleTreeInDocumentOrder(false);
-    for (ListHashSet<CSSStyleSheet*, 16>::iterator it = m_pendingStyleSheets.begin(); it != m_pendingStyleSheets.end(); ++it)
+    for (WillBeHeapListHashSet<RawPtrWillBeMember<CSSStyleSheet>, 16>::iterator it = m_pendingStyleSheets.begin(); it != m_pendingStyleSheets.end(); ++it)
         appendCSSStyleSheet(*it);
 
     m_pendingStyleSheets.clear();
     finishAppendAuthorStyleSheets();
 }
 
-void StyleResolver::appendAuthorStyleSheets(unsigned firstNew, const Vector<RefPtr<CSSStyleSheet> >& styleSheets)
+void StyleResolver::appendAuthorStyleSheets(const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& styleSheets)
 {
     // This handles sheets added to the end of the stylesheet list only. In other cases the style resolver
     // needs to be reconstructed. To handle insertions too the rule order numbers would need to be updated.
     unsigned size = styleSheets.size();
-    for (unsigned i = firstNew; i < size; ++i)
+    for (unsigned i = 0; i < size; ++i)
         appendCSSStyleSheet(styleSheets[i].get());
 }
 
@@ -229,8 +218,8 @@ void StyleResolver::finishAppendAuthorStyleSheets()
 {
     collectFeatures();
 
-    if (document().renderer() && document().renderer()->style())
-        document().renderer()->style()->font().update(document().styleEngine()->fontSelector());
+    if (document().renderView() && document().renderView()->style())
+        document().renderView()->style()->font().update(document().styleEngine()->fontSelector());
 
     collectViewportRules();
 
@@ -246,58 +235,50 @@ void StyleResolver::resetRuleFeatures()
     m_needCollectFeatures = true;
 }
 
-void StyleResolver::addTreeBoundaryCrossingRules(const Vector<MinimalRuleData>& rules, ContainerNode* scope)
+void StyleResolver::processScopedRules(const RuleSet& authorRules, CSSStyleSheet* parentStyleSheet, unsigned parentIndex, ContainerNode& scope)
 {
-    for (unsigned i = 0; i < rules.size(); ++i) {
-        const MinimalRuleData& info = rules[i];
-        m_treeBoundaryCrossingRules.addRule(info.m_rule, info.m_selectorIndex, scope, info.m_flags);
-    }
-}
-
-void StyleResolver::processScopedRules(const RuleSet& authorRules, const KURL& sheetBaseURL, ContainerNode* scope)
-{
-    const Vector<StyleRuleKeyframes*> keyframesRules = authorRules.keyframesRules();
+    const WillBeHeapVector<RawPtrWillBeMember<StyleRuleKeyframes> > keyframesRules = authorRules.keyframesRules();
+    ScopedStyleResolver* resolver = &scope.treeScope().ensureScopedStyleResolver();
+    document().styleEngine()->addScopedStyleResolver(resolver);
     for (unsigned i = 0; i < keyframesRules.size(); ++i)
-        ensureScopedStyleResolver(scope)->addKeyframeStyle(keyframesRules[i]);
+        resolver->addKeyframeStyle(keyframesRules[i]);
 
-    addTreeBoundaryCrossingRules(authorRules.treeBoundaryCrossingRules(), scope);
+    m_treeBoundaryCrossingRules.addTreeBoundaryCrossingRules(authorRules, parentStyleSheet, parentIndex, scope);
 
     // FIXME(BUG 72461): We don't add @font-face rules of scoped style sheets for the moment.
-    if (!scope || scope->isDocumentNode()) {
-        const Vector<StyleRuleFontFace*> fontFaceRules = authorRules.fontFaceRules();
+    if (scope.isDocumentNode()) {
+        const WillBeHeapVector<RawPtrWillBeMember<StyleRuleFontFace> > fontFaceRules = authorRules.fontFaceRules();
         for (unsigned i = 0; i < fontFaceRules.size(); ++i)
-            addFontFaceRule(&m_document, document().styleEngine()->fontSelector(), fontFaceRules[i]);
+            addFontFaceRule(m_document, document().styleEngine()->fontSelector(), fontFaceRules[i]);
         if (fontFaceRules.size())
             invalidateMatchedPropertiesCache();
-    } else {
-        addTreeBoundaryCrossingRules(authorRules.shadowDistributedRules(), scope);
     }
 }
 
-void StyleResolver::resetAuthorStyle(const ContainerNode* scopingNode)
+void StyleResolver::resetAuthorStyle(TreeScope& treeScope)
 {
-    // FIXME: When chanking scoped attribute, scopingNode's hasScopedHTMLStyleChild has been already modified.
-    // So we cannot use hasScopedHTMLStyleChild flag here.
-    ScopedStyleResolver* resolver = scopingNode ? m_styleTree.lookupScopedStyleResolverFor(scopingNode) : m_styleTree.scopedStyleResolverForDocument();
+    ScopedStyleResolver* resolver = treeScope.scopedStyleResolver();
     if (!resolver)
         return;
 
-    treeBoundaryCrossingRules().reset(scopingNode);
+    m_treeBoundaryCrossingRules.reset(&treeScope.rootNode());
 
     resolver->resetAuthorStyle();
     resetRuleFeatures();
-    if (!scopingNode)
+    if (treeScope.rootNode().isDocumentNode())
         return;
 
-    m_styleTree.remove(scopingNode);
+    // resolver is going to be freed below.
+    document().styleEngine()->removeScopedStyleResolver(resolver);
+    treeScope.clearScopedStyleResolver();
 }
 
-static PassOwnPtr<RuleSet> makeRuleSet(const Vector<RuleFeature>& rules)
+static PassOwnPtrWillBeRawPtr<RuleSet> makeRuleSet(const WillBeHeapVector<RuleFeature>& rules)
 {
     size_t size = rules.size();
     if (!size)
         return nullptr;
-    OwnPtr<RuleSet> ruleSet = RuleSet::create();
+    OwnPtrWillBeRawPtr<RuleSet> ruleSet = RuleSet::create();
     for (size_t i = 0; i < size; ++i)
         ruleSet->addRule(rules[i].rule, rules[i].selectorIndex, rules[i].hasDocumentSecurityOrigin ? RuleHasDocumentSecurityOrigin : RuleHasNoSpecialState);
     return ruleSet.release();
@@ -316,12 +297,15 @@ void StyleResolver::collectFeatures()
     if (document().isViewSource())
         m_features.add(defaultStyleSheets.defaultViewSourceStyle()->features());
 
+    if (document().isTransitionDocument())
+        m_features.add(defaultStyleSheets.defaultTransitionStyle()->features());
+
     if (m_watchedSelectorsRules)
         m_features.add(m_watchedSelectorsRules->features());
 
     m_treeBoundaryCrossingRules.collectFeaturesTo(m_features);
 
-    m_styleTree.collectFeaturesTo(m_features);
+    document().styleEngine()->collectScopedStyleFeaturesTo(m_features);
 
     m_siblingRuleSet = makeRuleSet(m_features.siblingRules);
     m_uncommonAttributeRuleSet = makeRuleSet(m_features.uncommonAttributeRules);
@@ -340,20 +324,28 @@ void StyleResolver::addToStyleSharingList(Element& element)
     if (!document().inStyleRecalc())
         return;
     INCREMENT_STYLE_STATS_COUNTER(*this, sharedStyleCandidates);
-    if (m_styleSharingList.size() >= styleSharingListSize)
-        m_styleSharingList.remove(--m_styleSharingList.end());
-    m_styleSharingList.prepend(&element);
+    StyleSharingList& list = styleSharingList();
+    if (list.size() >= styleSharingListSize)
+        list.removeLast();
+    list.prepend(&element);
 }
 
-void StyleResolver::clearStyleSharingList()
+StyleSharingList& StyleResolver::styleSharingList()
 {
-    m_styleSharingList.clear();
+    m_styleSharingLists.resize(styleSharingMaxDepth);
+
+    // We never put things at depth 0 into the list since that's only the <html> element
+    // and it has no siblings or cousins to share with.
+    unsigned depth = std::max(std::min(m_styleSharingDepth, styleSharingMaxDepth), 1u) - 1u;
+
+    if (!m_styleSharingLists[depth])
+        m_styleSharingLists[depth] = adoptPtrWillBeNoop(new StyleSharingList);
+    return *m_styleSharingLists[depth];
 }
 
-void StyleResolver::fontsNeedUpdate(CSSFontSelector* fontSelector)
+void StyleResolver::clearStyleSharingList()
 {
-    invalidateMatchedPropertiesCache();
-    m_document.setNeedsStyleRecalc(SubtreeStyleChange);
+    m_styleSharingLists.resize(0);
 }
 
 void StyleResolver::pushParentElement(Element& parent)
@@ -368,9 +360,6 @@ void StyleResolver::pushParentElement(Element& parent)
         m_selectorFilter.setupParentStack(parent);
     else
         m_selectorFilter.pushParent(parent);
-
-    // Note: We mustn't skip ShadowRoot nodes for the scope stack.
-    m_styleTree.pushStyleCache(parent, parent.parentOrShadowHostNode());
 }
 
 void StyleResolver::popParentElement(Element& parent)
@@ -379,91 +368,30 @@ void StyleResolver::popParentElement(Element& parent)
     // Pause maintaining the stack in this case.
     if (m_selectorFilter.parentStackIsConsistent(&parent))
         m_selectorFilter.popParent();
-
-    m_styleTree.popStyleCache(parent);
-}
-
-void StyleResolver::pushParentShadowRoot(const ShadowRoot& shadowRoot)
-{
-    ASSERT(shadowRoot.host());
-    m_styleTree.pushStyleCache(shadowRoot, shadowRoot.host());
-}
-
-void StyleResolver::popParentShadowRoot(const ShadowRoot& shadowRoot)
-{
-    ASSERT(shadowRoot.host());
-    m_styleTree.popStyleCache(shadowRoot);
 }
 
 StyleResolver::~StyleResolver()
 {
-    m_viewportStyleResolver->clearDocument();
-}
-
-inline void StyleResolver::collectTreeBoundaryCrossingRules(Element* element, ElementRuleCollector& collector, bool includeEmptyRules)
-{
-    if (m_treeBoundaryCrossingRules.isEmpty())
-        return;
-
-    RuleRange ruleRange = collector.matchedResult().ranges.authorRuleRange();
-
-    // When comparing rules declared in outer treescopes, outer's rules win.
-    CascadeOrder outerCascadeOrder = m_treeBoundaryCrossingRules.size() + m_treeBoundaryCrossingRules.size();
-    // When comparing rules declared in inner treescopes, inner's rules win.
-    CascadeOrder innerCascadeOrder = m_treeBoundaryCrossingRules.size();
-
-    for (DocumentOrderedList::iterator it = m_treeBoundaryCrossingRules.begin(); it != m_treeBoundaryCrossingRules.end(); ++it) {
-        const ContainerNode* scopingNode = toContainerNode(*it);
-
-        if (ShadowRoot* shadowRoot = scopingNode->containingShadowRoot()) {
-            if (!shadowRoot->isActiveForStyling())
-                continue;
-        }
-
-        RuleSet* ruleSet = m_treeBoundaryCrossingRules.ruleSetScopedBy(scopingNode);
-        unsigned boundaryBehavior = SelectorChecker::ScopeContainsLastMatchedElement;
-        bool isInnerTreeScope = element->treeScope().isInclusiveAncestorOf(scopingNode->treeScope());
-
-        // If a given scoping node is a shadow root and a given element is in a descendant tree of tree hosted by
-        // the scoping node's shadow host, we should use ScopeIsShadowHost.
-        if (scopingNode && scopingNode->isShadowRoot()) {
-            if (element->isInDescendantTreeOf(toShadowRoot(scopingNode)->host()))
-                boundaryBehavior |= SelectorChecker::ScopeIsShadowHost;
-            scopingNode = toShadowRoot(scopingNode)->host();
-        }
-
-        CascadeOrder cascadeOrder = isInnerTreeScope ? innerCascadeOrder : outerCascadeOrder;
-
-        collector.collectMatchingRules(MatchRequest(ruleSet, includeEmptyRules, scopingNode), ruleRange, static_cast<SelectorChecker::BehaviorAtBoundary>(boundaryBehavior), ignoreCascadeScope, cascadeOrder);
-        ++innerCascadeOrder;
-        --outerCascadeOrder;
-    }
-}
-
-static inline bool applyAuthorStylesOf(const Element* element)
-{
-    return element->treeScope().applyAuthorStyles() || (element->shadow() && element->shadow()->applyAuthorStyles());
 }
 
-void StyleResolver::matchAuthorRulesForShadowHost(Element* element, ElementRuleCollector& collector, bool includeEmptyRules, Vector<ScopedStyleResolver*, 8>& resolvers, Vector<ScopedStyleResolver*, 8>& resolversInShadowTree)
+void StyleResolver::matchAuthorRulesForShadowHost(Element* element, ElementRuleCollector& collector, bool includeEmptyRules, WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8>& resolvers, WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8>& resolversInShadowTree)
 {
     collector.clearMatchedRules();
     collector.matchedResult().ranges.lastAuthorRule = collector.matchedResult().matchedProperties.size() - 1;
 
     CascadeScope cascadeScope = 0;
     CascadeOrder cascadeOrder = 0;
-    bool applyAuthorStyles = applyAuthorStylesOf(element);
 
     for (int j = resolversInShadowTree.size() - 1; j >= 0; --j)
-        resolversInShadowTree.at(j)->collectMatchingAuthorRules(collector, includeEmptyRules, applyAuthorStyles, cascadeScope, cascadeOrder++);
+        resolversInShadowTree.at(j)->collectMatchingAuthorRules(collector, includeEmptyRules, cascadeScope, cascadeOrder++);
 
     if (resolvers.isEmpty() || resolvers.first()->treeScope() != element->treeScope())
         ++cascadeScope;
     cascadeOrder += resolvers.size();
     for (unsigned i = 0; i < resolvers.size(); ++i)
-        resolvers.at(i)->collectMatchingAuthorRules(collector, includeEmptyRules, applyAuthorStyles, cascadeScope++, --cascadeOrder);
+        resolvers.at(i)->collectMatchingAuthorRules(collector, includeEmptyRules, cascadeScope++, --cascadeOrder);
 
-    collectTreeBoundaryCrossingRules(element, collector, includeEmptyRules);
+    m_treeBoundaryCrossingRules.collectTreeBoundaryCrossingRules(element, collector, includeEmptyRules);
     collector.sortAndTransferMatchedRules();
 }
 
@@ -472,19 +400,18 @@ void StyleResolver::matchAuthorRules(Element* element, ElementRuleCollector& col
     collector.clearMatchedRules();
     collector.matchedResult().ranges.lastAuthorRule = collector.matchedResult().matchedProperties.size() - 1;
 
-    bool applyAuthorStyles = applyAuthorStylesOf(element);
-    if (m_styleTree.hasOnlyScopedResolverForDocument()) {
-        m_styleTree.scopedStyleResolverForDocument()->collectMatchingAuthorRules(collector, includeEmptyRules, applyAuthorStyles, ignoreCascadeScope);
-        collectTreeBoundaryCrossingRules(element, collector, includeEmptyRules);
+    if (document().styleEngine()->hasOnlyScopedResolverForDocument()) {
+        document().scopedStyleResolver()->collectMatchingAuthorRules(collector, includeEmptyRules, ignoreCascadeScope);
+        m_treeBoundaryCrossingRules.collectTreeBoundaryCrossingRules(element, collector, includeEmptyRules);
         collector.sortAndTransferMatchedRules();
         return;
     }
 
-    Vector<ScopedStyleResolver*, 8> resolvers;
-    m_styleTree.resolveScopedStyles(element, resolvers);
+    WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8> resolvers;
+    resolveScopedStyles(element, resolvers);
 
-    Vector<ScopedStyleResolver*, 8> resolversInShadowTree;
-    m_styleTree.collectScopedResolversForHostedShadowTrees(element, resolversInShadowTree);
+    WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8> resolversInShadowTree;
+    collectScopedResolversForHostedShadowTrees(element, resolversInShadowTree);
     if (!resolversInShadowTree.isEmpty()) {
         matchAuthorRulesForShadowHost(element, collector, includeEmptyRules, resolvers, resolversInShadowTree);
         return;
@@ -498,25 +425,10 @@ void StyleResolver::matchAuthorRules(Element* element, ElementRuleCollector& col
     for (unsigned i = 0; i < resolvers.size(); ++i, --cascadeOrder) {
         ScopedStyleResolver* resolver = resolvers.at(i);
         // FIXME: Need to clarify how to treat style scoped.
-        resolver->collectMatchingAuthorRules(collector, includeEmptyRules, applyAuthorStyles, cascadeScope++, resolver->treeScope() == element->treeScope() && resolver->scopingNode().isShadowRoot() ? 0 : cascadeOrder);
+        resolver->collectMatchingAuthorRules(collector, includeEmptyRules, cascadeScope++, resolver->treeScope() == element->treeScope() && resolver->treeScope().rootNode().isShadowRoot() ? 0 : cascadeOrder);
     }
 
-    collectTreeBoundaryCrossingRules(element, collector, includeEmptyRules);
-    collector.sortAndTransferMatchedRules();
-}
-
-void StyleResolver::matchWatchSelectorRules(ElementRuleCollector& collector)
-{
-    if (!m_watchedSelectorsRules)
-        return;
-
-    collector.clearMatchedRules();
-    collector.matchedResult().ranges.lastUserRule = collector.matchedResult().matchedProperties.size() - 1;
-
-    MatchRequest matchRequest(m_watchedSelectorsRules.get());
-    RuleRange ruleRange = collector.matchedResult().ranges.userRuleRange();
-    collector.collectMatchingRules(matchRequest, ruleRange);
-
+    m_treeBoundaryCrossingRules.collectTreeBoundaryCrossingRules(element, collector, includeEmptyRules);
     collector.sortAndTransferMatchedRules();
 }
 
@@ -525,8 +437,7 @@ void StyleResolver::matchUARules(ElementRuleCollector& collector)
     collector.setMatchingUARules(true);
 
     CSSDefaultStyleSheets& defaultStyleSheets = CSSDefaultStyleSheets::instance();
-    RuleSet* userAgentStyleSheet = m_medium->mediaTypeMatchSpecific("print")
-        ? defaultStyleSheets.defaultPrintStyle() : defaultStyleSheets.defaultStyle();
+    RuleSet* userAgentStyleSheet = m_printMediaType ? defaultStyleSheets.defaultPrintStyle() : defaultStyleSheets.defaultStyle();
     matchUARules(collector, userAgentStyleSheet);
 
     // In quirks mode, we match rules from the quirks user agent sheet.
@@ -537,9 +448,10 @@ void StyleResolver::matchUARules(ElementRuleCollector& collector)
     if (document().isViewSource())
         matchUARules(collector, defaultStyleSheets.defaultViewSourceStyle());
 
-    collector.setMatchingUARules(false);
+    if (document().isTransitionDocument())
+        matchUARules(collector, defaultStyleSheets.defaultTransitionStyle());
 
-    matchWatchSelectorRules(collector);
+    collector.setMatchingUARules(false);
 }
 
 void StyleResolver::matchUARules(ElementRuleCollector& collector, RuleSet* rules)
@@ -589,31 +501,21 @@ void StyleResolver::matchAllRules(StyleResolverState& state, ElementRuleCollecto
     }
 }
 
-PassRefPtr<RenderStyle> StyleResolver::styleForDocument(Document& document, CSSFontSelector* fontSelector)
+PassRefPtr<RenderStyle> StyleResolver::styleForDocument(Document& document)
 {
-    const Frame* frame = document.frame();
+    const LocalFrame* frame = document.frame();
 
     RefPtr<RenderStyle> documentStyle = RenderStyle::create();
     documentStyle->setDisplay(BLOCK);
     documentStyle->setRTLOrdering(document.visuallyOrdered() ? VisualOrder : LogicalOrder);
     documentStyle->setZoom(frame && !document.printing() ? frame->pageZoomFactor() : 1);
     documentStyle->setLocale(document.contentLanguage());
-
-    // This overrides any -webkit-user-modify inherited from the parent iframe.
+    documentStyle->setZIndex(0);
     documentStyle->setUserModify(document.inDesignMode() ? READ_WRITE : READ_ONLY);
 
     document.setupFontBuilder(documentStyle.get());
-    return documentStyle.release();
-}
 
-// FIXME: This is duplicated with StyleAdjuster.cpp
-// Perhaps this should move onto ElementResolveContext or even Element?
-static inline bool isAtShadowBoundary(const Element* element)
-{
-    if (!element)
-        return false;
-    ContainerNode* parentNode = element->parentNode();
-    return parentNode && parentNode->isShadowRoot();
+    return documentStyle.release();
 }
 
 static inline void resetDirectionAndWritingModeOnDocument(Document& document)
@@ -625,31 +527,47 @@ static inline void resetDirectionAndWritingModeOnDocument(Document& document)
 static void addContentAttrValuesToFeatures(const Vector<AtomicString>& contentAttrValues, RuleFeatureSet& features)
 {
     for (size_t i = 0; i < contentAttrValues.size(); ++i)
-        features.addAttributeInASelector(contentAttrValues[i]);
+        features.addContentAttr(contentAttrValues[i]);
+}
+
+void StyleResolver::adjustRenderStyle(StyleResolverState& state, Element* element)
+{
+    StyleAdjuster adjuster(document().inQuirksMode());
+    adjuster.adjustRenderStyle(state.style(), state.parentStyle(), element, state.cachedUAStyle());
+}
+
+// Start loading resources referenced by this style.
+void StyleResolver::loadPendingResources(StyleResolverState& state)
+{
+    m_styleResourceLoader.loadPendingResources(state.style(), state.elementStyleResources());
+    document().styleEngine()->fontSelector()->fontLoader()->loadPendingFonts();
 }
 
 PassRefPtr<RenderStyle> StyleResolver::styleForElement(Element* element, RenderStyle* defaultParent, StyleSharingBehavior sharingBehavior,
     RuleMatchingBehavior matchingBehavior)
 {
     ASSERT(document().frame());
-    ASSERT(documentSettings());
+    ASSERT(document().settings());
     ASSERT(!hasPendingAuthorStyleSheets());
     ASSERT(!m_needCollectFeatures);
 
     // Once an element has a renderer, we don't try to destroy it, since otherwise the renderer
     // will vanish if a style recalc happens during loading.
-    if (sharingBehavior == AllowStyleSharing && !element->document().haveStylesheetsLoaded() && !element->renderer()) {
+    if (sharingBehavior == AllowStyleSharing && !document().isRenderingReady() && !element->renderer()) {
         if (!s_styleNotYetAvailable) {
             s_styleNotYetAvailable = RenderStyle::create().leakRef();
             s_styleNotYetAvailable->setDisplay(NONE);
             s_styleNotYetAvailable->font().update(document().styleEngine()->fontSelector());
         }
-        element->document().setHasNodesWithPlaceholderStyle();
+
+        document().setHasNodesWithPlaceholderStyle();
         return s_styleNotYetAvailable;
     }
 
     didAccess();
 
+    StyleResolverParentScope::ensureParentStackIsPushed();
+
     if (element == document().documentElement())
         resetDirectionAndWritingModeOnDocument(document());
     StyleResolverState state(document(), element, defaultParent);
@@ -676,7 +594,7 @@ PassRefPtr<RenderStyle> StyleResolver::styleForElement(Element* element, RenderS
         }
     }
 
-    state.fontBuilder().initForStyleResolve(state.document(), state.style(), state.useSVGZoomRules());
+    state.fontBuilder().initForStyleResolve(state.document(), state.style());
 
     if (element->isLink()) {
         state.style()->setIsLink(true);
@@ -697,27 +615,26 @@ PassRefPtr<RenderStyle> StyleResolver::styleForElement(Element* element, RenderS
     {
         ElementRuleCollector collector(state.elementContext(), m_selectorFilter, state.style());
 
-        if (matchingBehavior == MatchOnlyUserAgentRules)
-            matchUARules(collector);
-        else
-            matchAllRules(state, collector, matchingBehavior != MatchAllRulesExcludingSMIL);
+        matchAllRules(state, collector, matchingBehavior != MatchAllRulesExcludingSMIL);
 
         applyMatchedProperties(state, collector.matchedResult());
+        applyCallbackSelectors(state);
 
         addContentAttrValuesToFeatures(state.contentAttrValues(), m_features);
     }
-    {
-        StyleAdjuster adjuster(state.cachedUAStyle(), m_document.inQuirksMode());
-        adjuster.adjustRenderStyle(state.style(), state.parentStyle(), element);
-    }
+
+    // Cache our original display.
+    state.style()->setOriginalDisplay(state.style()->display());
+
+    adjustRenderStyle(state, element);
 
     // FIXME: The CSSWG wants to specify that the effects of animations are applied before
     // important rules, but this currently happens here as we require adjustment to have happened
     // before deciding which properties to transition.
-    applyAnimatedProperties(state, element);
+    if (applyAnimatedProperties(state, element))
+        adjustRenderStyle(state, element);
 
-    // FIXME: Shouldn't this be on RenderBody::styleDidChange?
-    if (element->hasTagName(bodyTag))
+    if (isHTMLBodyElement(*element))
         document().textLinkColors().setTextColor(state.style()->color());
 
     setAnimationUpdateIfNeeded(state, *element);
@@ -729,19 +646,18 @@ PassRefPtr<RenderStyle> StyleResolver::styleForElement(Element* element, RenderS
     return state.takeStyle();
 }
 
-PassRefPtr<RenderStyle> StyleResolver::styleForKeyframe(Element* element, const RenderStyle& elementStyle, RenderStyle* parentStyle, const StyleKeyframe* keyframe, const AtomicString& animationName)
+PassRefPtr<RenderStyle> StyleResolver::styleForKeyframe(Element& element, const RenderStyle& elementStyle, RenderStyle* parentStyle, const StyleKeyframe* keyframe, const AtomicString& animationName)
 {
     ASSERT(document().frame());
-    ASSERT(documentSettings());
+    ASSERT(document().settings());
     ASSERT(!hasPendingAuthorStyleSheets());
 
-    if (element == document().documentElement())
+    if (&element == document().documentElement())
         resetDirectionAndWritingModeOnDocument(document());
-    StyleResolverState state(document(), element, parentStyle);
+    StyleResolverState state(document(), &element, parentStyle);
 
     MatchResult result;
-    if (keyframe->properties())
-        result.addMatchedProperties(keyframe->properties());
+    result.addMatchedProperties(&keyframe->properties());
 
     ASSERT(!state.style());
 
@@ -749,27 +665,15 @@ PassRefPtr<RenderStyle> StyleResolver::styleForKeyframe(Element* element, const
     state.setStyle(RenderStyle::clone(&elementStyle));
     state.setLineHeightValue(0);
 
-    // Make sure that the CSSAnimationData for the animation to which this
-    // keyframe belongs is first in the list. This makes sure that if the
-    // animation-timing-function property is set for this keyframe, it will be
-    // applied to the correct CSSAnimationData object. Note that objects other
-    // than the first in the list are ignored when reading the timing function
-    // value. See KeyframeValue::timingFunction().
-    CSSAnimationDataList* animations = state.style()->accessAnimations();
-    ASSERT(animations && !animations->isEmpty());
-    while (animations->animation(0)->name() != animationName)
-        animations->remove(0);
-    ASSERT(!animations->isEmpty() && animations->animation(0)->name() == animationName);
-
-    state.fontBuilder().initForStyleResolve(state.document(), state.style(), state.useSVGZoomRules());
+    state.fontBuilder().initForStyleResolve(state.document(), state.style());
 
     // We don't need to bother with !important. Since there is only ever one
     // decl, there's nothing to override. So just add the first properties.
+    // We also don't need to bother with animation properties since the only
+    // relevant one is animation-timing-function and we special-case that in
+    // CSSAnimations.cpp
     bool inheritedOnly = false;
-    if (keyframe->properties()) {
-        applyMatchedProperties<AnimationProperties>(state, result, false, 0, result.matchedProperties.size() - 1, inheritedOnly);
-        applyMatchedProperties<HighPriorityProperties>(state, result, false, 0, result.matchedProperties.size() - 1, inheritedOnly);
-    }
+    applyMatchedProperties<HighPriorityProperties>(state, result, false, 0, result.matchedProperties.size() - 1, inheritedOnly);
 
     // If our font got dirtied, go ahead and update it now.
     updateFont(state);
@@ -779,16 +683,9 @@ PassRefPtr<RenderStyle> StyleResolver::styleForKeyframe(Element* element, const
         StyleBuilder::applyProperty(CSSPropertyLineHeight, state, state.lineHeightValue());
 
     // Now do rest of the properties.
-    if (keyframe->properties())
-        applyMatchedProperties<LowPriorityProperties>(state, result, false, 0, result.matchedProperties.size() - 1, inheritedOnly);
-
-    // If our font got dirtied by one of the non-essential font props,
-    // go ahead and update it a second time.
-    updateFont(state);
+    applyMatchedProperties<LowPriorityProperties>(state, result, false, 0, result.matchedProperties.size() - 1, inheritedOnly);
 
-    // Start loading resources referenced by this style.
-    m_styleResourceLoader.loadPendingResources(state.style(), state.elementStyleResources());
-    document().styleEngine()->fontSelector()->loadPendingFonts();
+    loadPendingResources(state);
 
     didAccess();
 
@@ -797,50 +694,58 @@ PassRefPtr<RenderStyle> StyleResolver::styleForKeyframe(Element* element, const
 
 // This function is used by the WebAnimations JavaScript API method animate().
 // FIXME: Remove this when animate() switches away from resolution-dependent parsing.
-PassRefPtr<KeyframeEffectModel> StyleResolver::createKeyframeEffectModel(Element& element, const Vector<RefPtr<MutableStylePropertySet> >& propertySetVector, KeyframeEffectModel::KeyframeVector& keyframes)
+PassRefPtrWillBeRawPtr<AnimatableValue> StyleResolver::createAnimatableValueSnapshot(Element& element, CSSPropertyID property, CSSValue& value)
 {
-    ASSERT(propertySetVector.size() == keyframes.size());
-
+    RefPtr<RenderStyle> style;
+    if (element.renderStyle())
+        style = RenderStyle::clone(element.renderStyle());
+    else
+        style = RenderStyle::create();
     StyleResolverState state(element.document(), &element);
-    state.setStyle(RenderStyle::create());
+    state.setStyle(style);
+    state.fontBuilder().initForStyleResolve(state.document(), state.style());
+    return createAnimatableValueSnapshot(state, property, value);
+}
 
-    for (unsigned i = 0; i < propertySetVector.size(); ++i) {
-        for (unsigned j = 0; j < propertySetVector[i]->propertyCount(); ++j) {
-            CSSPropertyID id = propertySetVector[i]->propertyAt(j).id();
-            StyleBuilder::applyProperty(id, state, propertySetVector[i]->getPropertyCSSValue(id).get());
-            keyframes[i]->setPropertyValue(id, CSSAnimatableValueFactory::create(id, *state.style()).get());
-        }
-    }
-    return KeyframeEffectModel::create(keyframes);
+PassRefPtrWillBeRawPtr<AnimatableValue> StyleResolver::createAnimatableValueSnapshot(StyleResolverState& state, CSSPropertyID property, CSSValue& value)
+{
+    StyleBuilder::applyProperty(property, state, &value);
+    return CSSAnimatableValueFactory::create(property, *state.style());
 }
 
-PassRefPtr<PseudoElement> StyleResolver::createPseudoElementIfNeeded(Element& parent, PseudoId pseudoId)
+PassRefPtrWillBeRawPtr<PseudoElement> StyleResolver::createPseudoElementIfNeeded(Element& parent, PseudoId pseudoId)
 {
     RenderObject* parentRenderer = parent.renderer();
     if (!parentRenderer)
-        return 0;
+        return nullptr;
 
     if (pseudoId < FIRST_INTERNAL_PSEUDOID && !parentRenderer->style()->hasPseudoStyle(pseudoId))
-        return 0;
+        return nullptr;
 
     if (pseudoId == BACKDROP && !parent.isInTopLayer())
-        return 0;
+        return nullptr;
 
     if (!parentRenderer->canHaveGeneratedChildren())
-        return 0;
+        return nullptr;
 
     RenderStyle* parentStyle = parentRenderer->style();
+    if (RenderStyle* cachedStyle = parentStyle->getCachedPseudoStyle(pseudoId)) {
+        if (!pseudoElementRendererIsNeeded(cachedStyle))
+            return nullptr;
+        return PseudoElement::create(&parent, pseudoId);
+    }
+
     StyleResolverState state(document(), &parent, parentStyle);
     if (!pseudoStyleForElementInternal(parent, pseudoId, parentStyle, state))
-        return 0;
+        return nullptr;
     RefPtr<RenderStyle> style = state.takeStyle();
     ASSERT(style);
+    parentStyle->addCachedPseudoStyle(style);
 
     if (!pseudoElementRendererIsNeeded(style.get()))
-        return 0;
+        return nullptr;
 
-    parentStyle->addCachedPseudoStyle(style.release());
-    RefPtr<PseudoElement> pseudo = PseudoElement::create(&parent, pseudoId);
+    RefPtrWillBeRawPtr<PseudoElement> pseudo = PseudoElement::create(&parent, pseudoId);
 
     setAnimationUpdateIfNeeded(state, *pseudo);
     if (ActiveAnimations* activeAnimations = pseudo->activeAnimations())
@@ -851,9 +756,11 @@ PassRefPtr<PseudoElement> StyleResolver::createPseudoElementIfNeeded(Element& pa
 bool StyleResolver::pseudoStyleForElementInternal(Element& element, const PseudoStyleRequest& pseudoStyleRequest, RenderStyle* parentStyle, StyleResolverState& state)
 {
     ASSERT(document().frame());
-    ASSERT(documentSettings());
+    ASSERT(document().settings());
     ASSERT(pseudoStyleRequest.pseudoId != FIRST_LINE_INHERITED);
 
+    StyleResolverParentScope::ensureParentStackIsPushed();
+
     if (pseudoStyleRequest.allowsInheritance(state.parentStyle())) {
         state.setStyle(RenderStyle::create());
         state.style()->inheritFrom(state.parentStyle());
@@ -862,7 +769,8 @@ bool StyleResolver::pseudoStyleForElementInternal(Element& element, const Pseudo
         state.setParentStyle(RenderStyle::clone(state.style()));
     }
 
-    state.fontBuilder().initForStyleResolve(state.document(), state.style(), state.useSVGZoomRules());
+    state.style()->setStyleType(pseudoStyleRequest.pseudoId);
+    state.fontBuilder().initForStyleResolve(state.document(), state.style());
 
     // Since we don't use pseudo-elements in any of our quirk/print
     // user agent rules, don't waste time walking those rules.
@@ -878,23 +786,24 @@ bool StyleResolver::pseudoStyleForElementInternal(Element& element, const Pseudo
         if (collector.matchedResult().matchedProperties.isEmpty())
             return false;
 
-        state.style()->setStyleType(pseudoStyleRequest.pseudoId);
-
         applyMatchedProperties(state, collector.matchedResult());
+        applyCallbackSelectors(state);
 
         addContentAttrValuesToFeatures(state.contentAttrValues(), m_features);
     }
-    {
-        StyleAdjuster adjuster(state.cachedUAStyle(), m_document.inQuirksMode());
-        // FIXME: Passing 0 as the Element* introduces a lot of complexity
-        // in the adjustRenderStyle code.
-        adjuster.adjustRenderStyle(state.style(), state.parentStyle(), 0);
-    }
+
+    // Cache our original display.
+    state.style()->setOriginalDisplay(state.style()->display());
+
+    // FIXME: Passing 0 as the Element* introduces a lot of complexity
+    // in the adjustRenderStyle code.
+    adjustRenderStyle(state, 0);
 
     // FIXME: The CSSWG wants to specify that the effects of animations are applied before
     // important rules, but this currently happens here as we require adjustment to have happened
     // before deciding which properties to transition.
-    applyAnimatedProperties(state, element.pseudoElement(pseudoStyleRequest.pseudoId));
+    if (applyAnimatedProperties(state, element.pseudoElement(pseudoStyleRequest.pseudoId)))
+        adjustRenderStyle(state, 0);
 
     didAccess();
 
@@ -908,11 +817,14 @@ PassRefPtr<RenderStyle> StyleResolver::pseudoStyleForElement(Element* element, c
 {
     ASSERT(parentStyle);
     if (!element)
-        return 0;
+        return nullptr;
 
     StyleResolverState state(document(), element, parentStyle);
-    if (!pseudoStyleForElementInternal(*element, pseudoStyleRequest, parentStyle, state))
-        return 0;
+    if (!pseudoStyleForElementInternal(*element, pseudoStyleRequest, parentStyle, state)) {
+        if (pseudoStyleRequest.type == PseudoStyleRequest::ForRenderer)
+            return nullptr;
+        return state.takeStyle();
+    }
 
     if (PseudoElement* pseudoElement = element->pseudoElement(pseudoStyleRequest.pseudoId))
         setAnimationUpdateIfNeeded(state, *pseudoElement);
@@ -932,13 +844,13 @@ PassRefPtr<RenderStyle> StyleResolver::styleForPage(int pageIndex)
     ASSERT(rootElementStyle);
     state.style()->inheritFrom(rootElementStyle);
 
-    state.fontBuilder().initForStyleResolve(state.document(), state.style(), state.useSVGZoomRules());
+    state.fontBuilder().initForStyleResolve(state.document(), state.style());
 
     PageRuleCollector collector(rootElementStyle, pageIndex);
 
     collector.matchPageRules(CSSDefaultStyleSheets::instance().defaultPrintStyle());
 
-    if (ScopedStyleResolver* scopedResolver = m_styleTree.scopedStyleResolverForDocument())
+    if (ScopedStyleResolver* scopedResolver = document().scopedStyleResolver())
         scopedResolver->matchPageRules(collector);
 
     state.setLineHeightValue(0);
@@ -958,9 +870,7 @@ PassRefPtr<RenderStyle> StyleResolver::styleForPage(int pageIndex)
 
     addContentAttrValuesToFeatures(state.contentAttrValues(), m_features);
 
-    // Start loading resources referenced by this style.
-    m_styleResourceLoader.loadPendingResources(state.style(), state.elementStyleResources());
-    document().styleEngine()->fontSelector()->loadPendingFonts();
+    loadPendingResources(state);
 
     didAccess();
 
@@ -979,7 +889,7 @@ void StyleResolver::collectViewportRules()
     if (document().isMobileDocument())
         viewportStyleResolver()->collectViewportRules(defaultStyleSheets.defaultXHTMLMobileProfileStyle(), ViewportStyleResolver::UserAgentOrigin);
 
-    if (ScopedStyleResolver* scopedResolver = m_styleTree.scopedStyleResolverForDocument())
+    if (ScopedStyleResolver* scopedResolver = document().scopedStyleResolver())
         scopedResolver->collectViewportRulesTo(this);
 
     viewportStyleResolver()->resolve();
@@ -989,7 +899,7 @@ PassRefPtr<RenderStyle> StyleResolver::defaultStyleForElement()
 {
     StyleResolverState state(document(), 0);
     state.setStyle(RenderStyle::create());
-    state.fontBuilder().initForStyleResolve(document(), state.style(), state.useSVGZoomRules());
+    state.fontBuilder().initForStyleResolve(document(), state.style());
     state.style()->setLineHeight(RenderStyle::initialLineHeight());
     state.setLineHeightValue(0);
     state.fontBuilder().setInitial(state.style()->effectiveZoom());
@@ -1001,9 +911,8 @@ PassRefPtr<RenderStyle> StyleResolver::styleForText(Text* textNode)
 {
     ASSERT(textNode);
 
-    NodeRenderingTraversal::ParentDetails parentDetails;
-    Node* parentNode = NodeRenderingTraversal::parent(textNode, &parentDetails);
-    if (!parentNode || !parentNode->renderStyle() || parentDetails.resetStyleInheritance())
+    Node* parentNode = NodeRenderingTraversal::parent(textNode);
+    if (!parentNode || !parentNode->renderStyle())
         return defaultStyleForElement();
     return parentNode->renderStyle();
 }
@@ -1011,11 +920,9 @@ PassRefPtr<RenderStyle> StyleResolver::styleForText(Text* textNode)
 void StyleResolver::updateFont(StyleResolverState& state)
 {
     state.fontBuilder().createFont(document().styleEngine()->fontSelector(), state.parentStyle(), state.style());
-    if (state.fontBuilder().fontSizeHasViewportUnits())
-        state.style()->setHasViewportUnits();
 }
 
-PassRefPtr<StyleRuleList> StyleResolver::styleRulesForElement(Element* element, unsigned rulesToInclude)
+PassRefPtrWillBeRawPtr<StyleRuleList> StyleResolver::styleRulesForElement(Element* element, unsigned rulesToInclude)
 {
     ASSERT(element);
     StyleResolverState state(document(), element);
@@ -1025,7 +932,7 @@ PassRefPtr<StyleRuleList> StyleResolver::styleRulesForElement(Element* element,
     return collector.matchedStyleRuleList();
 }
 
-PassRefPtr<CSSRuleList> StyleResolver::pseudoCSSRulesForElement(Element* element, PseudoId pseudoId, unsigned rulesToInclude)
+PassRefPtrWillBeRawPtr<CSSRuleList> StyleResolver::pseudoCSSRulesForElement(Element* element, PseudoId pseudoId, unsigned rulesToInclude)
 {
     ASSERT(element);
     StyleResolverState state(document(), element);
@@ -1035,7 +942,7 @@ PassRefPtr<CSSRuleList> StyleResolver::pseudoCSSRulesForElement(Element* element
     return collector.matchedCSSRuleList();
 }
 
-PassRefPtr<CSSRuleList> StyleResolver::cssRulesForElement(Element* element, unsigned rulesToInclude)
+PassRefPtrWillBeRawPtr<CSSRuleList> StyleResolver::cssRulesForElement(Element* element, unsigned rulesToInclude)
 {
     return pseudoCSSRulesForElement(element, NOPSEUDO, rulesToInclude);
 }
@@ -1056,9 +963,9 @@ void StyleResolver::collectPseudoRulesForElement(Element* element, ElementRuleCo
 // -------------------------------------------------------------------------------------
 // this is mostly boring stuff on how to apply a certain rule to the renderstyle...
 
-void StyleResolver::applyAnimatedProperties(StyleResolverState& state, Element* animatingElement)
+bool StyleResolver::applyAnimatedProperties(StyleResolverState& state, const Element* animatingElement)
 {
-    const Element* element = state.element();
+    Element* element = state.element();
     ASSERT(element);
 
     // The animating element may be this element, or its pseudo element. It is
@@ -1067,41 +974,84 @@ void StyleResolver::applyAnimatedProperties(StyleResolverState& state, Element*
     ASSERT(animatingElement == element || !animatingElement || animatingElement->parentOrShadowHostElement() == element);
 
     if (!(animatingElement && animatingElement->hasActiveAnimations())
-        && !(state.style()->transitions() && !state.style()->transitions()->isEmpty())
-        && !(state.style()->animations() && !state.style()->animations()->isEmpty()))
-        return;
+        && !state.style()->transitions() && !state.style()->animations())
+        return false;
 
     state.setAnimationUpdate(CSSAnimations::calculateUpdate(animatingElement, *element, *state.style(), state.parentStyle(), this));
     if (!state.animationUpdate())
+        return false;
+
+    const WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> >& activeInterpolationsForAnimations = state.animationUpdate()->activeInterpolationsForAnimations();
+    const WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> >& activeInterpolationsForTransitions = state.animationUpdate()->activeInterpolationsForTransitions();
+    applyAnimatedProperties<HighPriorityProperties>(state, activeInterpolationsForAnimations);
+    applyAnimatedProperties<HighPriorityProperties>(state, activeInterpolationsForTransitions);
+
+    updateFont(state);
+
+    applyAnimatedProperties<LowPriorityProperties>(state, activeInterpolationsForAnimations);
+    applyAnimatedProperties<LowPriorityProperties>(state, activeInterpolationsForTransitions);
+
+    // Start loading resources used by animations.
+    loadPendingResources(state);
+
+    ASSERT(!state.fontBuilder().fontDirty());
+
+    return true;
+}
+
+static inline ScopedStyleResolver* scopedResolverFor(const Element* element)
+{
+    for (TreeScope* treeScope = &element->treeScope(); treeScope; treeScope = treeScope->parentTreeScope()) {
+        if (ScopedStyleResolver* scopedStyleResolver = treeScope->scopedStyleResolver())
+            return scopedStyleResolver;
+    }
+    return 0;
+}
+
+void StyleResolver::resolveScopedStyles(const Element* element, WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8>& resolvers)
+{
+    for (ScopedStyleResolver* scopedResolver = scopedResolverFor(element); scopedResolver; scopedResolver = scopedResolver->parent())
+        resolvers.append(scopedResolver);
+}
+
+void StyleResolver::collectScopedResolversForHostedShadowTrees(const Element* element, WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8>& resolvers)
+{
+    ElementShadow* shadow = element->shadow();
+    if (!shadow)
         return;
 
-    const AnimationEffect::CompositableValueMap& compositableValuesForAnimations = state.animationUpdate()->compositableValuesForAnimations();
-    const AnimationEffect::CompositableValueMap& compositableValuesForTransitions = state.animationUpdate()->compositableValuesForTransitions();
-    applyAnimatedProperties<HighPriorityProperties>(state, compositableValuesForAnimations);
-    applyAnimatedProperties<HighPriorityProperties>(state, compositableValuesForTransitions);
-    applyAnimatedProperties<LowPriorityProperties>(state, compositableValuesForAnimations);
-    applyAnimatedProperties<LowPriorityProperties>(state, compositableValuesForTransitions);
+    // Adding scoped resolver for active shadow roots for shadow host styling.
+    for (ShadowRoot* shadowRoot = shadow->youngestShadowRoot(); shadowRoot; shadowRoot = shadowRoot->olderShadowRoot()) {
+        if (shadowRoot->numberOfStyles() > 0) {
+            if (ScopedStyleResolver* resolver = shadowRoot->scopedStyleResolver())
+                resolvers.append(resolver);
+        }
+    }
+}
 
-    // If the animations/transitions change opacity or transform, we need to update
-    // the style to impose the stacking rules. Note that this is also
-    // done in StyleResolver::adjustRenderStyle().
-    RenderStyle* style = state.style();
-    if (style->hasAutoZIndex() && (style->opacity() < 1.0f || style->hasTransform()))
-        style->setZIndex(0);
+void StyleResolver::styleTreeResolveScopedKeyframesRules(const Element* element, WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8>& resolvers)
+{
+    TreeScope& treeScope = element->treeScope();
+
+    // Add resolvers for shadow roots hosted by the given element.
+    collectScopedResolversForHostedShadowTrees(element, resolvers);
+
+    // Add resolvers while walking up DOM tree from the given element.
+    for (ScopedStyleResolver* scopedResolver = scopedResolverFor(element); scopedResolver; scopedResolver = scopedResolver->parent()) {
+        if (scopedResolver->treeScope() == treeScope)
+            resolvers.append(scopedResolver);
+    }
 }
 
 template <StyleResolver::StyleApplicationPass pass>
-void StyleResolver::applyAnimatedProperties(StyleResolverState& state, const AnimationEffect::CompositableValueMap& compositableValues)
+void StyleResolver::applyAnimatedProperties(StyleResolverState& state, const WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> >& activeInterpolations)
 {
-    ASSERT(pass != AnimationProperties);
-
-    for (AnimationEffect::CompositableValueMap::const_iterator iter = compositableValues.begin(); iter != compositableValues.end(); ++iter) {
+    for (WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> >::const_iterator iter = activeInterpolations.begin(); iter != activeInterpolations.end(); ++iter) {
         CSSPropertyID property = iter->key;
         if (!isPropertyForPass<pass>(property))
             continue;
-        ASSERT_WITH_MESSAGE(!iter->value->dependsOnUnderlyingValue(), "Web Animations not yet implemented: An interface for compositing onto the underlying value.");
-        RefPtr<AnimatableValue> animatableValue = iter->value->compositeOnto(0);
-        AnimatedStyleBuilder::applyProperty(property, state, animatableValue.get());
+        const StyleInterpolation* interpolation = toStyleInterpolation(iter->value.get());
+        interpolation->apply(state);
     }
 }
 
@@ -1125,6 +1075,7 @@ static inline bool isValidCueStyleProperty(CSSPropertyID id)
     case CSSPropertyFont:
     case CSSPropertyFontFamily:
     case CSSPropertyFontSize:
+    case CSSPropertyFontStretch:
     case CSSPropertyFontStyle:
     case CSSPropertyFontVariant:
     case CSSPropertyFontWeight:
@@ -1153,39 +1104,226 @@ static inline bool isValidCueStyleProperty(CSSPropertyID id)
     return false;
 }
 
+static inline bool isValidFirstLetterStyleProperty(CSSPropertyID id)
+{
+    switch (id) {
+    // Valid ::first-letter properties listed in spec:
+    // http://www.w3.org/TR/css3-selectors/#application-in-css
+    case CSSPropertyBackgroundAttachment:
+    case CSSPropertyBackgroundBlendMode:
+    case CSSPropertyBackgroundClip:
+    case CSSPropertyBackgroundColor:
+    case CSSPropertyBackgroundImage:
+    case CSSPropertyBackgroundOrigin:
+    case CSSPropertyBackgroundPosition:
+    case CSSPropertyBackgroundPositionX:
+    case CSSPropertyBackgroundPositionY:
+    case CSSPropertyBackgroundRepeat:
+    case CSSPropertyBackgroundRepeatX:
+    case CSSPropertyBackgroundRepeatY:
+    case CSSPropertyBackgroundSize:
+    case CSSPropertyBorderBottomColor:
+    case CSSPropertyBorderBottomLeftRadius:
+    case CSSPropertyBorderBottomRightRadius:
+    case CSSPropertyBorderBottomStyle:
+    case CSSPropertyBorderBottomWidth:
+    case CSSPropertyBorderImageOutset:
+    case CSSPropertyBorderImageRepeat:
+    case CSSPropertyBorderImageSlice:
+    case CSSPropertyBorderImageSource:
+    case CSSPropertyBorderImageWidth:
+    case CSSPropertyBorderLeftColor:
+    case CSSPropertyBorderLeftStyle:
+    case CSSPropertyBorderLeftWidth:
+    case CSSPropertyBorderRightColor:
+    case CSSPropertyBorderRightStyle:
+    case CSSPropertyBorderRightWidth:
+    case CSSPropertyBorderTopColor:
+    case CSSPropertyBorderTopLeftRadius:
+    case CSSPropertyBorderTopRightRadius:
+    case CSSPropertyBorderTopStyle:
+    case CSSPropertyBorderTopWidth:
+    case CSSPropertyColor:
+    case CSSPropertyFloat:
+    case CSSPropertyFont:
+    case CSSPropertyFontFamily:
+    case CSSPropertyFontKerning:
+    case CSSPropertyFontSize:
+    case CSSPropertyFontStretch:
+    case CSSPropertyFontStyle:
+    case CSSPropertyFontVariant:
+    case CSSPropertyFontVariantLigatures:
+    case CSSPropertyFontWeight:
+    case CSSPropertyLetterSpacing:
+    case CSSPropertyLineHeight:
+    case CSSPropertyMarginBottom:
+    case CSSPropertyMarginLeft:
+    case CSSPropertyMarginRight:
+    case CSSPropertyMarginTop:
+    case CSSPropertyPaddingBottom:
+    case CSSPropertyPaddingLeft:
+    case CSSPropertyPaddingRight:
+    case CSSPropertyPaddingTop:
+    case CSSPropertyTextTransform:
+    case CSSPropertyVerticalAlign:
+    case CSSPropertyWebkitBackgroundClip:
+    case CSSPropertyWebkitBackgroundComposite:
+    case CSSPropertyWebkitBackgroundOrigin:
+    case CSSPropertyWebkitBackgroundSize:
+    case CSSPropertyWebkitBorderAfter:
+    case CSSPropertyWebkitBorderAfterColor:
+    case CSSPropertyWebkitBorderAfterStyle:
+    case CSSPropertyWebkitBorderAfterWidth:
+    case CSSPropertyWebkitBorderBefore:
+    case CSSPropertyWebkitBorderBeforeColor:
+    case CSSPropertyWebkitBorderBeforeStyle:
+    case CSSPropertyWebkitBorderBeforeWidth:
+    case CSSPropertyWebkitBorderEnd:
+    case CSSPropertyWebkitBorderEndColor:
+    case CSSPropertyWebkitBorderEndStyle:
+    case CSSPropertyWebkitBorderEndWidth:
+    case CSSPropertyWebkitBorderFit:
+    case CSSPropertyWebkitBorderHorizontalSpacing:
+    case CSSPropertyWebkitBorderImage:
+    case CSSPropertyWebkitBorderRadius:
+    case CSSPropertyWebkitBorderStart:
+    case CSSPropertyWebkitBorderStartColor:
+    case CSSPropertyWebkitBorderStartStyle:
+    case CSSPropertyWebkitBorderStartWidth:
+    case CSSPropertyWebkitBorderVerticalSpacing:
+    case CSSPropertyWebkitFontSmoothing:
+    case CSSPropertyWebkitMarginAfter:
+    case CSSPropertyWebkitMarginAfterCollapse:
+    case CSSPropertyWebkitMarginBefore:
+    case CSSPropertyWebkitMarginBeforeCollapse:
+    case CSSPropertyWebkitMarginBottomCollapse:
+    case CSSPropertyWebkitMarginCollapse:
+    case CSSPropertyWebkitMarginEnd:
+    case CSSPropertyWebkitMarginStart:
+    case CSSPropertyWebkitMarginTopCollapse:
+    case CSSPropertyWordSpacing:
+        return true;
+    case CSSPropertyTextDecorationColor:
+    case CSSPropertyTextDecorationLine:
+    case CSSPropertyTextDecorationStyle:
+        return RuntimeEnabledFeatures::css3TextDecorationsEnabled();
+
+    // text-shadow added in text decoration spec:
+    // http://www.w3.org/TR/css-text-decor-3/#text-shadow-property
+    case CSSPropertyTextShadow:
+    // box-shadox added in CSS3 backgrounds spec:
+    // http://www.w3.org/TR/css3-background/#placement
+    case CSSPropertyBoxShadow:
+    case CSSPropertyWebkitBoxShadow:
+    // Properties that we currently support outside of spec.
+    case CSSPropertyWebkitLineBoxContain:
+    case CSSPropertyVisibility:
+        return true;
+
+    default:
+        return false;
+    }
+}
+
+// FIXME: Consider refactoring to create a new class which owns the following
+// first/last/range properties.
+// This method returns the first CSSPropertyId of high priority properties.
+// Other properties can depend on high priority properties. For example,
+// border-color property with currentColor value depends on color property.
+// All high priority properties are obtained by using
+// firstCSSPropertyId<HighPriorityProperties> and
+// lastCSSPropertyId<HighPriorityProperties>.
+template<> CSSPropertyID StyleResolver::firstCSSPropertyId<StyleResolver::HighPriorityProperties>()
+{
+    COMPILE_ASSERT(CSSPropertyColor == firstCSSProperty, CSS_color_is_first_high_priority_property);
+    return CSSPropertyColor;
+}
+
+// This method returns the last CSSPropertyId of high priority properties.
+template<> CSSPropertyID StyleResolver::lastCSSPropertyId<StyleResolver::HighPriorityProperties>()
+{
+    COMPILE_ASSERT(CSSPropertyLineHeight == CSSPropertyColor + 18, CSS_line_height_is_end_of_high_prioity_property_range);
+    COMPILE_ASSERT(CSSPropertyZoom == CSSPropertyLineHeight - 1, CSS_zoom_is_before_line_height);
+    return CSSPropertyLineHeight;
+}
+
+// This method returns the first CSSPropertyId of remaining properties,
+// i.e. low priority properties. No properties depend on low priority
+// properties. So we don't need to resolve such properties quickly.
+// All low priority properties are obtained by using
+// firstCSSPropertyId<LowPriorityProperties> and
+// lastCSSPropertyId<LowPriorityProperties>.
+template<> CSSPropertyID StyleResolver::firstCSSPropertyId<StyleResolver::LowPriorityProperties>()
+{
+    COMPILE_ASSERT(CSSPropertyAlignContent == CSSPropertyLineHeight + 1, CSS_background_is_first_low_priority_property);
+    return CSSPropertyAlignContent;
+}
+
+// This method returns the last CSSPropertyId of low priority properties.
+template<> CSSPropertyID StyleResolver::lastCSSPropertyId<StyleResolver::LowPriorityProperties>()
+{
+    return static_cast<CSSPropertyID>(lastCSSProperty);
+}
+
 template <StyleResolver::StyleApplicationPass pass>
 bool StyleResolver::isPropertyForPass(CSSPropertyID property)
 {
-    const CSSPropertyID firstAnimationProperty = CSSPropertyDisplay;
-    const CSSPropertyID lastAnimationProperty = CSSPropertyTransitionTimingFunction;
-    COMPILE_ASSERT(firstCSSProperty == firstAnimationProperty, CSS_first_animation_property_should_be_first_property);
-    const CSSPropertyID firstHighPriorityProperty = CSSPropertyColor;
-    const CSSPropertyID lastHighPriorityProperty = CSSPropertyLineHeight;
-    COMPILE_ASSERT(lastAnimationProperty + 1 == firstHighPriorityProperty, CSS_color_is_first_high_priority_property);
-    COMPILE_ASSERT(CSSPropertyLineHeight == firstHighPriorityProperty + 17, CSS_line_height_is_end_of_high_prioity_property_range);
-    COMPILE_ASSERT(CSSPropertyZoom == lastHighPriorityProperty - 1, CSS_zoom_is_before_line_height);
-    switch (pass) {
-    case AnimationProperties:
-        return property >= firstAnimationProperty && property <= lastAnimationProperty;
-    case HighPriorityProperties:
-        return property >= firstHighPriorityProperty && property <= lastHighPriorityProperty;
-    case LowPriorityProperties:
-        return property > lastHighPriorityProperty;
-    }
-    ASSERT_NOT_REACHED();
-    return false;
+    return firstCSSPropertyId<pass>() <= property && property <= lastCSSPropertyId<pass>();
 }
 
+// This method expands the 'all' shorthand property to longhand properties
+// and applies the expanded longhand properties.
 template <StyleResolver::StyleApplicationPass pass>
-void StyleResolver::applyProperties(StyleResolverState& state, const StylePropertySet* properties, StyleRule* rule, bool isImportant, bool inheritedOnly, PropertyWhitelistType propertyWhitelistType)
+void StyleResolver::applyAllProperty(StyleResolverState& state, CSSValue* allValue)
 {
-    state.setCurrentRule(rule);
+    bool isUnsetValue = !allValue->isInitialValue() && !allValue->isInheritedValue();
+    unsigned startCSSProperty = firstCSSPropertyId<pass>();
+    unsigned endCSSProperty = lastCSSPropertyId<pass>();
 
+    for (unsigned i = startCSSProperty; i <= endCSSProperty; ++i) {
+        CSSPropertyID propertyId = static_cast<CSSPropertyID>(i);
+
+        // StyleBuilder does not allow any expanded shorthands.
+        if (isExpandedShorthandForAll(propertyId))
+            continue;
+
+        // all shorthand spec says:
+        // The all property is a shorthand that resets all CSS properties
+        // except direction and unicode-bidi.
+        // c.f. http://dev.w3.org/csswg/css-cascade/#all-shorthand
+        // We skip applyProperty when a given property is unicode-bidi or
+        // direction.
+        if (!CSSProperty::isAffectedByAllProperty(propertyId))
+            continue;
+
+        CSSValue* value;
+        if (!isUnsetValue) {
+            value = allValue;
+        } else {
+            if (CSSPropertyMetadata::isInheritedProperty(propertyId))
+                value = cssValuePool().createInheritedValue().get();
+            else
+                value = cssValuePool().createExplicitInitialValue().get();
+        }
+        StyleBuilder::applyProperty(propertyId, state, value);
+    }
+}
+
+template <StyleResolver::StyleApplicationPass pass>
+void StyleResolver::applyProperties(StyleResolverState& state, const StylePropertySet* properties, bool isImportant, bool inheritedOnly, PropertyWhitelistType propertyWhitelistType)
+{
     unsigned propertyCount = properties->propertyCount();
     for (unsigned i = 0; i < propertyCount; ++i) {
         StylePropertySet::PropertyReference current = properties->propertyAt(i);
         if (isImportant != current.isImportant())
             continue;
+
+        CSSPropertyID property = current.id();
+        if (property == CSSPropertyAll) {
+            applyAllProperty<pass>(state, current.value());
+            continue;
+        }
+
         if (inheritedOnly && !current.isInherited()) {
             // If the property value is explicitly inherited, we need to apply further non-inherited properties
             // as they might override the value inherited here. For this reason we don't allow declarations with
@@ -1193,10 +1331,11 @@ void StyleResolver::applyProperties(StyleResolverState& state, const StyleProper
             ASSERT(!current.value()->isInheritedValue());
             continue;
         }
-        CSSPropertyID property = current.id();
 
         if (propertyWhitelistType == PropertyWhitelistCue && !isValidCueStyleProperty(property))
             continue;
+        if (propertyWhitelistType == PropertyWhitelistFirstLetter && !isValidFirstLetterStyleProperty(property))
+            continue;
         if (!isPropertyForPass<pass>(property))
             continue;
         if (pass == HighPriorityProperties && property == CSSPropertyLineHeight)
@@ -1215,12 +1354,12 @@ void StyleResolver::applyMatchedProperties(StyleResolverState& state, const Matc
     if (state.style()->insideLink() != NotInsideLink) {
         for (int i = startIndex; i <= endIndex; ++i) {
             const MatchedProperties& matchedProperties = matchResult.matchedProperties[i];
-            unsigned linkMatchType = matchedProperties.linkMatchType;
+            unsigned linkMatchType = matchedProperties.m_types.linkMatchType;
             // FIXME: It would be nicer to pass these as arguments but that requires changes in many places.
             state.setApplyPropertyToRegularStyle(linkMatchType & SelectorChecker::MatchLink);
             state.setApplyPropertyToVisitedLinkStyle(linkMatchType & SelectorChecker::MatchVisited);
 
-            applyProperties<pass>(state, matchedProperties.properties.get(), matchResult.matchedRules[i], isImportant, inheritedOnly, static_cast<PropertyWhitelistType>(matchedProperties.whitelistType));
+            applyProperties<pass>(state, matchedProperties.properties.get(), isImportant, inheritedOnly, static_cast<PropertyWhitelistType>(matchedProperties.m_types.whitelistType));
         }
         state.setApplyPropertyToRegularStyle(true);
         state.setApplyPropertyToVisitedLinkStyle(false);
@@ -1228,7 +1367,7 @@ void StyleResolver::applyMatchedProperties(StyleResolverState& state, const Matc
     }
     for (int i = startIndex; i <= endIndex; ++i) {
         const MatchedProperties& matchedProperties = matchResult.matchedProperties[i];
-        applyProperties<pass>(state, matchedProperties.properties.get(), matchResult.matchedRules[i], isImportant, inheritedOnly, static_cast<PropertyWhitelistType>(matchedProperties.whitelistType));
+        applyProperties<pass>(state, matchedProperties.properties.get(), isImportant, inheritedOnly, static_cast<PropertyWhitelistType>(matchedProperties.m_types.whitelistType));
     }
 }
 
@@ -1257,10 +1396,9 @@ void StyleResolver::applyMatchedProperties(StyleResolverState& state, const Matc
 
     unsigned cacheHash = matchResult.isCacheable ? computeMatchedPropertiesHash(matchResult.matchedProperties.data(), matchResult.matchedProperties.size()) : 0;
     bool applyInheritedOnly = false;
-    const CachedMatchedProperties* cachedMatchedProperties = 0;
+    const CachedMatchedProperties* cachedMatchedProperties = cacheHash ? m_matchedPropertiesCache.find(cacheHash, state, matchResult) : 0;
 
-    if (cacheHash && (cachedMatchedProperties = m_matchedPropertiesCache.find(cacheHash, state, matchResult))
-        && MatchedPropertiesCache::isCacheable(element, state.style(), state.parentStyle())) {
+    if (cachedMatchedProperties && MatchedPropertiesCache::isCacheable(element, state.style(), state.parentStyle())) {
         INCREMENT_STYLE_STATS_COUNTER(*this, matchedPropertyCacheHit);
         // We can build up the style by copying non-inherited properties from an earlier style object built using the same exact
         // style declarations. We then only need to apply the inherited properties, if any, as their values can depend on the
@@ -1282,18 +1420,6 @@ void StyleResolver::applyMatchedProperties(StyleResolverState& state, const Matc
         applyInheritedOnly = true;
     }
 
-    // Apply animation properties in order to apply animation results and trigger transitions below.
-    applyMatchedProperties<AnimationProperties>(state, matchResult, false, 0, matchResult.matchedProperties.size() - 1, applyInheritedOnly);
-    applyMatchedProperties<AnimationProperties>(state, matchResult, true, matchResult.ranges.firstAuthorRule, matchResult.ranges.lastAuthorRule, applyInheritedOnly);
-    applyMatchedProperties<AnimationProperties>(state, matchResult, true, matchResult.ranges.firstUserRule, matchResult.ranges.lastUserRule, applyInheritedOnly);
-    applyMatchedProperties<AnimationProperties>(state, matchResult, true, matchResult.ranges.firstUARule, matchResult.ranges.lastUARule, applyInheritedOnly);
-
-    // Match transition-property / animation-name length by trimming and
-    // lengthening other transition / animation property lists
-    // FIXME: This is wrong because we shouldn't affect the computed values
-    state.style()->adjustAnimations();
-    state.style()->adjustTransitions();
-
     // Now we have all of the matched rules in the appropriate order. Walk the rules and apply
     // high-priority properties first, i.e., those properties that other properties depend on.
     // The order is (1) high-priority not important, (2) high-priority important, (3) normal not important
@@ -1301,9 +1427,19 @@ void StyleResolver::applyMatchedProperties(StyleResolverState& state, const Matc
     state.setLineHeightValue(0);
     applyMatchedProperties<HighPriorityProperties>(state, matchResult, false, 0, matchResult.matchedProperties.size() - 1, applyInheritedOnly);
     applyMatchedProperties<HighPriorityProperties>(state, matchResult, true, matchResult.ranges.firstAuthorRule, matchResult.ranges.lastAuthorRule, applyInheritedOnly);
-    applyMatchedProperties<HighPriorityProperties>(state, matchResult, true, matchResult.ranges.firstUserRule, matchResult.ranges.lastUserRule, applyInheritedOnly);
     applyMatchedProperties<HighPriorityProperties>(state, matchResult, true, matchResult.ranges.firstUARule, matchResult.ranges.lastUARule, applyInheritedOnly);
 
+    if (UNLIKELY(isSVGForeignObjectElement(element))) {
+        // RenderSVGRoot handles zooming for the whole SVG subtree, so foreignObject content should not be scaled again.
+        //
+        // FIXME: The following hijacks the zoom property for foreignObject so that children of foreignObject get the
+        // correct font-size in case of zooming. 'zoom' is part of HighPriorityProperties, along with other font-related
+        // properties used as input to the FontBuilder, so resetting it here may cause the FontBuilder to recompute the
+        // font used as inheritable font for foreignObject content. If we want to support zoom on foreignObject we'll
+        // need to find another way of handling the SVG zoom model.
+        state.setEffectiveZoom(RenderStyle::initialZoom());
+    }
+
     if (cachedMatchedProperties && cachedMatchedProperties->renderStyle->effectiveZoom() != state.style()->effectiveZoom()) {
         state.fontBuilder().setFontDirty(true);
         applyInheritedOnly = false;
@@ -1329,12 +1465,9 @@ void StyleResolver::applyMatchedProperties(StyleResolverState& state, const Matc
     // Now do the author and user normal priority properties and all the !important properties.
     applyMatchedProperties<LowPriorityProperties>(state, matchResult, false, matchResult.ranges.lastUARule + 1, matchResult.matchedProperties.size() - 1, applyInheritedOnly);
     applyMatchedProperties<LowPriorityProperties>(state, matchResult, true, matchResult.ranges.firstAuthorRule, matchResult.ranges.lastAuthorRule, applyInheritedOnly);
-    applyMatchedProperties<LowPriorityProperties>(state, matchResult, true, matchResult.ranges.firstUserRule, matchResult.ranges.lastUserRule, applyInheritedOnly);
     applyMatchedProperties<LowPriorityProperties>(state, matchResult, true, matchResult.ranges.firstUARule, matchResult.ranges.lastUARule, applyInheritedOnly);
 
-    // Start loading resources referenced by this style.
-    m_styleResourceLoader.loadPendingResources(state.style(), state.elementStyleResources());
-    document().styleEngine()->fontSelector()->loadPendingFonts();
+    loadPendingResources(state);
 
     if (!cachedMatchedProperties && cacheHash && MatchedPropertiesCache::isCacheable(element, state.style(), state.parentStyle())) {
         INCREMENT_STYLE_STATS_COUNTER(*this, matchedPropertyCacheAdded);
@@ -1344,6 +1477,26 @@ void StyleResolver::applyMatchedProperties(StyleResolverState& state, const Matc
     ASSERT(!state.fontBuilder().fontDirty());
 }
 
+void StyleResolver::applyCallbackSelectors(StyleResolverState& state)
+{
+    if (!m_watchedSelectorsRules)
+        return;
+
+    ElementRuleCollector collector(state.elementContext(), m_selectorFilter, state.style());
+    collector.setMode(SelectorChecker::CollectingStyleRules);
+
+    MatchRequest matchRequest(m_watchedSelectorsRules.get(), true);
+    RuleRange ruleRange = collector.matchedResult().ranges.authorRuleRange();
+    collector.collectMatchingRules(matchRequest, ruleRange);
+    collector.sortAndTransferMatchedRules();
+
+    RefPtrWillBeRawPtr<StyleRuleList> rules = collector.matchedStyleRuleList();
+    if (!rules)
+        return;
+    for (size_t i = 0; i < rules->m_list.size(); i++)
+        state.style()->addCallbackSelector(rules->m_list[i]->selectorList().selectorsText());
+}
+
 CSSPropertyValue::CSSPropertyValue(CSSPropertyID id, const StylePropertySet& propertySet)
     : property(id), value(propertySet.getPropertyCSSValue(id).get())
 { }
@@ -1371,7 +1524,7 @@ void StyleResolver::printStats()
 {
     if (!m_styleResolverStats)
         return;
-    fprintf(stderr, "=== Style Resolver Stats (resolve #%u) (%s) ===\n", ++m_styleResolverStatsSequence, m_document.url().string().utf8().data());
+    fprintf(stderr, "=== Style Resolver Stats (resolve #%u) (%s) ===\n", ++m_styleResolverStatsSequence, document().url().string().utf8().data());
     fprintf(stderr, "%s\n", m_styleResolverStats->report().utf8().data());
     fprintf(stderr, "== Totals ==\n");
     fprintf(stderr, "%s\n", m_styleResolverStatsTotals->report().utf8().data());
@@ -1382,7 +1535,7 @@ void StyleResolver::applyPropertiesToStyle(const CSSPropertyValue* properties, s
     StyleResolverState state(document(), document().documentElement(), style);
     state.setStyle(style);
 
-    state.fontBuilder().initForStyleResolve(document(), style, state.useSVGZoomRules());
+    state.fontBuilder().initForStyleResolve(document(), style);
 
     for (size_t i = 0; i < count; ++i) {
         if (properties[i].value) {
@@ -1411,10 +1564,29 @@ void StyleResolver::addMediaQueryResults(const MediaQueryResultList& list)
 bool StyleResolver::mediaQueryAffectedByViewportChange() const
 {
     for (unsigned i = 0; i < m_viewportDependentMediaQueryResults.size(); ++i) {
-        if (m_medium->eval(&m_viewportDependentMediaQueryResults[i]->m_expression) != m_viewportDependentMediaQueryResults[i]->m_result)
+        if (m_medium->eval(m_viewportDependentMediaQueryResults[i]->expression()) != m_viewportDependentMediaQueryResults[i]->result())
             return true;
     }
     return false;
 }
 
-} // namespace WebCore
+void StyleResolver::trace(Visitor* visitor)
+{
+#if ENABLE(OILPAN)
+    visitor->trace(m_keyframesRuleMap);
+    visitor->trace(m_matchedPropertiesCache);
+    visitor->trace(m_viewportDependentMediaQueryResults);
+    visitor->trace(m_selectorFilter);
+    visitor->trace(m_viewportStyleResolver);
+    visitor->trace(m_features);
+    visitor->trace(m_siblingRuleSet);
+    visitor->trace(m_uncommonAttributeRuleSet);
+    visitor->trace(m_watchedSelectorsRules);
+    visitor->trace(m_treeBoundaryCrossingRules);
+    visitor->trace(m_styleSharingLists);
+    visitor->trace(m_pendingStyleSheets);
+    visitor->trace(m_document);
+#endif
+}
+
+} // namespace blink