Home | History | Annotate | Download | only in resolver
      1 /*
      2  * Copyright (C) 1999 Lars Knoll (knoll (at) kde.org)
      3  *           (C) 2004-2005 Allan Sandfeld Jensen (kde (at) carewolf.com)
      4  * Copyright (C) 2006, 2007 Nicholas Shanks (webkit (at) nickshanks.com)
      5  * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.
      6  * Copyright (C) 2007 Alexey Proskuryakov <ap (at) webkit.org>
      7  * Copyright (C) 2007, 2008 Eric Seidel <eric (at) webkit.org>
      8  * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
      9  * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
     10  * Copyright (C) Research In Motion Limited 2011. All rights reserved.
     11  * Copyright (C) 2012 Google Inc. All rights reserved.
     12  *
     13  * This library is free software; you can redistribute it and/or
     14  * modify it under the terms of the GNU Library General Public
     15  * License as published by the Free Software Foundation; either
     16  * version 2 of the License, or (at your option) any later version.
     17  *
     18  * This library is distributed in the hope that it will be useful,
     19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     21  * Library General Public License for more details.
     22  *
     23  * You should have received a copy of the GNU Library General Public License
     24  * along with this library; see the file COPYING.LIB.  If not, write to
     25  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     26  * Boston, MA 02110-1301, USA.
     27  */
     28 
     29 #include "config.h"
     30 #include "core/css/resolver/StyleResolver.h"
     31 
     32 #include "core/CSSPropertyNames.h"
     33 #include "core/HTMLNames.h"
     34 #include "core/MediaTypeNames.h"
     35 #include "core/StylePropertyShorthand.h"
     36 #include "core/animation/ActiveAnimations.h"
     37 #include "core/animation/Animation.h"
     38 #include "core/animation/AnimationTimeline.h"
     39 #include "core/animation/StyleInterpolation.h"
     40 #include "core/animation/animatable/AnimatableValue.h"
     41 #include "core/animation/css/CSSAnimatableValueFactory.h"
     42 #include "core/animation/css/CSSAnimations.h"
     43 #include "core/css/CSSCalculationValue.h"
     44 #include "core/css/CSSDefaultStyleSheets.h"
     45 #include "core/css/CSSFontSelector.h"
     46 #include "core/css/CSSKeyframeRule.h"
     47 #include "core/css/CSSKeyframesRule.h"
     48 #include "core/css/CSSReflectValue.h"
     49 #include "core/css/CSSRuleList.h"
     50 #include "core/css/CSSSelector.h"
     51 #include "core/css/CSSStyleRule.h"
     52 #include "core/css/CSSValueList.h"
     53 #include "core/css/CSSValuePool.h"
     54 #include "core/css/ElementRuleCollector.h"
     55 #include "core/css/FontFace.h"
     56 #include "core/css/MediaQueryEvaluator.h"
     57 #include "core/css/PageRuleCollector.h"
     58 #include "core/css/StylePropertySet.h"
     59 #include "core/css/StyleRuleImport.h"
     60 #include "core/css/StyleSheetContents.h"
     61 #include "core/css/resolver/AnimatedStyleBuilder.h"
     62 #include "core/css/resolver/MatchResult.h"
     63 #include "core/css/resolver/MediaQueryResult.h"
     64 #include "core/css/resolver/SharedStyleFinder.h"
     65 #include "core/css/resolver/StyleAdjuster.h"
     66 #include "core/css/resolver/StyleResolverParentScope.h"
     67 #include "core/css/resolver/StyleResolverState.h"
     68 #include "core/css/resolver/StyleResolverStats.h"
     69 #include "core/css/resolver/ViewportStyleResolver.h"
     70 #include "core/dom/CSSSelectorWatch.h"
     71 #include "core/dom/NodeRenderStyle.h"
     72 #include "core/dom/StyleEngine.h"
     73 #include "core/dom/Text.h"
     74 #include "core/dom/shadow/ElementShadow.h"
     75 #include "core/dom/shadow/ShadowRoot.h"
     76 #include "core/frame/FrameView.h"
     77 #include "core/frame/LocalFrame.h"
     78 #include "core/html/HTMLIFrameElement.h"
     79 #include "core/inspector/InspectorInstrumentation.h"
     80 #include "core/rendering/RenderView.h"
     81 #include "core/rendering/style/KeyframeList.h"
     82 #include "core/svg/SVGDocumentExtensions.h"
     83 #include "core/svg/SVGElement.h"
     84 #include "core/svg/SVGFontFaceElement.h"
     85 #include "platform/RuntimeEnabledFeatures.h"
     86 #include "wtf/StdLibExtras.h"
     87 
     88 namespace {
     89 
     90 using namespace blink;
     91 
     92 void setAnimationUpdateIfNeeded(StyleResolverState& state, Element& element)
     93 {
     94     // If any changes to CSS Animations were detected, stash the update away for application after the
     95     // render object is updated if we're in the appropriate scope.
     96     if (state.animationUpdate())
     97         element.ensureActiveAnimations().cssAnimations().setPendingUpdate(state.takeAnimationUpdate());
     98 }
     99 
    100 } // namespace
    101 
    102 namespace blink {
    103 
    104 using namespace HTMLNames;
    105 
    106 RenderStyle* StyleResolver::s_styleNotYetAvailable;
    107 
    108 static StylePropertySet* leftToRightDeclaration()
    109 {
    110     DEFINE_STATIC_REF_WILL_BE_PERSISTENT(MutableStylePropertySet, leftToRightDecl, (MutableStylePropertySet::create()));
    111     if (leftToRightDecl->isEmpty())
    112         leftToRightDecl->setProperty(CSSPropertyDirection, CSSValueLtr);
    113     return leftToRightDecl;
    114 }
    115 
    116 static StylePropertySet* rightToLeftDeclaration()
    117 {
    118     DEFINE_STATIC_REF_WILL_BE_PERSISTENT(MutableStylePropertySet, rightToLeftDecl, (MutableStylePropertySet::create()));
    119     if (rightToLeftDecl->isEmpty())
    120         rightToLeftDecl->setProperty(CSSPropertyDirection, CSSValueRtl);
    121     return rightToLeftDecl;
    122 }
    123 
    124 static void addFontFaceRule(Document* document, CSSFontSelector* cssFontSelector, const StyleRuleFontFace* fontFaceRule)
    125 {
    126     RefPtrWillBeRawPtr<FontFace> fontFace = FontFace::create(document, fontFaceRule);
    127     if (fontFace)
    128         cssFontSelector->fontFaceCache()->add(cssFontSelector, fontFaceRule, fontFace);
    129 }
    130 
    131 StyleResolver::StyleResolver(Document& document)
    132     : m_document(document)
    133     , m_viewportStyleResolver(ViewportStyleResolver::create(&document))
    134     , m_needCollectFeatures(false)
    135     , m_printMediaType(false)
    136     , m_styleResourceLoader(document.fetcher())
    137     , m_styleSharingDepth(0)
    138     , m_styleResolverStatsSequence(0)
    139     , m_accessCount(0)
    140 {
    141     FrameView* view = document.view();
    142     if (view) {
    143         m_medium = adoptPtr(new MediaQueryEvaluator(&view->frame()));
    144         m_printMediaType = equalIgnoringCase(view->mediaType(), MediaTypeNames::print);
    145     } else {
    146         m_medium = adoptPtr(new MediaQueryEvaluator("all"));
    147     }
    148 
    149     initWatchedSelectorRules(CSSSelectorWatch::from(document).watchedCallbackSelectors());
    150 
    151 #if ENABLE(SVG_FONTS)
    152     if (document.svgExtensions()) {
    153         const WillBeHeapHashSet<RawPtrWillBeMember<SVGFontFaceElement> >& svgFontFaceElements = document.svgExtensions()->svgFontFaceElements();
    154         WillBeHeapHashSet<RawPtrWillBeMember<SVGFontFaceElement> >::const_iterator end = svgFontFaceElements.end();
    155         for (WillBeHeapHashSet<RawPtrWillBeMember<SVGFontFaceElement> >::const_iterator it = svgFontFaceElements.begin(); it != end; ++it)
    156             addFontFaceRule(&document, document.styleEngine()->fontSelector(), (*it)->fontFaceRule());
    157     }
    158 #endif
    159 }
    160 
    161 void StyleResolver::initWatchedSelectorRules(const WillBeHeapVector<RefPtrWillBeMember<StyleRule> >& watchedSelectors)
    162 {
    163     if (!watchedSelectors.size())
    164         return;
    165     m_watchedSelectorsRules = RuleSet::create();
    166     for (unsigned i = 0; i < watchedSelectors.size(); ++i)
    167         m_watchedSelectorsRules->addStyleRule(watchedSelectors[i].get(), RuleHasNoSpecialState);
    168 }
    169 
    170 void StyleResolver::lazyAppendAuthorStyleSheets(unsigned firstNew, const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& styleSheets)
    171 {
    172     unsigned size = styleSheets.size();
    173     for (unsigned i = firstNew; i < size; ++i)
    174         m_pendingStyleSheets.add(styleSheets[i].get());
    175 }
    176 
    177 void StyleResolver::removePendingAuthorStyleSheets(const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& styleSheets)
    178 {
    179     for (unsigned i = 0; i < styleSheets.size(); ++i)
    180         m_pendingStyleSheets.remove(styleSheets[i].get());
    181 }
    182 
    183 void StyleResolver::appendCSSStyleSheet(CSSStyleSheet* cssSheet)
    184 {
    185     ASSERT(cssSheet);
    186     ASSERT(!cssSheet->disabled());
    187     if (cssSheet->mediaQueries() && !m_medium->eval(cssSheet->mediaQueries(), &m_viewportDependentMediaQueryResults))
    188         return;
    189 
    190     TreeScope* treeScope = ScopedStyleResolver::treeScopeFor(document(), cssSheet);
    191     if (!treeScope)
    192         return;
    193 
    194     ScopedStyleResolver& resolver = treeScope->ensureScopedStyleResolver();
    195     document().styleEngine()->addScopedStyleResolver(&resolver);
    196     resolver.addRulesFromSheet(cssSheet, *m_medium, this);
    197 }
    198 
    199 void StyleResolver::appendPendingAuthorStyleSheets()
    200 {
    201     for (WillBeHeapListHashSet<RawPtrWillBeMember<CSSStyleSheet>, 16>::iterator it = m_pendingStyleSheets.begin(); it != m_pendingStyleSheets.end(); ++it)
    202         appendCSSStyleSheet(*it);
    203 
    204     m_pendingStyleSheets.clear();
    205     finishAppendAuthorStyleSheets();
    206 }
    207 
    208 void StyleResolver::appendAuthorStyleSheets(const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& styleSheets)
    209 {
    210     // This handles sheets added to the end of the stylesheet list only. In other cases the style resolver
    211     // needs to be reconstructed. To handle insertions too the rule order numbers would need to be updated.
    212     unsigned size = styleSheets.size();
    213     for (unsigned i = 0; i < size; ++i)
    214         appendCSSStyleSheet(styleSheets[i].get());
    215 }
    216 
    217 void StyleResolver::finishAppendAuthorStyleSheets()
    218 {
    219     collectFeatures();
    220 
    221     if (document().renderView() && document().renderView()->style())
    222         document().renderView()->style()->font().update(document().styleEngine()->fontSelector());
    223 
    224     collectViewportRules();
    225 
    226     document().styleEngine()->resetCSSFeatureFlags(m_features);
    227 }
    228 
    229 void StyleResolver::resetRuleFeatures()
    230 {
    231     // Need to recreate RuleFeatureSet.
    232     m_features.clear();
    233     m_siblingRuleSet.clear();
    234     m_uncommonAttributeRuleSet.clear();
    235     m_needCollectFeatures = true;
    236 }
    237 
    238 void StyleResolver::processScopedRules(const RuleSet& authorRules, CSSStyleSheet* parentStyleSheet, unsigned parentIndex, ContainerNode& scope)
    239 {
    240     const WillBeHeapVector<RawPtrWillBeMember<StyleRuleKeyframes> > keyframesRules = authorRules.keyframesRules();
    241     ScopedStyleResolver* resolver = &scope.treeScope().ensureScopedStyleResolver();
    242     document().styleEngine()->addScopedStyleResolver(resolver);
    243     for (unsigned i = 0; i < keyframesRules.size(); ++i)
    244         resolver->addKeyframeStyle(keyframesRules[i]);
    245 
    246     m_treeBoundaryCrossingRules.addTreeBoundaryCrossingRules(authorRules, parentStyleSheet, parentIndex, scope);
    247 
    248     // FIXME(BUG 72461): We don't add @font-face rules of scoped style sheets for the moment.
    249     if (scope.isDocumentNode()) {
    250         const WillBeHeapVector<RawPtrWillBeMember<StyleRuleFontFace> > fontFaceRules = authorRules.fontFaceRules();
    251         for (unsigned i = 0; i < fontFaceRules.size(); ++i)
    252             addFontFaceRule(m_document, document().styleEngine()->fontSelector(), fontFaceRules[i]);
    253         if (fontFaceRules.size())
    254             invalidateMatchedPropertiesCache();
    255     }
    256 }
    257 
    258 void StyleResolver::resetAuthorStyle(TreeScope& treeScope)
    259 {
    260     ScopedStyleResolver* resolver = treeScope.scopedStyleResolver();
    261     if (!resolver)
    262         return;
    263 
    264     m_treeBoundaryCrossingRules.reset(&treeScope.rootNode());
    265 
    266     resolver->resetAuthorStyle();
    267     resetRuleFeatures();
    268     if (treeScope.rootNode().isDocumentNode())
    269         return;
    270 
    271     // resolver is going to be freed below.
    272     document().styleEngine()->removeScopedStyleResolver(resolver);
    273     treeScope.clearScopedStyleResolver();
    274 }
    275 
    276 static PassOwnPtrWillBeRawPtr<RuleSet> makeRuleSet(const WillBeHeapVector<RuleFeature>& rules)
    277 {
    278     size_t size = rules.size();
    279     if (!size)
    280         return nullptr;
    281     OwnPtrWillBeRawPtr<RuleSet> ruleSet = RuleSet::create();
    282     for (size_t i = 0; i < size; ++i)
    283         ruleSet->addRule(rules[i].rule, rules[i].selectorIndex, rules[i].hasDocumentSecurityOrigin ? RuleHasDocumentSecurityOrigin : RuleHasNoSpecialState);
    284     return ruleSet.release();
    285 }
    286 
    287 void StyleResolver::collectFeatures()
    288 {
    289     m_features.clear();
    290     // Collect all ids and rules using sibling selectors (:first-child and similar)
    291     // in the current set of stylesheets. Style sharing code uses this information to reject
    292     // sharing candidates.
    293     CSSDefaultStyleSheets& defaultStyleSheets = CSSDefaultStyleSheets::instance();
    294     if (defaultStyleSheets.defaultStyle())
    295         m_features.add(defaultStyleSheets.defaultStyle()->features());
    296 
    297     if (document().isViewSource())
    298         m_features.add(defaultStyleSheets.defaultViewSourceStyle()->features());
    299 
    300     if (document().isTransitionDocument())
    301         m_features.add(defaultStyleSheets.defaultTransitionStyle()->features());
    302 
    303     if (m_watchedSelectorsRules)
    304         m_features.add(m_watchedSelectorsRules->features());
    305 
    306     m_treeBoundaryCrossingRules.collectFeaturesTo(m_features);
    307 
    308     document().styleEngine()->collectScopedStyleFeaturesTo(m_features);
    309 
    310     m_siblingRuleSet = makeRuleSet(m_features.siblingRules);
    311     m_uncommonAttributeRuleSet = makeRuleSet(m_features.uncommonAttributeRules);
    312     m_needCollectFeatures = false;
    313 }
    314 
    315 bool StyleResolver::hasRulesForId(const AtomicString& id) const
    316 {
    317     return m_features.hasSelectorForId(id);
    318 }
    319 
    320 void StyleResolver::addToStyleSharingList(Element& element)
    321 {
    322     // Never add elements to the style sharing list if we're not in a recalcStyle,
    323     // otherwise we could leave stale pointers in there.
    324     if (!document().inStyleRecalc())
    325         return;
    326     INCREMENT_STYLE_STATS_COUNTER(*this, sharedStyleCandidates);
    327     StyleSharingList& list = styleSharingList();
    328     if (list.size() >= styleSharingListSize)
    329         list.removeLast();
    330     list.prepend(&element);
    331 }
    332 
    333 StyleSharingList& StyleResolver::styleSharingList()
    334 {
    335     m_styleSharingLists.resize(styleSharingMaxDepth);
    336 
    337     // We never put things at depth 0 into the list since that's only the <html> element
    338     // and it has no siblings or cousins to share with.
    339     unsigned depth = std::max(std::min(m_styleSharingDepth, styleSharingMaxDepth), 1u) - 1u;
    340 
    341     if (!m_styleSharingLists[depth])
    342         m_styleSharingLists[depth] = adoptPtrWillBeNoop(new StyleSharingList);
    343     return *m_styleSharingLists[depth];
    344 }
    345 
    346 void StyleResolver::clearStyleSharingList()
    347 {
    348     m_styleSharingLists.resize(0);
    349 }
    350 
    351 void StyleResolver::pushParentElement(Element& parent)
    352 {
    353     const ContainerNode* parentsParent = parent.parentOrShadowHostElement();
    354 
    355     // We are not always invoked consistently. For example, script execution can cause us to enter
    356     // style recalc in the middle of tree building. We may also be invoked from somewhere within the tree.
    357     // Reset the stack in this case, or if we see a new root element.
    358     // Otherwise just push the new parent.
    359     if (!parentsParent || m_selectorFilter.parentStackIsEmpty())
    360         m_selectorFilter.setupParentStack(parent);
    361     else
    362         m_selectorFilter.pushParent(parent);
    363 }
    364 
    365 void StyleResolver::popParentElement(Element& parent)
    366 {
    367     // Note that we may get invoked for some random elements in some wacky cases during style resolve.
    368     // Pause maintaining the stack in this case.
    369     if (m_selectorFilter.parentStackIsConsistent(&parent))
    370         m_selectorFilter.popParent();
    371 }
    372 
    373 StyleResolver::~StyleResolver()
    374 {
    375 }
    376 
    377 void StyleResolver::matchAuthorRulesForShadowHost(Element* element, ElementRuleCollector& collector, bool includeEmptyRules, WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8>& resolvers, WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8>& resolversInShadowTree)
    378 {
    379     collector.clearMatchedRules();
    380     collector.matchedResult().ranges.lastAuthorRule = collector.matchedResult().matchedProperties.size() - 1;
    381 
    382     CascadeScope cascadeScope = 0;
    383     CascadeOrder cascadeOrder = 0;
    384 
    385     for (int j = resolversInShadowTree.size() - 1; j >= 0; --j)
    386         resolversInShadowTree.at(j)->collectMatchingAuthorRules(collector, includeEmptyRules, cascadeScope, cascadeOrder++);
    387 
    388     if (resolvers.isEmpty() || resolvers.first()->treeScope() != element->treeScope())
    389         ++cascadeScope;
    390     cascadeOrder += resolvers.size();
    391     for (unsigned i = 0; i < resolvers.size(); ++i)
    392         resolvers.at(i)->collectMatchingAuthorRules(collector, includeEmptyRules, cascadeScope++, --cascadeOrder);
    393 
    394     m_treeBoundaryCrossingRules.collectTreeBoundaryCrossingRules(element, collector, includeEmptyRules);
    395     collector.sortAndTransferMatchedRules();
    396 }
    397 
    398 void StyleResolver::matchAuthorRules(Element* element, ElementRuleCollector& collector, bool includeEmptyRules)
    399 {
    400     collector.clearMatchedRules();
    401     collector.matchedResult().ranges.lastAuthorRule = collector.matchedResult().matchedProperties.size() - 1;
    402 
    403     if (document().styleEngine()->hasOnlyScopedResolverForDocument()) {
    404         document().scopedStyleResolver()->collectMatchingAuthorRules(collector, includeEmptyRules, ignoreCascadeScope);
    405         m_treeBoundaryCrossingRules.collectTreeBoundaryCrossingRules(element, collector, includeEmptyRules);
    406         collector.sortAndTransferMatchedRules();
    407         return;
    408     }
    409 
    410     WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8> resolvers;
    411     resolveScopedStyles(element, resolvers);
    412 
    413     WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8> resolversInShadowTree;
    414     collectScopedResolversForHostedShadowTrees(element, resolversInShadowTree);
    415     if (!resolversInShadowTree.isEmpty()) {
    416         matchAuthorRulesForShadowHost(element, collector, includeEmptyRules, resolvers, resolversInShadowTree);
    417         return;
    418     }
    419 
    420     if (resolvers.isEmpty())
    421         return;
    422 
    423     CascadeScope cascadeScope = 0;
    424     CascadeOrder cascadeOrder = resolvers.size();
    425     for (unsigned i = 0; i < resolvers.size(); ++i, --cascadeOrder) {
    426         ScopedStyleResolver* resolver = resolvers.at(i);
    427         // FIXME: Need to clarify how to treat style scoped.
    428         resolver->collectMatchingAuthorRules(collector, includeEmptyRules, cascadeScope++, resolver->treeScope() == element->treeScope() && resolver->treeScope().rootNode().isShadowRoot() ? 0 : cascadeOrder);
    429     }
    430 
    431     m_treeBoundaryCrossingRules.collectTreeBoundaryCrossingRules(element, collector, includeEmptyRules);
    432     collector.sortAndTransferMatchedRules();
    433 }
    434 
    435 void StyleResolver::matchUARules(ElementRuleCollector& collector)
    436 {
    437     collector.setMatchingUARules(true);
    438 
    439     CSSDefaultStyleSheets& defaultStyleSheets = CSSDefaultStyleSheets::instance();
    440     RuleSet* userAgentStyleSheet = m_printMediaType ? defaultStyleSheets.defaultPrintStyle() : defaultStyleSheets.defaultStyle();
    441     matchUARules(collector, userAgentStyleSheet);
    442 
    443     // In quirks mode, we match rules from the quirks user agent sheet.
    444     if (document().inQuirksMode())
    445         matchUARules(collector, defaultStyleSheets.defaultQuirksStyle());
    446 
    447     // If document uses view source styles (in view source mode or in xml viewer mode), then we match rules from the view source style sheet.
    448     if (document().isViewSource())
    449         matchUARules(collector, defaultStyleSheets.defaultViewSourceStyle());
    450 
    451     if (document().isTransitionDocument())
    452         matchUARules(collector, defaultStyleSheets.defaultTransitionStyle());
    453 
    454     collector.setMatchingUARules(false);
    455 }
    456 
    457 void StyleResolver::matchUARules(ElementRuleCollector& collector, RuleSet* rules)
    458 {
    459     collector.clearMatchedRules();
    460     collector.matchedResult().ranges.lastUARule = collector.matchedResult().matchedProperties.size() - 1;
    461 
    462     RuleRange ruleRange = collector.matchedResult().ranges.UARuleRange();
    463     collector.collectMatchingRules(MatchRequest(rules), ruleRange);
    464 
    465     collector.sortAndTransferMatchedRules();
    466 }
    467 
    468 void StyleResolver::matchAllRules(StyleResolverState& state, ElementRuleCollector& collector, bool includeSMILProperties)
    469 {
    470     matchUARules(collector);
    471 
    472     // Now check author rules, beginning first with presentational attributes mapped from HTML.
    473     if (state.element()->isStyledElement()) {
    474         collector.addElementStyleProperties(state.element()->presentationAttributeStyle());
    475 
    476         // Now we check additional mapped declarations.
    477         // Tables and table cells share an additional mapped rule that must be applied
    478         // after all attributes, since their mapped style depends on the values of multiple attributes.
    479         collector.addElementStyleProperties(state.element()->additionalPresentationAttributeStyle());
    480 
    481         if (state.element()->isHTMLElement()) {
    482             bool isAuto;
    483             TextDirection textDirection = toHTMLElement(state.element())->directionalityIfhasDirAutoAttribute(isAuto);
    484             if (isAuto)
    485                 collector.matchedResult().addMatchedProperties(textDirection == LTR ? leftToRightDeclaration() : rightToLeftDeclaration());
    486         }
    487     }
    488 
    489     matchAuthorRules(state.element(), collector, false);
    490 
    491     if (state.element()->isStyledElement()) {
    492         if (state.element()->inlineStyle()) {
    493             // Inline style is immutable as long as there is no CSSOM wrapper.
    494             bool isInlineStyleCacheable = !state.element()->inlineStyle()->isMutable();
    495             collector.addElementStyleProperties(state.element()->inlineStyle(), isInlineStyleCacheable);
    496         }
    497 
    498         // Now check SMIL animation override style.
    499         if (includeSMILProperties && state.element()->isSVGElement())
    500             collector.addElementStyleProperties(toSVGElement(state.element())->animatedSMILStyleProperties(), false /* isCacheable */);
    501     }
    502 }
    503 
    504 PassRefPtr<RenderStyle> StyleResolver::styleForDocument(Document& document)
    505 {
    506     const LocalFrame* frame = document.frame();
    507 
    508     RefPtr<RenderStyle> documentStyle = RenderStyle::create();
    509     documentStyle->setDisplay(BLOCK);
    510     documentStyle->setRTLOrdering(document.visuallyOrdered() ? VisualOrder : LogicalOrder);
    511     documentStyle->setZoom(frame && !document.printing() ? frame->pageZoomFactor() : 1);
    512     documentStyle->setLocale(document.contentLanguage());
    513     documentStyle->setZIndex(0);
    514     documentStyle->setUserModify(document.inDesignMode() ? READ_WRITE : READ_ONLY);
    515 
    516     document.setupFontBuilder(documentStyle.get());
    517 
    518     return documentStyle.release();
    519 }
    520 
    521 static inline void resetDirectionAndWritingModeOnDocument(Document& document)
    522 {
    523     document.setDirectionSetOnDocumentElement(false);
    524     document.setWritingModeSetOnDocumentElement(false);
    525 }
    526 
    527 static void addContentAttrValuesToFeatures(const Vector<AtomicString>& contentAttrValues, RuleFeatureSet& features)
    528 {
    529     for (size_t i = 0; i < contentAttrValues.size(); ++i)
    530         features.addContentAttr(contentAttrValues[i]);
    531 }
    532 
    533 void StyleResolver::adjustRenderStyle(StyleResolverState& state, Element* element)
    534 {
    535     StyleAdjuster adjuster(document().inQuirksMode());
    536     adjuster.adjustRenderStyle(state.style(), state.parentStyle(), element, state.cachedUAStyle());
    537 }
    538 
    539 // Start loading resources referenced by this style.
    540 void StyleResolver::loadPendingResources(StyleResolverState& state)
    541 {
    542     m_styleResourceLoader.loadPendingResources(state.style(), state.elementStyleResources());
    543     document().styleEngine()->fontSelector()->fontLoader()->loadPendingFonts();
    544 }
    545 
    546 PassRefPtr<RenderStyle> StyleResolver::styleForElement(Element* element, RenderStyle* defaultParent, StyleSharingBehavior sharingBehavior,
    547     RuleMatchingBehavior matchingBehavior)
    548 {
    549     ASSERT(document().frame());
    550     ASSERT(document().settings());
    551     ASSERT(!hasPendingAuthorStyleSheets());
    552     ASSERT(!m_needCollectFeatures);
    553 
    554     // Once an element has a renderer, we don't try to destroy it, since otherwise the renderer
    555     // will vanish if a style recalc happens during loading.
    556     if (sharingBehavior == AllowStyleSharing && !document().isRenderingReady() && !element->renderer()) {
    557         if (!s_styleNotYetAvailable) {
    558             s_styleNotYetAvailable = RenderStyle::create().leakRef();
    559             s_styleNotYetAvailable->setDisplay(NONE);
    560             s_styleNotYetAvailable->font().update(document().styleEngine()->fontSelector());
    561         }
    562 
    563         document().setHasNodesWithPlaceholderStyle();
    564         return s_styleNotYetAvailable;
    565     }
    566 
    567     didAccess();
    568 
    569     StyleResolverParentScope::ensureParentStackIsPushed();
    570 
    571     if (element == document().documentElement())
    572         resetDirectionAndWritingModeOnDocument(document());
    573     StyleResolverState state(document(), element, defaultParent);
    574 
    575     if (sharingBehavior == AllowStyleSharing && state.parentStyle()) {
    576         SharedStyleFinder styleFinder(state.elementContext(), m_features, m_siblingRuleSet.get(), m_uncommonAttributeRuleSet.get(), *this);
    577         if (RefPtr<RenderStyle> sharedStyle = styleFinder.findSharedStyle())
    578             return sharedStyle.release();
    579     }
    580 
    581     if (state.parentStyle()) {
    582         state.setStyle(RenderStyle::create());
    583         state.style()->inheritFrom(state.parentStyle(), isAtShadowBoundary(element) ? RenderStyle::AtShadowBoundary : RenderStyle::NotAtShadowBoundary);
    584     } else {
    585         state.setStyle(defaultStyleForElement());
    586         state.setParentStyle(RenderStyle::clone(state.style()));
    587     }
    588     // contenteditable attribute (implemented by -webkit-user-modify) should
    589     // be propagated from shadow host to distributed node.
    590     if (state.distributedToInsertionPoint()) {
    591         if (Element* parent = element->parentElement()) {
    592             if (RenderStyle* styleOfShadowHost = parent->renderStyle())
    593                 state.style()->setUserModify(styleOfShadowHost->userModify());
    594         }
    595     }
    596 
    597     state.fontBuilder().initForStyleResolve(state.document(), state.style());
    598 
    599     if (element->isLink()) {
    600         state.style()->setIsLink(true);
    601         EInsideLink linkState = state.elementLinkState();
    602         if (linkState != NotInsideLink) {
    603             bool forceVisited = InspectorInstrumentation::forcePseudoState(element, CSSSelector::PseudoVisited);
    604             if (forceVisited)
    605                 linkState = InsideVisitedLink;
    606         }
    607         state.style()->setInsideLink(linkState);
    608     }
    609 
    610     bool needsCollection = false;
    611     CSSDefaultStyleSheets::instance().ensureDefaultStyleSheetsForElement(element, needsCollection);
    612     if (needsCollection)
    613         collectFeatures();
    614 
    615     {
    616         ElementRuleCollector collector(state.elementContext(), m_selectorFilter, state.style());
    617 
    618         matchAllRules(state, collector, matchingBehavior != MatchAllRulesExcludingSMIL);
    619 
    620         applyMatchedProperties(state, collector.matchedResult());
    621         applyCallbackSelectors(state);
    622 
    623         addContentAttrValuesToFeatures(state.contentAttrValues(), m_features);
    624     }
    625 
    626     // Cache our original display.
    627     state.style()->setOriginalDisplay(state.style()->display());
    628 
    629     adjustRenderStyle(state, element);
    630 
    631     // FIXME: The CSSWG wants to specify that the effects of animations are applied before
    632     // important rules, but this currently happens here as we require adjustment to have happened
    633     // before deciding which properties to transition.
    634     if (applyAnimatedProperties(state, element))
    635         adjustRenderStyle(state, element);
    636 
    637     if (isHTMLBodyElement(*element))
    638         document().textLinkColors().setTextColor(state.style()->color());
    639 
    640     setAnimationUpdateIfNeeded(state, *element);
    641 
    642     if (state.style()->hasViewportUnits())
    643         document().setHasViewportUnits();
    644 
    645     // Now return the style.
    646     return state.takeStyle();
    647 }
    648 
    649 PassRefPtr<RenderStyle> StyleResolver::styleForKeyframe(Element& element, const RenderStyle& elementStyle, RenderStyle* parentStyle, const StyleKeyframe* keyframe, const AtomicString& animationName)
    650 {
    651     ASSERT(document().frame());
    652     ASSERT(document().settings());
    653     ASSERT(!hasPendingAuthorStyleSheets());
    654 
    655     if (&element == document().documentElement())
    656         resetDirectionAndWritingModeOnDocument(document());
    657     StyleResolverState state(document(), &element, parentStyle);
    658 
    659     MatchResult result;
    660     result.addMatchedProperties(&keyframe->properties());
    661 
    662     ASSERT(!state.style());
    663 
    664     // Create the style
    665     state.setStyle(RenderStyle::clone(&elementStyle));
    666     state.setLineHeightValue(0);
    667 
    668     state.fontBuilder().initForStyleResolve(state.document(), state.style());
    669 
    670     // We don't need to bother with !important. Since there is only ever one
    671     // decl, there's nothing to override. So just add the first properties.
    672     // We also don't need to bother with animation properties since the only
    673     // relevant one is animation-timing-function and we special-case that in
    674     // CSSAnimations.cpp
    675     bool inheritedOnly = false;
    676     applyMatchedProperties<HighPriorityProperties>(state, result, false, 0, result.matchedProperties.size() - 1, inheritedOnly);
    677 
    678     // If our font got dirtied, go ahead and update it now.
    679     updateFont(state);
    680 
    681     // Line-height is set when we are sure we decided on the font-size
    682     if (state.lineHeightValue())
    683         StyleBuilder::applyProperty(CSSPropertyLineHeight, state, state.lineHeightValue());
    684 
    685     // Now do rest of the properties.
    686     applyMatchedProperties<LowPriorityProperties>(state, result, false, 0, result.matchedProperties.size() - 1, inheritedOnly);
    687 
    688     loadPendingResources(state);
    689 
    690     didAccess();
    691 
    692     return state.takeStyle();
    693 }
    694 
    695 // This function is used by the WebAnimations JavaScript API method animate().
    696 // FIXME: Remove this when animate() switches away from resolution-dependent parsing.
    697 PassRefPtrWillBeRawPtr<AnimatableValue> StyleResolver::createAnimatableValueSnapshot(Element& element, CSSPropertyID property, CSSValue& value)
    698 {
    699     RefPtr<RenderStyle> style;
    700     if (element.renderStyle())
    701         style = RenderStyle::clone(element.renderStyle());
    702     else
    703         style = RenderStyle::create();
    704     StyleResolverState state(element.document(), &element);
    705     state.setStyle(style);
    706     state.fontBuilder().initForStyleResolve(state.document(), state.style());
    707     return createAnimatableValueSnapshot(state, property, value);
    708 }
    709 
    710 PassRefPtrWillBeRawPtr<AnimatableValue> StyleResolver::createAnimatableValueSnapshot(StyleResolverState& state, CSSPropertyID property, CSSValue& value)
    711 {
    712     StyleBuilder::applyProperty(property, state, &value);
    713     return CSSAnimatableValueFactory::create(property, *state.style());
    714 }
    715 
    716 PassRefPtrWillBeRawPtr<PseudoElement> StyleResolver::createPseudoElementIfNeeded(Element& parent, PseudoId pseudoId)
    717 {
    718     RenderObject* parentRenderer = parent.renderer();
    719     if (!parentRenderer)
    720         return nullptr;
    721 
    722     if (pseudoId < FIRST_INTERNAL_PSEUDOID && !parentRenderer->style()->hasPseudoStyle(pseudoId))
    723         return nullptr;
    724 
    725     if (pseudoId == BACKDROP && !parent.isInTopLayer())
    726         return nullptr;
    727 
    728     if (!parentRenderer->canHaveGeneratedChildren())
    729         return nullptr;
    730 
    731     RenderStyle* parentStyle = parentRenderer->style();
    732     if (RenderStyle* cachedStyle = parentStyle->getCachedPseudoStyle(pseudoId)) {
    733         if (!pseudoElementRendererIsNeeded(cachedStyle))
    734             return nullptr;
    735         return PseudoElement::create(&parent, pseudoId);
    736     }
    737 
    738     StyleResolverState state(document(), &parent, parentStyle);
    739     if (!pseudoStyleForElementInternal(parent, pseudoId, parentStyle, state))
    740         return nullptr;
    741     RefPtr<RenderStyle> style = state.takeStyle();
    742     ASSERT(style);
    743     parentStyle->addCachedPseudoStyle(style);
    744 
    745     if (!pseudoElementRendererIsNeeded(style.get()))
    746         return nullptr;
    747 
    748     RefPtrWillBeRawPtr<PseudoElement> pseudo = PseudoElement::create(&parent, pseudoId);
    749 
    750     setAnimationUpdateIfNeeded(state, *pseudo);
    751     if (ActiveAnimations* activeAnimations = pseudo->activeAnimations())
    752         activeAnimations->cssAnimations().maybeApplyPendingUpdate(pseudo.get());
    753     return pseudo.release();
    754 }
    755 
    756 bool StyleResolver::pseudoStyleForElementInternal(Element& element, const PseudoStyleRequest& pseudoStyleRequest, RenderStyle* parentStyle, StyleResolverState& state)
    757 {
    758     ASSERT(document().frame());
    759     ASSERT(document().settings());
    760     ASSERT(pseudoStyleRequest.pseudoId != FIRST_LINE_INHERITED);
    761 
    762     StyleResolverParentScope::ensureParentStackIsPushed();
    763 
    764     if (pseudoStyleRequest.allowsInheritance(state.parentStyle())) {
    765         state.setStyle(RenderStyle::create());
    766         state.style()->inheritFrom(state.parentStyle());
    767     } else {
    768         state.setStyle(defaultStyleForElement());
    769         state.setParentStyle(RenderStyle::clone(state.style()));
    770     }
    771 
    772     state.style()->setStyleType(pseudoStyleRequest.pseudoId);
    773     state.fontBuilder().initForStyleResolve(state.document(), state.style());
    774 
    775     // Since we don't use pseudo-elements in any of our quirk/print
    776     // user agent rules, don't waste time walking those rules.
    777 
    778     {
    779         // Check UA, user and author rules.
    780         ElementRuleCollector collector(state.elementContext(), m_selectorFilter, state.style());
    781         collector.setPseudoStyleRequest(pseudoStyleRequest);
    782 
    783         matchUARules(collector);
    784         matchAuthorRules(state.element(), collector, false);
    785 
    786         if (collector.matchedResult().matchedProperties.isEmpty())
    787             return false;
    788 
    789         applyMatchedProperties(state, collector.matchedResult());
    790         applyCallbackSelectors(state);
    791 
    792         addContentAttrValuesToFeatures(state.contentAttrValues(), m_features);
    793     }
    794 
    795     // Cache our original display.
    796     state.style()->setOriginalDisplay(state.style()->display());
    797 
    798     // FIXME: Passing 0 as the Element* introduces a lot of complexity
    799     // in the adjustRenderStyle code.
    800     adjustRenderStyle(state, 0);
    801 
    802     // FIXME: The CSSWG wants to specify that the effects of animations are applied before
    803     // important rules, but this currently happens here as we require adjustment to have happened
    804     // before deciding which properties to transition.
    805     if (applyAnimatedProperties(state, element.pseudoElement(pseudoStyleRequest.pseudoId)))
    806         adjustRenderStyle(state, 0);
    807 
    808     didAccess();
    809 
    810     if (state.style()->hasViewportUnits())
    811         document().setHasViewportUnits();
    812 
    813     return true;
    814 }
    815 
    816 PassRefPtr<RenderStyle> StyleResolver::pseudoStyleForElement(Element* element, const PseudoStyleRequest& pseudoStyleRequest, RenderStyle* parentStyle)
    817 {
    818     ASSERT(parentStyle);
    819     if (!element)
    820         return nullptr;
    821 
    822     StyleResolverState state(document(), element, parentStyle);
    823     if (!pseudoStyleForElementInternal(*element, pseudoStyleRequest, parentStyle, state)) {
    824         if (pseudoStyleRequest.type == PseudoStyleRequest::ForRenderer)
    825             return nullptr;
    826         return state.takeStyle();
    827     }
    828 
    829     if (PseudoElement* pseudoElement = element->pseudoElement(pseudoStyleRequest.pseudoId))
    830         setAnimationUpdateIfNeeded(state, *pseudoElement);
    831 
    832     // Now return the style.
    833     return state.takeStyle();
    834 }
    835 
    836 PassRefPtr<RenderStyle> StyleResolver::styleForPage(int pageIndex)
    837 {
    838     ASSERT(!hasPendingAuthorStyleSheets());
    839     resetDirectionAndWritingModeOnDocument(document());
    840     StyleResolverState state(document(), document().documentElement()); // m_rootElementStyle will be set to the document style.
    841 
    842     state.setStyle(RenderStyle::create());
    843     const RenderStyle* rootElementStyle = state.rootElementStyle() ? state.rootElementStyle() : document().renderStyle();
    844     ASSERT(rootElementStyle);
    845     state.style()->inheritFrom(rootElementStyle);
    846 
    847     state.fontBuilder().initForStyleResolve(state.document(), state.style());
    848 
    849     PageRuleCollector collector(rootElementStyle, pageIndex);
    850 
    851     collector.matchPageRules(CSSDefaultStyleSheets::instance().defaultPrintStyle());
    852 
    853     if (ScopedStyleResolver* scopedResolver = document().scopedStyleResolver())
    854         scopedResolver->matchPageRules(collector);
    855 
    856     state.setLineHeightValue(0);
    857     bool inheritedOnly = false;
    858 
    859     MatchResult& result = collector.matchedResult();
    860     applyMatchedProperties<HighPriorityProperties>(state, result, false, 0, result.matchedProperties.size() - 1, inheritedOnly);
    861 
    862     // If our font got dirtied, go ahead and update it now.
    863     updateFont(state);
    864 
    865     // Line-height is set when we are sure we decided on the font-size.
    866     if (state.lineHeightValue())
    867         StyleBuilder::applyProperty(CSSPropertyLineHeight, state, state.lineHeightValue());
    868 
    869     applyMatchedProperties<LowPriorityProperties>(state, result, false, 0, result.matchedProperties.size() - 1, inheritedOnly);
    870 
    871     addContentAttrValuesToFeatures(state.contentAttrValues(), m_features);
    872 
    873     loadPendingResources(state);
    874 
    875     didAccess();
    876 
    877     // Now return the style.
    878     return state.takeStyle();
    879 }
    880 
    881 void StyleResolver::collectViewportRules()
    882 {
    883     CSSDefaultStyleSheets& defaultStyleSheets = CSSDefaultStyleSheets::instance();
    884     viewportStyleResolver()->collectViewportRules(defaultStyleSheets.defaultStyle(), ViewportStyleResolver::UserAgentOrigin);
    885 
    886     if (!InspectorInstrumentation::applyViewportStyleOverride(&document(), this))
    887         viewportStyleResolver()->collectViewportRules(defaultStyleSheets.defaultViewportStyle(), ViewportStyleResolver::UserAgentOrigin);
    888 
    889     if (document().isMobileDocument())
    890         viewportStyleResolver()->collectViewportRules(defaultStyleSheets.defaultXHTMLMobileProfileStyle(), ViewportStyleResolver::UserAgentOrigin);
    891 
    892     if (ScopedStyleResolver* scopedResolver = document().scopedStyleResolver())
    893         scopedResolver->collectViewportRulesTo(this);
    894 
    895     viewportStyleResolver()->resolve();
    896 }
    897 
    898 PassRefPtr<RenderStyle> StyleResolver::defaultStyleForElement()
    899 {
    900     StyleResolverState state(document(), 0);
    901     state.setStyle(RenderStyle::create());
    902     state.fontBuilder().initForStyleResolve(document(), state.style());
    903     state.style()->setLineHeight(RenderStyle::initialLineHeight());
    904     state.setLineHeightValue(0);
    905     state.fontBuilder().setInitial(state.style()->effectiveZoom());
    906     state.style()->font().update(document().styleEngine()->fontSelector());
    907     return state.takeStyle();
    908 }
    909 
    910 PassRefPtr<RenderStyle> StyleResolver::styleForText(Text* textNode)
    911 {
    912     ASSERT(textNode);
    913 
    914     Node* parentNode = NodeRenderingTraversal::parent(textNode);
    915     if (!parentNode || !parentNode->renderStyle())
    916         return defaultStyleForElement();
    917     return parentNode->renderStyle();
    918 }
    919 
    920 void StyleResolver::updateFont(StyleResolverState& state)
    921 {
    922     state.fontBuilder().createFont(document().styleEngine()->fontSelector(), state.parentStyle(), state.style());
    923 }
    924 
    925 PassRefPtrWillBeRawPtr<StyleRuleList> StyleResolver::styleRulesForElement(Element* element, unsigned rulesToInclude)
    926 {
    927     ASSERT(element);
    928     StyleResolverState state(document(), element);
    929     ElementRuleCollector collector(state.elementContext(), m_selectorFilter, state.style());
    930     collector.setMode(SelectorChecker::CollectingStyleRules);
    931     collectPseudoRulesForElement(element, collector, NOPSEUDO, rulesToInclude);
    932     return collector.matchedStyleRuleList();
    933 }
    934 
    935 PassRefPtrWillBeRawPtr<CSSRuleList> StyleResolver::pseudoCSSRulesForElement(Element* element, PseudoId pseudoId, unsigned rulesToInclude)
    936 {
    937     ASSERT(element);
    938     StyleResolverState state(document(), element);
    939     ElementRuleCollector collector(state.elementContext(), m_selectorFilter, state.style());
    940     collector.setMode(SelectorChecker::CollectingCSSRules);
    941     collectPseudoRulesForElement(element, collector, pseudoId, rulesToInclude);
    942     return collector.matchedCSSRuleList();
    943 }
    944 
    945 PassRefPtrWillBeRawPtr<CSSRuleList> StyleResolver::cssRulesForElement(Element* element, unsigned rulesToInclude)
    946 {
    947     return pseudoCSSRulesForElement(element, NOPSEUDO, rulesToInclude);
    948 }
    949 
    950 void StyleResolver::collectPseudoRulesForElement(Element* element, ElementRuleCollector& collector, PseudoId pseudoId, unsigned rulesToInclude)
    951 {
    952     collector.setPseudoStyleRequest(PseudoStyleRequest(pseudoId));
    953 
    954     if (rulesToInclude & UAAndUserCSSRules)
    955         matchUARules(collector);
    956 
    957     if (rulesToInclude & AuthorCSSRules) {
    958         collector.setSameOriginOnly(!(rulesToInclude & CrossOriginCSSRules));
    959         matchAuthorRules(element, collector, rulesToInclude & EmptyCSSRules);
    960     }
    961 }
    962 
    963 // -------------------------------------------------------------------------------------
    964 // this is mostly boring stuff on how to apply a certain rule to the renderstyle...
    965 
    966 bool StyleResolver::applyAnimatedProperties(StyleResolverState& state, const Element* animatingElement)
    967 {
    968     Element* element = state.element();
    969     ASSERT(element);
    970 
    971     // The animating element may be this element, or its pseudo element. It is
    972     // null when calculating the style for a potential pseudo element that has
    973     // yet to be created.
    974     ASSERT(animatingElement == element || !animatingElement || animatingElement->parentOrShadowHostElement() == element);
    975 
    976     if (!(animatingElement && animatingElement->hasActiveAnimations())
    977         && !state.style()->transitions() && !state.style()->animations())
    978         return false;
    979 
    980     state.setAnimationUpdate(CSSAnimations::calculateUpdate(animatingElement, *element, *state.style(), state.parentStyle(), this));
    981     if (!state.animationUpdate())
    982         return false;
    983 
    984     const WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> >& activeInterpolationsForAnimations = state.animationUpdate()->activeInterpolationsForAnimations();
    985     const WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> >& activeInterpolationsForTransitions = state.animationUpdate()->activeInterpolationsForTransitions();
    986     applyAnimatedProperties<HighPriorityProperties>(state, activeInterpolationsForAnimations);
    987     applyAnimatedProperties<HighPriorityProperties>(state, activeInterpolationsForTransitions);
    988 
    989     updateFont(state);
    990 
    991     applyAnimatedProperties<LowPriorityProperties>(state, activeInterpolationsForAnimations);
    992     applyAnimatedProperties<LowPriorityProperties>(state, activeInterpolationsForTransitions);
    993 
    994     // Start loading resources used by animations.
    995     loadPendingResources(state);
    996 
    997     ASSERT(!state.fontBuilder().fontDirty());
    998 
    999     return true;
   1000 }
   1001 
   1002 static inline ScopedStyleResolver* scopedResolverFor(const Element* element)
   1003 {
   1004     for (TreeScope* treeScope = &element->treeScope(); treeScope; treeScope = treeScope->parentTreeScope()) {
   1005         if (ScopedStyleResolver* scopedStyleResolver = treeScope->scopedStyleResolver())
   1006             return scopedStyleResolver;
   1007     }
   1008     return 0;
   1009 }
   1010 
   1011 void StyleResolver::resolveScopedStyles(const Element* element, WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8>& resolvers)
   1012 {
   1013     for (ScopedStyleResolver* scopedResolver = scopedResolverFor(element); scopedResolver; scopedResolver = scopedResolver->parent())
   1014         resolvers.append(scopedResolver);
   1015 }
   1016 
   1017 void StyleResolver::collectScopedResolversForHostedShadowTrees(const Element* element, WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8>& resolvers)
   1018 {
   1019     ElementShadow* shadow = element->shadow();
   1020     if (!shadow)
   1021         return;
   1022 
   1023     // Adding scoped resolver for active shadow roots for shadow host styling.
   1024     for (ShadowRoot* shadowRoot = shadow->youngestShadowRoot(); shadowRoot; shadowRoot = shadowRoot->olderShadowRoot()) {
   1025         if (shadowRoot->numberOfStyles() > 0) {
   1026             if (ScopedStyleResolver* resolver = shadowRoot->scopedStyleResolver())
   1027                 resolvers.append(resolver);
   1028         }
   1029     }
   1030 }
   1031 
   1032 void StyleResolver::styleTreeResolveScopedKeyframesRules(const Element* element, WillBeHeapVector<RawPtrWillBeMember<ScopedStyleResolver>, 8>& resolvers)
   1033 {
   1034     TreeScope& treeScope = element->treeScope();
   1035 
   1036     // Add resolvers for shadow roots hosted by the given element.
   1037     collectScopedResolversForHostedShadowTrees(element, resolvers);
   1038 
   1039     // Add resolvers while walking up DOM tree from the given element.
   1040     for (ScopedStyleResolver* scopedResolver = scopedResolverFor(element); scopedResolver; scopedResolver = scopedResolver->parent()) {
   1041         if (scopedResolver->treeScope() == treeScope)
   1042             resolvers.append(scopedResolver);
   1043     }
   1044 }
   1045 
   1046 template <StyleResolver::StyleApplicationPass pass>
   1047 void StyleResolver::applyAnimatedProperties(StyleResolverState& state, const WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> >& activeInterpolations)
   1048 {
   1049     for (WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> >::const_iterator iter = activeInterpolations.begin(); iter != activeInterpolations.end(); ++iter) {
   1050         CSSPropertyID property = iter->key;
   1051         if (!isPropertyForPass<pass>(property))
   1052             continue;
   1053         const StyleInterpolation* interpolation = toStyleInterpolation(iter->value.get());
   1054         interpolation->apply(state);
   1055     }
   1056 }
   1057 
   1058 static inline bool isValidCueStyleProperty(CSSPropertyID id)
   1059 {
   1060     switch (id) {
   1061     case CSSPropertyBackground:
   1062     case CSSPropertyBackgroundAttachment:
   1063     case CSSPropertyBackgroundClip:
   1064     case CSSPropertyBackgroundColor:
   1065     case CSSPropertyBackgroundImage:
   1066     case CSSPropertyBackgroundOrigin:
   1067     case CSSPropertyBackgroundPosition:
   1068     case CSSPropertyBackgroundPositionX:
   1069     case CSSPropertyBackgroundPositionY:
   1070     case CSSPropertyBackgroundRepeat:
   1071     case CSSPropertyBackgroundRepeatX:
   1072     case CSSPropertyBackgroundRepeatY:
   1073     case CSSPropertyBackgroundSize:
   1074     case CSSPropertyColor:
   1075     case CSSPropertyFont:
   1076     case CSSPropertyFontFamily:
   1077     case CSSPropertyFontSize:
   1078     case CSSPropertyFontStretch:
   1079     case CSSPropertyFontStyle:
   1080     case CSSPropertyFontVariant:
   1081     case CSSPropertyFontWeight:
   1082     case CSSPropertyLineHeight:
   1083     case CSSPropertyOpacity:
   1084     case CSSPropertyOutline:
   1085     case CSSPropertyOutlineColor:
   1086     case CSSPropertyOutlineOffset:
   1087     case CSSPropertyOutlineStyle:
   1088     case CSSPropertyOutlineWidth:
   1089     case CSSPropertyVisibility:
   1090     case CSSPropertyWhiteSpace:
   1091     // FIXME: 'text-decoration' shorthand to be handled when available.
   1092     // See https://chromiumcodereview.appspot.com/19516002 for details.
   1093     case CSSPropertyTextDecoration:
   1094     case CSSPropertyTextShadow:
   1095     case CSSPropertyBorderStyle:
   1096         return true;
   1097     case CSSPropertyTextDecorationLine:
   1098     case CSSPropertyTextDecorationStyle:
   1099     case CSSPropertyTextDecorationColor:
   1100         return RuntimeEnabledFeatures::css3TextDecorationsEnabled();
   1101     default:
   1102         break;
   1103     }
   1104     return false;
   1105 }
   1106 
   1107 static inline bool isValidFirstLetterStyleProperty(CSSPropertyID id)
   1108 {
   1109     switch (id) {
   1110     // Valid ::first-letter properties listed in spec:
   1111     // http://www.w3.org/TR/css3-selectors/#application-in-css
   1112     case CSSPropertyBackgroundAttachment:
   1113     case CSSPropertyBackgroundBlendMode:
   1114     case CSSPropertyBackgroundClip:
   1115     case CSSPropertyBackgroundColor:
   1116     case CSSPropertyBackgroundImage:
   1117     case CSSPropertyBackgroundOrigin:
   1118     case CSSPropertyBackgroundPosition:
   1119     case CSSPropertyBackgroundPositionX:
   1120     case CSSPropertyBackgroundPositionY:
   1121     case CSSPropertyBackgroundRepeat:
   1122     case CSSPropertyBackgroundRepeatX:
   1123     case CSSPropertyBackgroundRepeatY:
   1124     case CSSPropertyBackgroundSize:
   1125     case CSSPropertyBorderBottomColor:
   1126     case CSSPropertyBorderBottomLeftRadius:
   1127     case CSSPropertyBorderBottomRightRadius:
   1128     case CSSPropertyBorderBottomStyle:
   1129     case CSSPropertyBorderBottomWidth:
   1130     case CSSPropertyBorderImageOutset:
   1131     case CSSPropertyBorderImageRepeat:
   1132     case CSSPropertyBorderImageSlice:
   1133     case CSSPropertyBorderImageSource:
   1134     case CSSPropertyBorderImageWidth:
   1135     case CSSPropertyBorderLeftColor:
   1136     case CSSPropertyBorderLeftStyle:
   1137     case CSSPropertyBorderLeftWidth:
   1138     case CSSPropertyBorderRightColor:
   1139     case CSSPropertyBorderRightStyle:
   1140     case CSSPropertyBorderRightWidth:
   1141     case CSSPropertyBorderTopColor:
   1142     case CSSPropertyBorderTopLeftRadius:
   1143     case CSSPropertyBorderTopRightRadius:
   1144     case CSSPropertyBorderTopStyle:
   1145     case CSSPropertyBorderTopWidth:
   1146     case CSSPropertyColor:
   1147     case CSSPropertyFloat:
   1148     case CSSPropertyFont:
   1149     case CSSPropertyFontFamily:
   1150     case CSSPropertyFontKerning:
   1151     case CSSPropertyFontSize:
   1152     case CSSPropertyFontStretch:
   1153     case CSSPropertyFontStyle:
   1154     case CSSPropertyFontVariant:
   1155     case CSSPropertyFontVariantLigatures:
   1156     case CSSPropertyFontWeight:
   1157     case CSSPropertyLetterSpacing:
   1158     case CSSPropertyLineHeight:
   1159     case CSSPropertyMarginBottom:
   1160     case CSSPropertyMarginLeft:
   1161     case CSSPropertyMarginRight:
   1162     case CSSPropertyMarginTop:
   1163     case CSSPropertyPaddingBottom:
   1164     case CSSPropertyPaddingLeft:
   1165     case CSSPropertyPaddingRight:
   1166     case CSSPropertyPaddingTop:
   1167     case CSSPropertyTextTransform:
   1168     case CSSPropertyVerticalAlign:
   1169     case CSSPropertyWebkitBackgroundClip:
   1170     case CSSPropertyWebkitBackgroundComposite:
   1171     case CSSPropertyWebkitBackgroundOrigin:
   1172     case CSSPropertyWebkitBackgroundSize:
   1173     case CSSPropertyWebkitBorderAfter:
   1174     case CSSPropertyWebkitBorderAfterColor:
   1175     case CSSPropertyWebkitBorderAfterStyle:
   1176     case CSSPropertyWebkitBorderAfterWidth:
   1177     case CSSPropertyWebkitBorderBefore:
   1178     case CSSPropertyWebkitBorderBeforeColor:
   1179     case CSSPropertyWebkitBorderBeforeStyle:
   1180     case CSSPropertyWebkitBorderBeforeWidth:
   1181     case CSSPropertyWebkitBorderEnd:
   1182     case CSSPropertyWebkitBorderEndColor:
   1183     case CSSPropertyWebkitBorderEndStyle:
   1184     case CSSPropertyWebkitBorderEndWidth:
   1185     case CSSPropertyWebkitBorderFit:
   1186     case CSSPropertyWebkitBorderHorizontalSpacing:
   1187     case CSSPropertyWebkitBorderImage:
   1188     case CSSPropertyWebkitBorderRadius:
   1189     case CSSPropertyWebkitBorderStart:
   1190     case CSSPropertyWebkitBorderStartColor:
   1191     case CSSPropertyWebkitBorderStartStyle:
   1192     case CSSPropertyWebkitBorderStartWidth:
   1193     case CSSPropertyWebkitBorderVerticalSpacing:
   1194     case CSSPropertyWebkitFontSmoothing:
   1195     case CSSPropertyWebkitMarginAfter:
   1196     case CSSPropertyWebkitMarginAfterCollapse:
   1197     case CSSPropertyWebkitMarginBefore:
   1198     case CSSPropertyWebkitMarginBeforeCollapse:
   1199     case CSSPropertyWebkitMarginBottomCollapse:
   1200     case CSSPropertyWebkitMarginCollapse:
   1201     case CSSPropertyWebkitMarginEnd:
   1202     case CSSPropertyWebkitMarginStart:
   1203     case CSSPropertyWebkitMarginTopCollapse:
   1204     case CSSPropertyWordSpacing:
   1205         return true;
   1206     case CSSPropertyTextDecorationColor:
   1207     case CSSPropertyTextDecorationLine:
   1208     case CSSPropertyTextDecorationStyle:
   1209         return RuntimeEnabledFeatures::css3TextDecorationsEnabled();
   1210 
   1211     // text-shadow added in text decoration spec:
   1212     // http://www.w3.org/TR/css-text-decor-3/#text-shadow-property
   1213     case CSSPropertyTextShadow:
   1214     // box-shadox added in CSS3 backgrounds spec:
   1215     // http://www.w3.org/TR/css3-background/#placement
   1216     case CSSPropertyBoxShadow:
   1217     case CSSPropertyWebkitBoxShadow:
   1218     // Properties that we currently support outside of spec.
   1219     case CSSPropertyWebkitLineBoxContain:
   1220     case CSSPropertyVisibility:
   1221         return true;
   1222 
   1223     default:
   1224         return false;
   1225     }
   1226 }
   1227 
   1228 // FIXME: Consider refactoring to create a new class which owns the following
   1229 // first/last/range properties.
   1230 // This method returns the first CSSPropertyId of high priority properties.
   1231 // Other properties can depend on high priority properties. For example,
   1232 // border-color property with currentColor value depends on color property.
   1233 // All high priority properties are obtained by using
   1234 // firstCSSPropertyId<HighPriorityProperties> and
   1235 // lastCSSPropertyId<HighPriorityProperties>.
   1236 template<> CSSPropertyID StyleResolver::firstCSSPropertyId<StyleResolver::HighPriorityProperties>()
   1237 {
   1238     COMPILE_ASSERT(CSSPropertyColor == firstCSSProperty, CSS_color_is_first_high_priority_property);
   1239     return CSSPropertyColor;
   1240 }
   1241 
   1242 // This method returns the last CSSPropertyId of high priority properties.
   1243 template<> CSSPropertyID StyleResolver::lastCSSPropertyId<StyleResolver::HighPriorityProperties>()
   1244 {
   1245     COMPILE_ASSERT(CSSPropertyLineHeight == CSSPropertyColor + 18, CSS_line_height_is_end_of_high_prioity_property_range);
   1246     COMPILE_ASSERT(CSSPropertyZoom == CSSPropertyLineHeight - 1, CSS_zoom_is_before_line_height);
   1247     return CSSPropertyLineHeight;
   1248 }
   1249 
   1250 // This method returns the first CSSPropertyId of remaining properties,
   1251 // i.e. low priority properties. No properties depend on low priority
   1252 // properties. So we don't need to resolve such properties quickly.
   1253 // All low priority properties are obtained by using
   1254 // firstCSSPropertyId<LowPriorityProperties> and
   1255 // lastCSSPropertyId<LowPriorityProperties>.
   1256 template<> CSSPropertyID StyleResolver::firstCSSPropertyId<StyleResolver::LowPriorityProperties>()
   1257 {
   1258     COMPILE_ASSERT(CSSPropertyAlignContent == CSSPropertyLineHeight + 1, CSS_background_is_first_low_priority_property);
   1259     return CSSPropertyAlignContent;
   1260 }
   1261 
   1262 // This method returns the last CSSPropertyId of low priority properties.
   1263 template<> CSSPropertyID StyleResolver::lastCSSPropertyId<StyleResolver::LowPriorityProperties>()
   1264 {
   1265     return static_cast<CSSPropertyID>(lastCSSProperty);
   1266 }
   1267 
   1268 template <StyleResolver::StyleApplicationPass pass>
   1269 bool StyleResolver::isPropertyForPass(CSSPropertyID property)
   1270 {
   1271     return firstCSSPropertyId<pass>() <= property && property <= lastCSSPropertyId<pass>();
   1272 }
   1273 
   1274 // This method expands the 'all' shorthand property to longhand properties
   1275 // and applies the expanded longhand properties.
   1276 template <StyleResolver::StyleApplicationPass pass>
   1277 void StyleResolver::applyAllProperty(StyleResolverState& state, CSSValue* allValue)
   1278 {
   1279     bool isUnsetValue = !allValue->isInitialValue() && !allValue->isInheritedValue();
   1280     unsigned startCSSProperty = firstCSSPropertyId<pass>();
   1281     unsigned endCSSProperty = lastCSSPropertyId<pass>();
   1282 
   1283     for (unsigned i = startCSSProperty; i <= endCSSProperty; ++i) {
   1284         CSSPropertyID propertyId = static_cast<CSSPropertyID>(i);
   1285 
   1286         // StyleBuilder does not allow any expanded shorthands.
   1287         if (isExpandedShorthandForAll(propertyId))
   1288             continue;
   1289 
   1290         // all shorthand spec says:
   1291         // The all property is a shorthand that resets all CSS properties
   1292         // except direction and unicode-bidi.
   1293         // c.f. http://dev.w3.org/csswg/css-cascade/#all-shorthand
   1294         // We skip applyProperty when a given property is unicode-bidi or
   1295         // direction.
   1296         if (!CSSProperty::isAffectedByAllProperty(propertyId))
   1297             continue;
   1298 
   1299         CSSValue* value;
   1300         if (!isUnsetValue) {
   1301             value = allValue;
   1302         } else {
   1303             if (CSSPropertyMetadata::isInheritedProperty(propertyId))
   1304                 value = cssValuePool().createInheritedValue().get();
   1305             else
   1306                 value = cssValuePool().createExplicitInitialValue().get();
   1307         }
   1308         StyleBuilder::applyProperty(propertyId, state, value);
   1309     }
   1310 }
   1311 
   1312 template <StyleResolver::StyleApplicationPass pass>
   1313 void StyleResolver::applyProperties(StyleResolverState& state, const StylePropertySet* properties, bool isImportant, bool inheritedOnly, PropertyWhitelistType propertyWhitelistType)
   1314 {
   1315     unsigned propertyCount = properties->propertyCount();
   1316     for (unsigned i = 0; i < propertyCount; ++i) {
   1317         StylePropertySet::PropertyReference current = properties->propertyAt(i);
   1318         if (isImportant != current.isImportant())
   1319             continue;
   1320 
   1321         CSSPropertyID property = current.id();
   1322         if (property == CSSPropertyAll) {
   1323             applyAllProperty<pass>(state, current.value());
   1324             continue;
   1325         }
   1326 
   1327         if (inheritedOnly && !current.isInherited()) {
   1328             // If the property value is explicitly inherited, we need to apply further non-inherited properties
   1329             // as they might override the value inherited here. For this reason we don't allow declarations with
   1330             // explicitly inherited properties to be cached.
   1331             ASSERT(!current.value()->isInheritedValue());
   1332             continue;
   1333         }
   1334 
   1335         if (propertyWhitelistType == PropertyWhitelistCue && !isValidCueStyleProperty(property))
   1336             continue;
   1337         if (propertyWhitelistType == PropertyWhitelistFirstLetter && !isValidFirstLetterStyleProperty(property))
   1338             continue;
   1339         if (!isPropertyForPass<pass>(property))
   1340             continue;
   1341         if (pass == HighPriorityProperties && property == CSSPropertyLineHeight)
   1342             state.setLineHeightValue(current.value());
   1343         else
   1344             StyleBuilder::applyProperty(current.id(), state, current.value());
   1345     }
   1346 }
   1347 
   1348 template <StyleResolver::StyleApplicationPass pass>
   1349 void StyleResolver::applyMatchedProperties(StyleResolverState& state, const MatchResult& matchResult, bool isImportant, int startIndex, int endIndex, bool inheritedOnly)
   1350 {
   1351     if (startIndex == -1)
   1352         return;
   1353 
   1354     if (state.style()->insideLink() != NotInsideLink) {
   1355         for (int i = startIndex; i <= endIndex; ++i) {
   1356             const MatchedProperties& matchedProperties = matchResult.matchedProperties[i];
   1357             unsigned linkMatchType = matchedProperties.m_types.linkMatchType;
   1358             // FIXME: It would be nicer to pass these as arguments but that requires changes in many places.
   1359             state.setApplyPropertyToRegularStyle(linkMatchType & SelectorChecker::MatchLink);
   1360             state.setApplyPropertyToVisitedLinkStyle(linkMatchType & SelectorChecker::MatchVisited);
   1361 
   1362             applyProperties<pass>(state, matchedProperties.properties.get(), isImportant, inheritedOnly, static_cast<PropertyWhitelistType>(matchedProperties.m_types.whitelistType));
   1363         }
   1364         state.setApplyPropertyToRegularStyle(true);
   1365         state.setApplyPropertyToVisitedLinkStyle(false);
   1366         return;
   1367     }
   1368     for (int i = startIndex; i <= endIndex; ++i) {
   1369         const MatchedProperties& matchedProperties = matchResult.matchedProperties[i];
   1370         applyProperties<pass>(state, matchedProperties.properties.get(), isImportant, inheritedOnly, static_cast<PropertyWhitelistType>(matchedProperties.m_types.whitelistType));
   1371     }
   1372 }
   1373 
   1374 static unsigned computeMatchedPropertiesHash(const MatchedProperties* properties, unsigned size)
   1375 {
   1376     return StringHasher::hashMemory(properties, sizeof(MatchedProperties) * size);
   1377 }
   1378 
   1379 void StyleResolver::invalidateMatchedPropertiesCache()
   1380 {
   1381     m_matchedPropertiesCache.clear();
   1382 }
   1383 
   1384 void StyleResolver::notifyResizeForViewportUnits()
   1385 {
   1386     collectViewportRules();
   1387     m_matchedPropertiesCache.clearViewportDependent();
   1388 }
   1389 
   1390 void StyleResolver::applyMatchedProperties(StyleResolverState& state, const MatchResult& matchResult)
   1391 {
   1392     const Element* element = state.element();
   1393     ASSERT(element);
   1394 
   1395     INCREMENT_STYLE_STATS_COUNTER(*this, matchedPropertyApply);
   1396 
   1397     unsigned cacheHash = matchResult.isCacheable ? computeMatchedPropertiesHash(matchResult.matchedProperties.data(), matchResult.matchedProperties.size()) : 0;
   1398     bool applyInheritedOnly = false;
   1399     const CachedMatchedProperties* cachedMatchedProperties = cacheHash ? m_matchedPropertiesCache.find(cacheHash, state, matchResult) : 0;
   1400 
   1401     if (cachedMatchedProperties && MatchedPropertiesCache::isCacheable(element, state.style(), state.parentStyle())) {
   1402         INCREMENT_STYLE_STATS_COUNTER(*this, matchedPropertyCacheHit);
   1403         // We can build up the style by copying non-inherited properties from an earlier style object built using the same exact
   1404         // style declarations. We then only need to apply the inherited properties, if any, as their values can depend on the
   1405         // element context. This is fast and saves memory by reusing the style data structures.
   1406         state.style()->copyNonInheritedFrom(cachedMatchedProperties->renderStyle.get());
   1407         if (state.parentStyle()->inheritedDataShared(cachedMatchedProperties->parentRenderStyle.get()) && !isAtShadowBoundary(element)
   1408             && (!state.distributedToInsertionPoint() || state.style()->userModify() == READ_ONLY)) {
   1409             INCREMENT_STYLE_STATS_COUNTER(*this, matchedPropertyCacheInheritedHit);
   1410 
   1411             EInsideLink linkStatus = state.style()->insideLink();
   1412             // If the cache item parent style has identical inherited properties to the current parent style then the
   1413             // resulting style will be identical too. We copy the inherited properties over from the cache and are done.
   1414             state.style()->inheritFrom(cachedMatchedProperties->renderStyle.get());
   1415 
   1416             // Unfortunately the link status is treated like an inherited property. We need to explicitly restore it.
   1417             state.style()->setInsideLink(linkStatus);
   1418             return;
   1419         }
   1420         applyInheritedOnly = true;
   1421     }
   1422 
   1423     // Now we have all of the matched rules in the appropriate order. Walk the rules and apply
   1424     // high-priority properties first, i.e., those properties that other properties depend on.
   1425     // The order is (1) high-priority not important, (2) high-priority important, (3) normal not important
   1426     // and (4) normal important.
   1427     state.setLineHeightValue(0);
   1428     applyMatchedProperties<HighPriorityProperties>(state, matchResult, false, 0, matchResult.matchedProperties.size() - 1, applyInheritedOnly);
   1429     applyMatchedProperties<HighPriorityProperties>(state, matchResult, true, matchResult.ranges.firstAuthorRule, matchResult.ranges.lastAuthorRule, applyInheritedOnly);
   1430     applyMatchedProperties<HighPriorityProperties>(state, matchResult, true, matchResult.ranges.firstUARule, matchResult.ranges.lastUARule, applyInheritedOnly);
   1431 
   1432     if (UNLIKELY(isSVGForeignObjectElement(element))) {
   1433         // RenderSVGRoot handles zooming for the whole SVG subtree, so foreignObject content should not be scaled again.
   1434         //
   1435         // FIXME: The following hijacks the zoom property for foreignObject so that children of foreignObject get the
   1436         // correct font-size in case of zooming. 'zoom' is part of HighPriorityProperties, along with other font-related
   1437         // properties used as input to the FontBuilder, so resetting it here may cause the FontBuilder to recompute the
   1438         // font used as inheritable font for foreignObject content. If we want to support zoom on foreignObject we'll
   1439         // need to find another way of handling the SVG zoom model.
   1440         state.setEffectiveZoom(RenderStyle::initialZoom());
   1441     }
   1442 
   1443     if (cachedMatchedProperties && cachedMatchedProperties->renderStyle->effectiveZoom() != state.style()->effectiveZoom()) {
   1444         state.fontBuilder().setFontDirty(true);
   1445         applyInheritedOnly = false;
   1446     }
   1447 
   1448     // If our font got dirtied, go ahead and update it now.
   1449     updateFont(state);
   1450 
   1451     // Line-height is set when we are sure we decided on the font-size.
   1452     if (state.lineHeightValue())
   1453         StyleBuilder::applyProperty(CSSPropertyLineHeight, state, state.lineHeightValue());
   1454 
   1455     // Many properties depend on the font. If it changes we just apply all properties.
   1456     if (cachedMatchedProperties && cachedMatchedProperties->renderStyle->fontDescription() != state.style()->fontDescription())
   1457         applyInheritedOnly = false;
   1458 
   1459     // Now do the normal priority UA properties.
   1460     applyMatchedProperties<LowPriorityProperties>(state, matchResult, false, matchResult.ranges.firstUARule, matchResult.ranges.lastUARule, applyInheritedOnly);
   1461 
   1462     // Cache the UA properties to pass them to RenderTheme in adjustRenderStyle.
   1463     state.cacheUserAgentBorderAndBackground();
   1464 
   1465     // Now do the author and user normal priority properties and all the !important properties.
   1466     applyMatchedProperties<LowPriorityProperties>(state, matchResult, false, matchResult.ranges.lastUARule + 1, matchResult.matchedProperties.size() - 1, applyInheritedOnly);
   1467     applyMatchedProperties<LowPriorityProperties>(state, matchResult, true, matchResult.ranges.firstAuthorRule, matchResult.ranges.lastAuthorRule, applyInheritedOnly);
   1468     applyMatchedProperties<LowPriorityProperties>(state, matchResult, true, matchResult.ranges.firstUARule, matchResult.ranges.lastUARule, applyInheritedOnly);
   1469 
   1470     loadPendingResources(state);
   1471 
   1472     if (!cachedMatchedProperties && cacheHash && MatchedPropertiesCache::isCacheable(element, state.style(), state.parentStyle())) {
   1473         INCREMENT_STYLE_STATS_COUNTER(*this, matchedPropertyCacheAdded);
   1474         m_matchedPropertiesCache.add(state.style(), state.parentStyle(), cacheHash, matchResult);
   1475     }
   1476 
   1477     ASSERT(!state.fontBuilder().fontDirty());
   1478 }
   1479 
   1480 void StyleResolver::applyCallbackSelectors(StyleResolverState& state)
   1481 {
   1482     if (!m_watchedSelectorsRules)
   1483         return;
   1484 
   1485     ElementRuleCollector collector(state.elementContext(), m_selectorFilter, state.style());
   1486     collector.setMode(SelectorChecker::CollectingStyleRules);
   1487 
   1488     MatchRequest matchRequest(m_watchedSelectorsRules.get(), true);
   1489     RuleRange ruleRange = collector.matchedResult().ranges.authorRuleRange();
   1490     collector.collectMatchingRules(matchRequest, ruleRange);
   1491     collector.sortAndTransferMatchedRules();
   1492 
   1493     RefPtrWillBeRawPtr<StyleRuleList> rules = collector.matchedStyleRuleList();
   1494     if (!rules)
   1495         return;
   1496     for (size_t i = 0; i < rules->m_list.size(); i++)
   1497         state.style()->addCallbackSelector(rules->m_list[i]->selectorList().selectorsText());
   1498 }
   1499 
   1500 CSSPropertyValue::CSSPropertyValue(CSSPropertyID id, const StylePropertySet& propertySet)
   1501     : property(id), value(propertySet.getPropertyCSSValue(id).get())
   1502 { }
   1503 
   1504 void StyleResolver::enableStats(StatsReportType reportType)
   1505 {
   1506     if (m_styleResolverStats)
   1507         return;
   1508     m_styleResolverStats = StyleResolverStats::create();
   1509     m_styleResolverStatsTotals = StyleResolverStats::create();
   1510     if (reportType == ReportSlowStats) {
   1511         m_styleResolverStats->printMissedCandidateCount = true;
   1512         m_styleResolverStatsTotals->printMissedCandidateCount = true;
   1513     }
   1514 }
   1515 
   1516 void StyleResolver::disableStats()
   1517 {
   1518     m_styleResolverStatsSequence = 0;
   1519     m_styleResolverStats.clear();
   1520     m_styleResolverStatsTotals.clear();
   1521 }
   1522 
   1523 void StyleResolver::printStats()
   1524 {
   1525     if (!m_styleResolverStats)
   1526         return;
   1527     fprintf(stderr, "=== Style Resolver Stats (resolve #%u) (%s) ===\n", ++m_styleResolverStatsSequence, document().url().string().utf8().data());
   1528     fprintf(stderr, "%s\n", m_styleResolverStats->report().utf8().data());
   1529     fprintf(stderr, "== Totals ==\n");
   1530     fprintf(stderr, "%s\n", m_styleResolverStatsTotals->report().utf8().data());
   1531 }
   1532 
   1533 void StyleResolver::applyPropertiesToStyle(const CSSPropertyValue* properties, size_t count, RenderStyle* style)
   1534 {
   1535     StyleResolverState state(document(), document().documentElement(), style);
   1536     state.setStyle(style);
   1537 
   1538     state.fontBuilder().initForStyleResolve(document(), style);
   1539 
   1540     for (size_t i = 0; i < count; ++i) {
   1541         if (properties[i].value) {
   1542             // As described in BUG66291, setting font-size and line-height on a font may entail a CSSPrimitiveValue::computeLengthDouble call,
   1543             // which assumes the fontMetrics are available for the affected font, otherwise a crash occurs (see http://trac.webkit.org/changeset/96122).
   1544             // The updateFont() call below updates the fontMetrics and ensure the proper setting of font-size and line-height.
   1545             switch (properties[i].property) {
   1546             case CSSPropertyFontSize:
   1547             case CSSPropertyLineHeight:
   1548                 updateFont(state);
   1549                 break;
   1550             default:
   1551                 break;
   1552             }
   1553             StyleBuilder::applyProperty(properties[i].property, state, properties[i].value);
   1554         }
   1555     }
   1556 }
   1557 
   1558 void StyleResolver::addMediaQueryResults(const MediaQueryResultList& list)
   1559 {
   1560     for (size_t i = 0; i < list.size(); ++i)
   1561         m_viewportDependentMediaQueryResults.append(list[i]);
   1562 }
   1563 
   1564 bool StyleResolver::mediaQueryAffectedByViewportChange() const
   1565 {
   1566     for (unsigned i = 0; i < m_viewportDependentMediaQueryResults.size(); ++i) {
   1567         if (m_medium->eval(m_viewportDependentMediaQueryResults[i]->expression()) != m_viewportDependentMediaQueryResults[i]->result())
   1568             return true;
   1569     }
   1570     return false;
   1571 }
   1572 
   1573 void StyleResolver::trace(Visitor* visitor)
   1574 {
   1575 #if ENABLE(OILPAN)
   1576     visitor->trace(m_keyframesRuleMap);
   1577     visitor->trace(m_matchedPropertiesCache);
   1578     visitor->trace(m_viewportDependentMediaQueryResults);
   1579     visitor->trace(m_selectorFilter);
   1580     visitor->trace(m_viewportStyleResolver);
   1581     visitor->trace(m_features);
   1582     visitor->trace(m_siblingRuleSet);
   1583     visitor->trace(m_uncommonAttributeRuleSet);
   1584     visitor->trace(m_watchedSelectorsRules);
   1585     visitor->trace(m_treeBoundaryCrossingRules);
   1586     visitor->trace(m_styleSharingLists);
   1587     visitor->trace(m_pendingStyleSheets);
   1588     visitor->trace(m_document);
   1589 #endif
   1590 }
   1591 
   1592 } // namespace blink
   1593