Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / css / resolver / StyleResolver.cpp
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com)
4  * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@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@webkit.org>
7  * Copyright (C) 2007, 2008 Eric Seidel <eric@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