ca585fdc7cdf23fb4710c5749626bdbbac66f991
[WebKit-https.git] / Source / WebCore / css / StyleResolver.h
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB.  If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  *
20  */
21
22 #ifndef StyleResolver_h
23 #define StyleResolver_h
24
25 #include "CSSToStyleMap.h"
26 #include "CSSValueList.h"
27 #include "DocumentRuleSets.h"
28 #include "InspectorCSSOMWrappers.h"
29 #include "LinkHash.h"
30 #include "MediaQueryExp.h"
31 #include "RenderStyle.h"
32 #include "RuleFeature.h"
33 #include "RuleSet.h"
34 #include "RuntimeEnabledFeatures.h"
35 #include "ScrollTypes.h"
36 #include "SelectorChecker.h"
37 #include "SelectorFilter.h"
38 #include "StyleInheritedData.h"
39 #include "StyleScopeResolver.h"
40 #include "ViewportStyleResolver.h"
41 #if ENABLE(CSS_SHADERS)
42 #include "CustomFilterConstants.h"
43 #endif
44 #include <wtf/HashMap.h>
45 #include <wtf/HashSet.h>
46 #include <wtf/RefPtr.h>
47 #include <wtf/Vector.h>
48 #include <wtf/text/AtomicStringHash.h>
49 #include <wtf/text/StringHash.h>
50
51 namespace WebCore {
52
53 class CSSCursorImageValue;
54 class CSSFontSelector;
55 class CSSFontFace;
56 class CSSFontFaceRule;
57 class CSSImageGeneratorValue;
58 class CSSImageSetValue;
59 class CSSImageValue;
60 class CSSPageRule;
61 class CSSPrimitiveValue;
62 class CSSProperty;
63 class CSSSelector;
64 class CSSStyleSheet;
65 class CSSValue;
66 class ContainerNode;
67 class CustomFilterOperation;
68 class CustomFilterParameter;
69 class CustomFilterParameterList;
70 class CustomFilterProgram;
71 struct CustomFilterProgramMixSettings;
72 class Document;
73 class DeprecatedStyleBuilder;
74 class Element;
75 class Frame;
76 class FrameView;
77 class URL;
78 class KeyframeList;
79 class KeyframeValue;
80 class MediaQueryEvaluator;
81 class Node;
82 class RenderRegion;
83 class RenderScrollbar;
84 class RuleData;
85 class RuleSet;
86 class Settings;
87 class StyleCustomFilterProgramCache;
88 class StyleScopeResolver;
89 class StyleImage;
90 class StyleKeyframe;
91 class StylePendingImage;
92 class StyleProperties;
93 class StyleRule;
94 #if ENABLE(SHADOW_DOM)
95 class StyleRuleHost;
96 #endif
97 class StyleRuleKeyframes;
98 class StyleRulePage;
99 class StyleRuleRegion;
100 class StyleShader;
101 class StyleSheet;
102 class StyleSheetList;
103 class StyledElement;
104 class ViewportStyleResolver;
105 class WebKitCSSFilterValue;
106 class WebKitCSSShaderValue;
107
108 class MediaQueryResult {
109     WTF_MAKE_NONCOPYABLE(MediaQueryResult); WTF_MAKE_FAST_ALLOCATED;
110 public:
111     MediaQueryResult(const MediaQueryExp& expr, bool result)
112         : m_expression(expr)
113         , m_result(result)
114     {
115     }
116
117     MediaQueryExp m_expression;
118     bool m_result;
119 };
120
121 enum StyleSharingBehavior {
122     AllowStyleSharing,
123     DisallowStyleSharing,
124 };
125
126 // MatchOnlyUserAgentRules is used in media queries, where relative units
127 // are interpreted according to the document root element style, and styled only
128 // from the User Agent Stylesheet rules.
129
130 enum RuleMatchingBehavior {
131     MatchAllRules,
132     MatchAllRulesExcludingSMIL,
133     MatchOnlyUserAgentRules,
134 };
135
136 class PseudoStyleRequest {
137 public:
138     PseudoStyleRequest(PseudoId pseudoId, RenderScrollbar* scrollbar = 0, ScrollbarPart scrollbarPart = NoPart)
139         : pseudoId(pseudoId)
140         , scrollbarPart(scrollbarPart)
141         , scrollbar(scrollbar)
142     {
143     }
144
145     PseudoId pseudoId;
146     ScrollbarPart scrollbarPart;
147     RenderScrollbar* scrollbar;
148 };
149
150 // This class selects a RenderStyle for a given element based on a collection of stylesheets.
151 class StyleResolver {
152     WTF_MAKE_NONCOPYABLE(StyleResolver); WTF_MAKE_FAST_ALLOCATED;
153 public:
154     StyleResolver(Document&, bool matchAuthorAndUserStyles);
155     ~StyleResolver();
156
157     // Using these during tree walk will allow style selector to optimize child and descendant selector lookups.
158     void pushParentElement(Element*);
159     void popParentElement(Element*);
160     void pushParentShadowRoot(const ShadowRoot*);
161     void popParentShadowRoot(const ShadowRoot*);
162 #if ENABLE(SHADOW_DOM)
163     void addHostRule(StyleRuleHost* rule, bool hasDocumentSecurityOrigin, const ContainerNode* scope) { ensureScopeResolver()->addHostRule(rule, hasDocumentSecurityOrigin, scope); }
164 #endif
165
166     PassRef<RenderStyle> styleForElement(Element*, RenderStyle* parentStyle = 0, StyleSharingBehavior = AllowStyleSharing,
167         RuleMatchingBehavior = MatchAllRules, RenderRegion* regionForStyling = 0);
168
169     void keyframeStylesForAnimation(Element*, const RenderStyle*, KeyframeList&);
170
171     PassRefPtr<RenderStyle> pseudoStyleForElement(Element*, const PseudoStyleRequest&, RenderStyle* parentStyle);
172
173     PassRef<RenderStyle> styleForPage(int pageIndex);
174     PassRef<RenderStyle> defaultStyleForElement();
175
176     RenderStyle* style() const { return m_state.style(); }
177     RenderStyle* parentStyle() const { return m_state.parentStyle(); }
178     RenderStyle* rootElementStyle() const { return m_state.rootElementStyle(); }
179     Element* element() { return m_state.element(); }
180     Document& document() { return m_document; }
181     StyleScopeResolver* scopeResolver() const { return m_scopeResolver.get(); }
182     bool hasParentNode() const { return m_state.parentNode(); }
183
184     // FIXME: It could be better to call m_ruleSets.appendAuthorStyleSheets() directly after we factor StyleRsolver further.
185     // https://bugs.webkit.org/show_bug.cgi?id=108890
186     void appendAuthorStyleSheets(unsigned firstNew, const Vector<RefPtr<CSSStyleSheet>>&);
187
188     DocumentRuleSets& ruleSets() { return m_ruleSets; }
189     const DocumentRuleSets& ruleSets() const { return m_ruleSets; }
190     SelectorFilter& selectorFilter() { return m_selectorFilter; }
191
192 #if ENABLE(SHADOW_DOM)
193     StyleScopeResolver* ensureScopeResolver()
194     {
195         ASSERT(RuntimeEnabledFeatures::sharedFeatures().shadowDOMEnabled());
196         if (!m_scopeResolver)
197             m_scopeResolver = adoptPtr(new StyleScopeResolver());
198         return m_scopeResolver.get();
199     }
200 #endif
201
202 private:
203     void initElement(Element*);
204     RenderStyle* locateSharedStyle();
205     bool styleSharingCandidateMatchesRuleSet(RuleSet*);
206     bool styleSharingCandidateMatchesHostRules();
207     Node* locateCousinList(Element* parent, unsigned& visitedNodeCount) const;
208     StyledElement* findSiblingForStyleSharing(Node*, unsigned& count) const;
209     bool canShareStyleWithElement(StyledElement*) const;
210
211     PassRef<RenderStyle> styleForKeyframe(const RenderStyle*, const StyleKeyframe*, KeyframeValue&);
212
213 public:
214     // These methods will give back the set of rules that matched for a given element (or a pseudo-element).
215     enum CSSRuleFilter {
216         UAAndUserCSSRules   = 1 << 1,
217         AuthorCSSRules      = 1 << 2,
218         EmptyCSSRules       = 1 << 3,
219         CrossOriginCSSRules = 1 << 4,
220         AllButEmptyCSSRules = UAAndUserCSSRules | AuthorCSSRules | CrossOriginCSSRules,
221         AllCSSRules         = AllButEmptyCSSRules | EmptyCSSRules,
222     };
223     Vector<RefPtr<StyleRuleBase>> styleRulesForElement(Element*, unsigned rulesToInclude = AllButEmptyCSSRules);
224     Vector<RefPtr<StyleRuleBase>> pseudoStyleRulesForElement(Element*, PseudoId, unsigned rulesToInclude = AllButEmptyCSSRules);
225
226 public:
227     void applyPropertyToStyle(CSSPropertyID, CSSValue*, RenderStyle*);
228
229     void applyPropertyToCurrentStyle(CSSPropertyID, CSSValue*);
230
231     void updateFont();
232     void initializeFontStyle(Settings*);
233
234     void setFontSize(FontDescription&, float size);
235
236 public:
237     bool useSVGZoomRules();
238
239     static bool colorFromPrimitiveValueIsDerivedFromElement(CSSPrimitiveValue*);
240     Color colorFromPrimitiveValue(CSSPrimitiveValue*, bool forVisitedLink = false) const;
241
242     bool hasSelectorForId(const AtomicString&) const;
243     bool hasSelectorForClass(const AtomicString&) const;
244     bool hasSelectorForAttribute(const AtomicString&) const;
245
246     CSSFontSelector* fontSelector() const { return m_fontSelector.get(); }
247 #if ENABLE(CSS_DEVICE_ADAPTATION)
248     ViewportStyleResolver* viewportStyleResolver() { return m_viewportStyleResolver.get(); }
249 #endif
250
251     void addViewportDependentMediaQueryResult(const MediaQueryExp*, bool result);
252     bool hasViewportDependentMediaQueries() const { return !m_viewportDependentMediaQueryResults.isEmpty(); }
253     bool affectedByViewportChange() const;
254
255     void addKeyframeStyle(PassRefPtr<StyleRuleKeyframes>);
256
257     bool checkRegionStyle(Element* regionElement);
258
259     bool usesSiblingRules() const { return !m_ruleSets.features().siblingRules.isEmpty(); }
260     bool usesFirstLineRules() const { return m_ruleSets.features().usesFirstLineRules; }
261     bool usesBeforeAfterRules() const { return m_ruleSets.features().usesBeforeAfterRules; }
262     
263     void invalidateMatchedPropertiesCache();
264
265 #if ENABLE(CSS_FILTERS)
266     bool createFilterOperations(CSSValue* inValue, FilterOperations& outOperations);
267 #if ENABLE(CSS_SHADERS)
268     StyleShader* styleShader(CSSValue*);
269     StyleShader* cachedOrPendingStyleShaderFromValue(WebKitCSSShaderValue*);
270     bool parseCustomFilterParameterList(CSSValue*, CustomFilterParameterList&);
271     PassRefPtr<CustomFilterParameter> parseCustomFilterParameter(const String& name, CSSValue*);
272     PassRefPtr<CustomFilterParameter> parseCustomFilterColorParameter(const String& name, CSSValueList*);
273     PassRefPtr<CustomFilterParameter> parseCustomFilterArrayParameter(const String& name, CSSValueList*, bool);
274     PassRefPtr<CustomFilterParameter> parseCustomFilterNumberParameter(const String& name, CSSValueList*);
275     PassRefPtr<CustomFilterParameter> parseCustomFilterTransformParameter(const String& name, CSSValueList*);
276     PassRefPtr<CustomFilterOperation> createCustomFilterOperationWithAtRuleReferenceSyntax(WebKitCSSFilterValue*);
277     PassRefPtr<CustomFilterOperation> createCustomFilterOperationWithInlineSyntax(WebKitCSSFilterValue*);
278     PassRefPtr<CustomFilterOperation> createCustomFilterOperation(WebKitCSSFilterValue*);
279     void loadPendingShaders();
280     PassRefPtr<CustomFilterProgram> lookupCustomFilterProgram(WebKitCSSShaderValue* vertexShader, WebKitCSSShaderValue* fragmentShader, 
281         CustomFilterProgramType, const CustomFilterProgramMixSettings&, CustomFilterMeshType);
282 #endif
283 #if ENABLE(SVG)
284     void loadPendingSVGDocuments();
285 #endif
286 #endif // ENABLE(CSS_FILTERS)
287
288     void loadPendingResources();
289
290     int viewportPercentageValue(CSSPrimitiveValue& unit, int percentage);
291
292     struct RuleRange {
293         RuleRange(int& firstRuleIndex, int& lastRuleIndex): firstRuleIndex(firstRuleIndex), lastRuleIndex(lastRuleIndex) { }
294         int& firstRuleIndex;
295         int& lastRuleIndex;
296     };
297
298     struct MatchRanges {
299         MatchRanges() : firstUARule(-1), lastUARule(-1), firstAuthorRule(-1), lastAuthorRule(-1), firstUserRule(-1), lastUserRule(-1) { }
300         int firstUARule;
301         int lastUARule;
302         int firstAuthorRule;
303         int lastAuthorRule;
304         int firstUserRule;
305         int lastUserRule;
306         RuleRange UARuleRange() { return RuleRange(firstUARule, lastUARule); }
307         RuleRange authorRuleRange() { return RuleRange(firstAuthorRule, lastAuthorRule); }
308         RuleRange userRuleRange() { return RuleRange(firstUserRule, lastUserRule); }
309     };
310
311     struct MatchedProperties {
312         MatchedProperties();
313         ~MatchedProperties();
314         
315         RefPtr<StyleProperties> properties;
316         union {
317             struct {
318                 unsigned linkMatchType : 2;
319                 unsigned whitelistType : 2;
320             };
321             // Used to make sure all memory is zero-initialized since we compute the hash over the bytes of this object.
322             void* possiblyPaddedMember;
323         };
324     };
325
326     struct MatchResult {
327         MatchResult() : isCacheable(true) { }
328         Vector<MatchedProperties, 64> matchedProperties;
329         Vector<StyleRule*, 64> matchedRules;
330         MatchRanges ranges;
331         bool isCacheable;
332
333         void addMatchedProperties(const StyleProperties&, StyleRule* = 0, unsigned linkMatchType = SelectorChecker::MatchAll, PropertyWhitelistType = PropertyWhitelistNone);
334     };
335
336 private:
337     // This function fixes up the default font size if it detects that the current generic font family has changed. -dwh
338     void checkForGenericFamilyChange(RenderStyle*, RenderStyle* parentStyle);
339     void checkForZoomChange(RenderStyle*, RenderStyle* parentStyle);
340 #if ENABLE(IOS_TEXT_AUTOSIZING)
341     void checkForTextSizeAdjust(RenderStyle*);
342 #endif
343
344     void adjustRenderStyle(RenderStyle& styleToAdjust, const RenderStyle& parentStyle, Element*);
345     void adjustGridItemPosition(RenderStyle& styleToAdjust, const RenderStyle& parentStyle) const;
346
347     bool fastRejectSelector(const RuleData&) const;
348
349     enum ShouldUseMatchedPropertiesCache { DoNotUseMatchedPropertiesCache = 0, UseMatchedPropertiesCache };
350     void applyMatchedProperties(const MatchResult&, const Element*, ShouldUseMatchedPropertiesCache = UseMatchedPropertiesCache);
351
352     class CascadedProperties;
353
354     void applyCascadedProperties(CascadedProperties&, int firstProperty, int lastProperty);
355     void cascadeMatches(CascadedProperties&, const MatchResult&, bool important, int startIndex, int endIndex, bool inheritedOnly);
356
357     static bool isValidRegionStyleProperty(CSSPropertyID);
358 #if ENABLE(VIDEO_TRACK)
359     static bool isValidCueStyleProperty(CSSPropertyID);
360 #endif
361     void matchPageRules(MatchResult&, RuleSet*, bool isLeftPage, bool isFirstPage, const String& pageName);
362     void matchPageRulesForList(Vector<StyleRulePage*>& matchedRules, const Vector<StyleRulePage*>&, bool isLeftPage, bool isFirstPage, const String& pageName);
363     Settings* documentSettings() { return m_document.settings(); }
364
365     bool isLeftPage(int pageIndex) const;
366     bool isRightPage(int pageIndex) const { return !isLeftPage(pageIndex); }
367     bool isFirstPage(int pageIndex) const;
368     String pageName(int pageIndex) const;
369
370     DocumentRuleSets m_ruleSets;
371
372     typedef HashMap<AtomicStringImpl*, RefPtr<StyleRuleKeyframes>> KeyframesRuleMap;
373     KeyframesRuleMap m_keyframesRuleMap;
374
375 public:
376     typedef HashMap<CSSPropertyID, RefPtr<CSSValue>> PendingImagePropertyMap;
377 #if ENABLE(CSS_FILTERS) && ENABLE(SVG)
378     typedef HashSet<CachedSVGDocumentReference*> PendingSVGDocumentSet;
379 #endif
380
381     class State {
382         WTF_MAKE_NONCOPYABLE(State);
383     public:
384         State()
385         : m_element(0)
386         , m_styledElement(0)
387         , m_parentNode(0)
388         , m_parentStyle(0)
389         , m_rootElementStyle(0)
390         , m_regionForStyling(0)
391         , m_elementLinkState(NotInsideLink)
392         , m_elementAffectedByClassRules(false)
393         , m_applyPropertyToRegularStyle(true)
394         , m_applyPropertyToVisitedLinkStyle(false)
395 #if ENABLE(CSS_SHADERS)
396         , m_hasPendingShaders(false)
397 #endif
398         , m_lineHeightValue(0)
399         , m_fontDirty(false)
400         , m_hasUAAppearance(false)
401         , m_backgroundData(BackgroundFillLayer) { }
402
403     public:
404         void initElement(Element*);
405         void initForStyleResolve(Document&, Element*, RenderStyle* parentStyle = 0, RenderRegion* regionForStyling = 0);
406         void clear();
407
408         Document& document() const { return m_element->document(); }
409         Element* element() const { return m_element; }
410         StyledElement* styledElement() const { return m_styledElement; }
411         void setStyle(PassRef<RenderStyle> style) { m_style = std::move(style); }
412         RenderStyle* style() const { return m_style.get(); }
413         PassRef<RenderStyle> takeStyle() { return m_style.releaseNonNull(); }
414
415         const ContainerNode* parentNode() const { return m_parentNode; }
416         void setParentStyle(PassRef<RenderStyle> parentStyle) { m_parentStyle = std::move(parentStyle); }
417         RenderStyle* parentStyle() const { return m_parentStyle.get(); }
418         RenderStyle* rootElementStyle() const { return m_rootElementStyle; }
419
420         const RenderRegion* regionForStyling() const { return m_regionForStyling; }
421         EInsideLink elementLinkState() const { return m_elementLinkState; }
422         void setElementAffectedByClassRules(bool isAffected) { m_elementAffectedByClassRules = isAffected; }
423         bool elementAffectedByClassRules() const { return m_elementAffectedByClassRules; }
424
425         void setApplyPropertyToRegularStyle(bool isApply) { m_applyPropertyToRegularStyle = isApply; }
426         void setApplyPropertyToVisitedLinkStyle(bool isApply) { m_applyPropertyToVisitedLinkStyle = isApply; }
427         bool applyPropertyToRegularStyle() const { return m_applyPropertyToRegularStyle; }
428         bool applyPropertyToVisitedLinkStyle() const { return m_applyPropertyToVisitedLinkStyle; }
429         PendingImagePropertyMap& pendingImageProperties() { return m_pendingImageProperties; }
430 #if ENABLE(CSS_FILTERS) && ENABLE(SVG)
431         PendingSVGDocumentSet& pendingSVGDocuments() { return m_pendingSVGDocuments; }
432 #endif
433 #if ENABLE(CSS_SHADERS)
434         void setHasPendingShaders(bool hasPendingShaders) { m_hasPendingShaders = hasPendingShaders; }
435         bool hasPendingShaders() const { return m_hasPendingShaders; }
436 #endif
437
438         void setLineHeightValue(CSSValue* value) { m_lineHeightValue = value; }
439         CSSValue* lineHeightValue() { return m_lineHeightValue; }
440         void setFontDirty(bool isDirty) { m_fontDirty = isDirty; }
441         bool fontDirty() const { return m_fontDirty; }
442
443         void cacheBorderAndBackground();
444         bool hasUAAppearance() const { return m_hasUAAppearance; }
445         BorderData borderData() const { return m_borderData; }
446         FillLayer backgroundData() const { return m_backgroundData; }
447         Color backgroundColor() const { return m_backgroundColor; }
448
449         const FontDescription& fontDescription() { return m_style->fontDescription(); }
450         const FontDescription& parentFontDescription() { return m_parentStyle->fontDescription(); }
451         void setFontDescription(const FontDescription& fontDescription) { m_fontDirty |= m_style->setFontDescription(fontDescription); }
452         void setZoom(float f) { m_fontDirty |= m_style->setZoom(f); }
453         void setEffectiveZoom(float f) { m_fontDirty |= m_style->setEffectiveZoom(f); }
454         void setWritingMode(WritingMode writingMode) { m_fontDirty |= m_style->setWritingMode(writingMode); }
455         void setTextOrientation(TextOrientation textOrientation) { m_fontDirty |= m_style->setTextOrientation(textOrientation); }
456
457         bool useSVGZoomRules() const { return m_element && m_element->isSVGElement(); }
458
459     private:
460         // FIXME(bug 108563): to make it easier to review, these member
461         // variables are public. However we should add methods to access
462         // these variables.
463         Element* m_element;
464         RefPtr<RenderStyle> m_style;
465         StyledElement* m_styledElement;
466         ContainerNode* m_parentNode;
467         RefPtr<RenderStyle> m_parentStyle;
468         RenderStyle* m_rootElementStyle;
469
470         // Required to ASSERT in applyProperties.
471         RenderRegion* m_regionForStyling;
472         
473         EInsideLink m_elementLinkState;
474
475         bool m_elementAffectedByClassRules;
476
477         bool m_applyPropertyToRegularStyle;
478         bool m_applyPropertyToVisitedLinkStyle;
479
480         PendingImagePropertyMap m_pendingImageProperties;
481 #if ENABLE(CSS_SHADERS)
482         bool m_hasPendingShaders;
483 #endif
484 #if ENABLE(CSS_FILTERS) && ENABLE(SVG)
485         PendingSVGDocumentSet m_pendingSVGDocuments;
486 #endif
487         CSSValue* m_lineHeightValue;
488         bool m_fontDirty;
489
490         bool m_hasUAAppearance;
491         BorderData m_borderData;
492         FillLayer m_backgroundData;
493         Color m_backgroundColor;
494     };
495
496     State& state() { return m_state; }
497
498     static RenderStyle* styleNotYetAvailable() { return s_styleNotYetAvailable; }
499
500     PassRefPtr<StyleImage> styleImage(CSSPropertyID, CSSValue*);
501     PassRefPtr<StyleImage> cachedOrPendingFromValue(CSSPropertyID, CSSImageValue*);
502     PassRefPtr<StyleImage> generatedOrPendingFromValue(CSSPropertyID, CSSImageGeneratorValue&);
503 #if ENABLE(CSS_IMAGE_SET)
504     PassRefPtr<StyleImage> setOrPendingFromValue(CSSPropertyID, CSSImageSetValue*);
505 #endif
506     PassRefPtr<StyleImage> cursorOrPendingFromValue(CSSPropertyID, CSSCursorImageValue*);
507
508     bool applyPropertyToRegularStyle() const { return m_state.applyPropertyToRegularStyle(); }
509     bool applyPropertyToVisitedLinkStyle() const { return m_state.applyPropertyToVisitedLinkStyle(); }
510
511     static Length convertToIntLength(const CSSPrimitiveValue*, const RenderStyle*, const RenderStyle* rootStyle, double multiplier = 1);
512     static Length convertToFloatLength(const CSSPrimitiveValue*, const RenderStyle*, const RenderStyle* rootStyle, double multiplier = 1);
513
514     CSSToStyleMap* styleMap() { return &m_styleMap; }
515     InspectorCSSOMWrappers& inspectorCSSOMWrappers() { return m_inspectorCSSOMWrappers; }
516     const FontDescription& fontDescription() { return m_state.fontDescription(); }
517     const FontDescription& parentFontDescription() { return m_state.parentFontDescription(); }
518     void setFontDescription(const FontDescription& fontDescription) { m_state.setFontDescription(fontDescription); }
519     void setZoom(float f) { m_state.setZoom(f); }
520     void setEffectiveZoom(float f) { m_state.setEffectiveZoom(f); }
521     void setWritingMode(WritingMode writingMode) { m_state.setWritingMode(writingMode); }
522     void setTextOrientation(TextOrientation textOrientation) { m_state.setTextOrientation(textOrientation); }
523
524 private:
525     static RenderStyle* s_styleNotYetAvailable;
526
527     void cacheBorderAndBackground();
528
529 private:
530     bool canShareStyleWithControl(StyledElement*) const;
531
532     void applyProperty(CSSPropertyID, CSSValue*);
533
534 #if ENABLE(SVG)
535     void applySVGProperty(CSSPropertyID, CSSValue*);
536 #endif
537
538     PassRefPtr<StyleImage> loadPendingImage(StylePendingImage*, const ResourceLoaderOptions&);
539     PassRefPtr<StyleImage> loadPendingImage(StylePendingImage*);
540     void loadPendingImages();
541 #if ENABLE(CSS_SHAPES)
542     void loadPendingShapeImage(ShapeValue*);
543 #endif
544
545     static unsigned computeMatchedPropertiesHash(const MatchedProperties*, unsigned size);
546     struct MatchedPropertiesCacheItem {
547         Vector<MatchedProperties> matchedProperties;
548         MatchRanges ranges;
549         RefPtr<RenderStyle> renderStyle;
550         RefPtr<RenderStyle> parentRenderStyle;
551     };
552     const MatchedPropertiesCacheItem* findFromMatchedPropertiesCache(unsigned hash, const MatchResult&);
553     void addToMatchedPropertiesCache(const RenderStyle*, const RenderStyle* parentStyle, unsigned hash, const MatchResult&);
554
555     // Every N additions to the matched declaration cache trigger a sweep where entries holding
556     // the last reference to a style declaration are garbage collected.
557     void sweepMatchedPropertiesCache(Timer<StyleResolver>*);
558
559     bool classNamesAffectedByRules(const SpaceSplitString&) const;
560     bool sharingCandidateHasIdenticalStyleAffectingAttributes(StyledElement*) const;
561
562
563     unsigned m_matchedPropertiesCacheAdditionsSinceLastSweep;
564
565     typedef HashMap<unsigned, MatchedPropertiesCacheItem> MatchedPropertiesCache;
566     MatchedPropertiesCache m_matchedPropertiesCache;
567
568     Timer<StyleResolver> m_matchedPropertiesCacheSweepTimer;
569
570     OwnPtr<MediaQueryEvaluator> m_medium;
571     RefPtr<RenderStyle> m_rootDefaultStyle;
572
573     Document& m_document;
574     SelectorFilter m_selectorFilter;
575
576     bool m_matchAuthorAndUserStyles;
577
578     RefPtr<CSSFontSelector> m_fontSelector;
579     Vector<OwnPtr<MediaQueryResult>> m_viewportDependentMediaQueryResults;
580
581 #if ENABLE(CSS_DEVICE_ADAPTATION)
582     RefPtr<ViewportStyleResolver> m_viewportStyleResolver;
583 #endif
584
585     const DeprecatedStyleBuilder& m_deprecatedStyleBuilder;
586
587     OwnPtr<StyleScopeResolver> m_scopeResolver;
588     CSSToStyleMap m_styleMap;
589     InspectorCSSOMWrappers m_inspectorCSSOMWrappers;
590
591     State m_state;
592
593 #if ENABLE(CSS_SHADERS)
594     OwnPtr<StyleCustomFilterProgramCache> m_customFilterProgramCache;
595 #endif
596
597     friend class DeprecatedStyleBuilder;
598     friend bool operator==(const MatchedProperties&, const MatchedProperties&);
599     friend bool operator!=(const MatchedProperties&, const MatchedProperties&);
600     friend bool operator==(const MatchRanges&, const MatchRanges&);
601     friend bool operator!=(const MatchRanges&, const MatchRanges&);
602 };
603
604 inline bool StyleResolver::hasSelectorForAttribute(const AtomicString &attributeName) const
605 {
606     ASSERT(!attributeName.isEmpty());
607     return m_ruleSets.features().attrsInRules.contains(attributeName.impl());
608 }
609
610 inline bool StyleResolver::hasSelectorForClass(const AtomicString& classValue) const
611 {
612     ASSERT(!classValue.isEmpty());
613     return m_ruleSets.features().classesInRules.contains(classValue.impl());
614 }
615
616 inline bool StyleResolver::hasSelectorForId(const AtomicString& idValue) const
617 {
618     ASSERT(!idValue.isEmpty());
619     return m_ruleSets.features().idsInRules.contains(idValue.impl());
620 }
621
622 inline bool checkRegionSelector(const CSSSelector* regionSelector, Element* regionElement)
623 {
624     if (!regionSelector || !regionElement)
625         return false;
626
627     SelectorChecker selectorChecker(regionElement->document(), SelectorChecker::QueryingRules);
628     for (const CSSSelector* s = regionSelector; s; s = CSSSelectorList::next(s)) {
629         SelectorChecker::SelectorCheckingContext selectorCheckingContext(s, regionElement, SelectorChecker::VisitedMatchDisabled);
630         PseudoId ignoreDynamicPseudo = NOPSEUDO;
631         if (selectorChecker.match(selectorCheckingContext, ignoreDynamicPseudo))
632             return true;
633     }
634     return false;
635 }
636
637 class StyleResolverParentPusher {
638 public:
639     StyleResolverParentPusher(Element* parent)
640         : m_parent(parent)
641         , m_pushedStyleResolver(0)
642     { }
643     void push()
644     {
645         if (m_pushedStyleResolver)
646             return;
647         m_pushedStyleResolver = &m_parent->document().ensureStyleResolver();
648         m_pushedStyleResolver->pushParentElement(m_parent);
649     }
650     ~StyleResolverParentPusher()
651     {
652         if (!m_pushedStyleResolver)
653             return;
654         // This tells us that our pushed style selector is in a bad state,
655         // so we should just bail out in that scenario.
656         ASSERT(m_pushedStyleResolver == &m_parent->document().ensureStyleResolver());
657         if (m_pushedStyleResolver != &m_parent->document().ensureStyleResolver())
658             return;
659         m_pushedStyleResolver->popParentElement(m_parent);
660     }
661     
662 private:
663     Element* m_parent;
664     StyleResolver* m_pushedStyleResolver;
665 };
666
667 } // namespace WebCore
668
669 #endif // StyleResolver_h