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